From 69b97a3b2471624a03488405f24608d05ac2e518 Mon Sep 17 00:00:00 2001 From: liujiahua123123 Date: Sat, 17 Aug 2019 15:53:38 +0800 Subject: [PATCH] thread safe event system --- .../net/mamoe/mirai/event/MiraiEventHook.java | 25 +++++++++++++++++++ .../mamoe/mirai/event/MiraiEventManager.java | 25 +++++++++++-------- .../mamoe/mirai/task/MiraiTaskManager.java | 6 +++-- 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHook.java b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHook.java index 6d39e2c12..a8e6e1936 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHook.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/event/MiraiEventHook.java @@ -1,8 +1,10 @@ package net.mamoe.mirai.event; import lombok.Getter; +import lombok.Setter; import net.mamoe.mirai.event.events.Cancellable; import net.mamoe.mirai.event.events.MiraiEvent; +import net.mamoe.mirai.event.events.server.ServerDisableEvent; import java.util.function.Consumer; import java.util.function.Predicate; @@ -21,6 +23,10 @@ public class MiraiEventHook { @Getter private volatile boolean ignoreCancelled = true; + @Getter + @Setter + private volatile boolean mount = false; + /** * return true -> this hook need to be removed */ @@ -74,4 +80,23 @@ public class MiraiEventHook { return this.valid.test((T)event); } + /** + * 更加安全高效的方式 + * Remember to use {@link this.mount()} at last + * */ + + public static MiraiEventHook onEvent(Class event){ + return new MiraiEventHook<>(event); + } + + public void mount(){ + MiraiEventManager.getInstance().registerHook(this); + } + + public void mountOnce(){ + MiraiEventManager.getInstance().hookOnce(this); + } + + + } 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 cc7df4418..7eabb7b7d 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 @@ -26,17 +26,11 @@ public class MiraiEventManager { private Map, List>> hooks = new HashMap<>(); public void hookUntil(MiraiEventHook hook, Predicate toRemove){ - hooksLock.lock(); - hooks.putIfAbsent(hook.getEventClass(),new ArrayList<>()); - hooks.get(hook.getEventClass()).add(hook.setValidUntil(toRemove)); - hooksLock.unlock(); + this.mountHook(hook.setValidUntil(toRemove)); } public void hookWhile(MiraiEventHook hook, Predicate toKeep){ - hooksLock.lock(); - hooks.putIfAbsent(hook.getEventClass(),new ArrayList<>()); - hooks.get(hook.getEventClass()).add(hook.setValidWhile(toKeep)); - hooksLock.unlock(); + this.mountHook(hook.setValidWhile(toKeep)); } public void hookOnce(MiraiEventHook hook){ @@ -44,15 +38,25 @@ public class MiraiEventManager { } public void registerHook(MiraiEventHook hook){ - this.hookUntil(hook,(a) -> false); + this.mountHook(hook); } + private void mountHook(MiraiEventHook hook){ + if(!hook.isMount()) { + hook.setMount(true); + hooksLock.lock(); + hooks.putIfAbsent(hook.getEventClass(), new ArrayList<>()); + hooks.get(hook.getEventClass()).add(hook); + hooksLock.unlock(); + } + } /** * 不推荐onEvent - * 非线程安全 + * 由于不能保证Hook的原子性 非线程安全 * 不能保证下一个 D event发生时handler就位 * @author NaturalHG Aug27 + * use {@link MiraiEventHook::onEvent()} to replace */ @Deprecated @@ -85,6 +89,7 @@ public class MiraiEventManager { + public void boardcastEvent(MiraiEvent event){ hooksLock.lock(); if(hooks.containsKey(event.getClass())){ diff --git a/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java b/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java index 653d89f13..58cd21e9d 100644 --- a/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java +++ b/mirai-core/src/main/java/net/mamoe/mirai/task/MiraiTaskManager.java @@ -2,6 +2,7 @@ package net.mamoe.mirai.task; import net.mamoe.mirai.MiraiServer; +import net.mamoe.mirai.event.MiraiEventHook; import net.mamoe.mirai.event.events.server.ServerDisableEvent; import java.util.concurrent.Callable; @@ -26,9 +27,10 @@ public class MiraiTaskManager { private MiraiTaskManager() { this.pool = new MiraiThreadPool(); - MiraiServer.getInstance().getEventManager() + MiraiEventHook .onEvent(ServerDisableEvent.class) - .setHandler(a -> this.pool.close()); + .setHandler(a -> this.pool.close()) + .mount(); }