diff --git a/src/main/java/ch/njol/skript/SkriptEventHandler.java b/src/main/java/ch/njol/skript/SkriptEventHandler.java index 144eca18721..28eaff9b23c 100644 --- a/src/main/java/ch/njol/skript/SkriptEventHandler.java +++ b/src/main/java/ch/njol/skript/SkriptEventHandler.java @@ -18,11 +18,17 @@ */ package ch.njol.skript; -import ch.njol.skript.lang.SkriptEvent; -import ch.njol.skript.lang.Trigger; -import ch.njol.skript.timings.SkriptTimings; -import com.google.common.collect.ArrayListMultimap; -import com.google.common.collect.Multimap; +import java.lang.ref.WeakReference; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + import org.bukkit.Bukkit; import org.bukkit.event.Cancellable; import org.bukkit.event.Event; @@ -36,16 +42,13 @@ import org.bukkit.plugin.RegisteredListener; import org.eclipse.jdt.annotation.Nullable; -import java.lang.ref.WeakReference; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; -import java.util.stream.Collectors; +import com.google.common.collect.ArrayListMultimap; +import com.google.common.collect.Multimap; + +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.Trigger; +import ch.njol.skript.timings.SkriptTimings; +import ch.njol.skript.util.Task; public final class SkriptEventHandler { @@ -110,12 +113,14 @@ private static List getTriggers(Class event) { */ private static void check(Event event, EventPriority priority) { List triggers = getTriggers(event.getClass()); + if (triggers.isEmpty()) + return; if (Skript.logVeryHigh()) { boolean hasTrigger = false; for (Trigger trigger : triggers) { SkriptEvent triggerEvent = trigger.getEvent(); - if (triggerEvent.getEventPriority() == priority && triggerEvent.check(event)) { + if (triggerEvent.getEventPriority() == priority && Boolean.TRUE.equals(Task.callSync(() -> triggerEvent.check(event)))) { hasTrigger = true; break; } @@ -137,16 +142,31 @@ private static void check(Event event, EventPriority priority) { for (Trigger trigger : triggers) { SkriptEvent triggerEvent = trigger.getEvent(); - if (triggerEvent.getEventPriority() != priority || !triggerEvent.check(event)) + if (triggerEvent.getEventPriority() != priority) continue; - logTriggerStart(trigger); - Object timing = SkriptTimings.start(trigger.getDebugLabel()); - - trigger.execute(event); - - SkriptTimings.stop(timing); - logTriggerEnd(trigger); + // these methods need to be run on whatever thread the trigger is + Runnable execute = () -> { + logTriggerStart(trigger); + Object timing = SkriptTimings.start(trigger.getDebugLabel()); + trigger.execute(event); + SkriptTimings.stop(timing); + logTriggerEnd(trigger); + }; + + if (trigger.getEvent().canExecuteAsynchronously()) { + // check should be performed on the main thread + if (Boolean.FALSE.equals(Task.callSync(() -> triggerEvent.check(event)))) + continue; + execute.run(); + } else { // Ensure main thread + Task.callSync(() -> { + if (!triggerEvent.check(event)) + return null; + execute.run(); + return null; // we don't care about a return value + }); + } } logEventEnd(); diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index e150e8699d8..1d89b2c6aa9 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -216,6 +216,13 @@ public boolean isEventPrioritySupported() { return true; } + /** + * Override this method to allow Skript to not force synchronization. + */ + public boolean canExecuteAsynchronously() { + return false; + } + /** * Fixes patterns in event by modifying every {@link ch.njol.skript.patterns.TypePatternElement} * to be nullable.