diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/Cancelable.java b/mirai-core/src/main/java/net/mamoe/mirai/event/Cancelable.java index 5c0e79116..b9e444c15 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/event/Cancelable.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/event/Cancelable.java @@ -1,7 +1,13 @@ package net.mamoe.mirai.event; +import lombok.Getter; + interface Cancelable { - void setCancel(boolean value); + boolean isCancelled(); + + void setCancelled(); + + void setCancelled(boolean forceCancel); } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEvent.java b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEvent.java index 541283429..93aeefe8f 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEvent.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEvent.java @@ -1,5 +1,28 @@ package net.mamoe.mirai.event; +import net.mamoe.jpre.event.Cancellable; +import net.mamoe.mirai.utils.EventException; + public abstract class MiraiEvent { + private boolean cancelled; + + public boolean isCancelled() { + if (!(this instanceof Cancellable)) { + throw new EventException("Event is not Cancellable"); + } + return this.cancelled; + } + + public void setCancelled() { + setCancelled(true); + } + + public void setCancelled(boolean value) { + if (!(this instanceof Cancellable)) { + throw new EventException("Event is not Cancellable"); + } + this.cancelled = value; + } + } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java index d2566e3ef..7c9fb6a24 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventManager.java @@ -3,12 +3,10 @@ package net.mamoe.mirai.event; import lombok.AllArgsConstructor; import lombok.Data; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.function.Consumer; import java.util.function.Predicate; +import java.util.stream.Collectors; public class MiraiEventManager { private MiraiEventManager(){ @@ -39,11 +37,37 @@ public class MiraiEventManager { this.registerUntil(hook,(a) -> false); } + + public void boardcastEvent(MiraiEvent event){ + if(hooks.containsKey(event.getClass())){ + hooks.put(event.getClass(), + hooks.get(event.getClass()) + .stream() + .sorted(Comparator.comparingInt(MiraiEventConsumer::getPriority)) + .dropWhile(a -> a.accept(event)) + .collect(Collectors.toList()) + ); + } + } + } @Data @AllArgsConstructor class MiraiEventConsumer{ private MiraiEventHook hook; private Predicate remove; + + + public int getPriority(){ + return hook.getPreferences().getPriority(); + } + + @SuppressWarnings("unchecked") + public boolean accept(MiraiEvent event) { + if(!(event instanceof Cancelable && event.isCancelled() && hook.getPreferences().isIgnoreCanceled())){ + hook.getHandler().accept((T) event); + } + return remove.test((T)event); + } } diff --git a/mirai-core/src/main/java/net/mamoe/mirai/utils/EventException.java b/mirai-core/src/main/java/net/mamoe/mirai/utils/EventException.java new file mode 100644 index 000000000..6b53c412d --- /dev/null +++ b/mirai-core/src/main/java/net/mamoe/mirai/utils/EventException.java @@ -0,0 +1,53 @@ +package net.mamoe.mirai.utils; + +public class EventException extends RuntimeException { + private final Throwable cause; + + /** + * Constructs a new EventException based on the given Exception + * + * @param throwable Exception that triggered this Exception + */ + public EventException(Throwable throwable) { + cause = throwable; + } + + /** + * Constructs a new EventException + */ + public EventException() { + cause = null; + } + + /** + * Constructs a new EventException with the given message + * + * @param cause The exception that caused this + * @param message The message + */ + public EventException(Throwable cause, String message) { + super(message); + this.cause = cause; + } + + /** + * Constructs a new EventException with the given message + * + * @param message The message + */ + public EventException(String message) { + super(message); + cause = null; + } + + /** + * If applicable, returns the Exception that triggered this Exception + * + * @return Inner exception, or null if one does not exist + */ + @Override + public Throwable getCause() { + return cause; + } +} +