diff --git a/src/main/java/com/mengcraft/script/EventListener.java b/src/main/java/com/mengcraft/script/EventListener.java index 12f2e0b..dde0d54 100644 --- a/src/main/java/com/mengcraft/script/EventListener.java +++ b/src/main/java/com/mengcraft/script/EventListener.java @@ -10,11 +10,10 @@ import org.bukkit.event.Listener; import org.bukkit.plugin.RegisteredListener; +import javax.script.Bindings; import java.util.Collections; import java.util.EnumMap; import java.util.List; -import java.util.function.Consumer; -import java.util.logging.Level; /** * Created on 16-10-17. @@ -42,7 +41,7 @@ protected void remove(HandledListener listener) { } } - public HandledListener add(ScriptPlugin script, Consumer executor, int order) { + public HandledListener add(ScriptPlugin script, Bindings executor, int order) { CustomRegisteredListener custom = handledExecutors.computeIfAbsent(Utils.getEventPriority(order), priority -> new CustomRegisteredListener(priority, false)); if (custom.isEmpty()) { @@ -77,11 +76,7 @@ private CustomRegisteredListener(EventPriority priority, boolean ignoreCancelled public void callEvent(Event event) { if (clz == event.getClass()) { for (HandledListener listener : executors) { - try { - listener.getExecutor().accept(event); - } catch (Exception e) { - listener.getPlugin().getLogger().log(Level.SEVERE, name(), e); - } + listener.handle(event); } } } diff --git a/src/main/java/com/mengcraft/script/HandledListener.java b/src/main/java/com/mengcraft/script/HandledListener.java index b81cb97..030e08c 100644 --- a/src/main/java/com/mengcraft/script/HandledListener.java +++ b/src/main/java/com/mengcraft/script/HandledListener.java @@ -1,12 +1,14 @@ package com.mengcraft.script; +import com.mengcraft.script.util.Utils; import lombok.EqualsAndHashCode; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; +import javax.script.Bindings; import java.util.Comparator; import java.util.UUID; -import java.util.function.Consumer; +import java.util.logging.Level; /** * Created on 16-10-17. @@ -15,13 +17,13 @@ public class HandledListener { private final UUID id = UUID.randomUUID();// Use random id to func - private final Consumer executor; + private final Bindings executor; private final EventListener managedListener; private final int priority; private final ScriptPlugin plugin; private final EventPriority eventPriority; - public HandledListener(EventListener managedListener, ScriptPlugin plugin, Consumer executor, int priority, EventPriority eventPriority) { + public HandledListener(EventListener managedListener, ScriptPlugin plugin, Bindings executor, int priority, EventPriority eventPriority) { this.managedListener = managedListener; this.plugin = plugin; this.executor = executor; @@ -29,16 +31,26 @@ public HandledListener(EventListener managedListener, ScriptPlugin plugin, Consu this.eventPriority = eventPriority; } + public void handle(Event event) { + long millis = System.currentTimeMillis(); + try { + Utils.invoke(executor, event); + } catch (Exception e) { + plugin.getLogger().log(Level.SEVERE, String.format("Exception occurred while handle %s\n%s", event.getEventName(), executor.toString()), e); + } finally { + millis = System.currentTimeMillis() - millis; + if (millis >= 5) { + plugin.getLogger().warning(String.format("Consume too much time to handle %s. (%s millis)\n%s", event.getEventName(), millis, executor.toString())); + } + } + } + public void remove() { if (plugin.remove(this)) { managedListener.remove(this); } } - public Consumer getExecutor() { - return executor; - } - public ScriptPlugin getPlugin() { return plugin; } diff --git a/src/main/java/com/mengcraft/script/ScriptPlugin.java b/src/main/java/com/mengcraft/script/ScriptPlugin.java index 29ca4b5..a4a17d0 100644 --- a/src/main/java/com/mengcraft/script/ScriptPlugin.java +++ b/src/main/java/com/mengcraft/script/ScriptPlugin.java @@ -204,11 +204,11 @@ public HandledPlaceholder addPlaceholder(String id, HandledPlaceholder.Func func throw new IllegalStateException("id " + id + " conflict"); } - public HandledListener addListener(String event, Consumer i) { - return addListener(event, i, -1); + public HandledListener addListener(String event, Bindings executor) { + return addListener(event, executor, -1); } - public HandledListener addListener(String eventName, Consumer executor, int priority) { + public HandledListener addListener(String eventName, Bindings executor, int priority) { Preconditions.checkState(isHandled(), "unloaded"); EventListener handle = EventMapping.INSTANCE.getListener(eventName); HandledListener add = handle.add(this, executor, priority); diff --git a/src/main/java/com/mengcraft/script/loader/ScriptLoader.java b/src/main/java/com/mengcraft/script/loader/ScriptLoader.java index 2d04225..2807999 100644 --- a/src/main/java/com/mengcraft/script/loader/ScriptLoader.java +++ b/src/main/java/com/mengcraft/script/loader/ScriptLoader.java @@ -80,7 +80,7 @@ private static void loadListener(ScriptPlugin plugin, ScriptEngine ctx) { if (handle != null && EventMapping.INSTANCE.initialized(handle)) { var obj = ctx.get("handle"); if (obj != null) { - plugin.addListener(handle, ((Invocable) ctx).getInterface(obj, Consumer.class)); + plugin.addListener(handle, (Bindings) obj); } } } diff --git a/src/main/java/com/mengcraft/script/util/Utils.java b/src/main/java/com/mengcraft/script/util/Utils.java index ecfb984..10fc1e4 100644 --- a/src/main/java/com/mengcraft/script/util/Utils.java +++ b/src/main/java/com/mengcraft/script/util/Utils.java @@ -11,6 +11,7 @@ import javax.script.ScriptEngine; import java.math.BigDecimal; import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; @@ -19,6 +20,7 @@ public class Utils { private static final Yaml YAML = new Yaml(); private static Function java_from_invoker; private static Consumer function_invoker; + private static BiConsumer function_alt_invoker; public static Yaml getYaml() { return YAML; @@ -50,12 +52,19 @@ public static void setup(ScriptEngine js) { bindings = js.createBindings(); js.eval("function accept(a){a();}", bindings); function_invoker = ((Invocable) js).getInterface(bindings, Consumer.class); + bindings = js.createBindings(); + js.eval("function accept(a, b){a(b);}", bindings); + function_alt_invoker = ((Invocable) js).getInterface(bindings, BiConsumer.class); } public static void invoke(Bindings bindings) { function_invoker.accept(bindings); } + public static void invoke(Bindings invokable, T obj) { + function_alt_invoker.accept(invokable, obj); + } + @SneakyThrows public static Bindings fromJava(T obj) { return java_from_invoker.apply(obj);