Created
November 8, 2020 11:30
-
-
Save mtbarr/96d4096f96ccd3ed45e92704ea3a4959 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package io.github.ninjaservices.factions.util.event; | |
import io.github.ninjaservices.factions.FactionsPlugin; | |
import org.bukkit.event.Event; | |
import org.bukkit.event.EventPriority; | |
import org.bukkit.event.HandlerList; | |
import org.bukkit.event.Listener; | |
import org.bukkit.plugin.Plugin; | |
import org.bukkit.plugin.RegisteredListener; | |
import java.util.Objects; | |
import java.util.concurrent.ScheduledExecutorService; | |
import java.util.concurrent.TimeUnit; | |
import java.util.function.Consumer; | |
import java.util.function.Predicate; | |
import static org.bukkit.Bukkit.getScheduler; | |
public final class EventScheduler<E extends Event> { | |
private final Plugin plugin; | |
private final Class<E> eventClazz; | |
private long time; | |
private TimeUnit timeUnit; | |
private Runnable timeoutRunnable; | |
private Predicate<E> predicate = Objects::nonNull; | |
private EventThreadContext eventThreadContext; | |
private Consumer<E> eventConsumer; | |
private final ScheduledExecutorService executor; | |
private RegisteredListener listener; | |
public static <T extends Event> EventSchedulerBuilder<T> of(Class<T> clazz) { | |
return new EventSchedulerBuilder<>(clazz); | |
} | |
public static <T extends Event> EventSchedulerBuilder<T> of(Plugin plugin, Class<T> clazz) { | |
return new EventSchedulerBuilder<>(plugin, clazz); | |
} | |
private EventScheduler(Plugin plugin, Class<E> eventClazz) { | |
this.plugin = plugin; | |
this.eventClazz = eventClazz; | |
this.executor = FactionsPlugin.EXECUTOR_SERVICE; | |
} | |
public EventScheduler<E> schedule() { | |
register(event -> { | |
if (eventClazz.isInstance(event)) { | |
E awaitEvent = (E) event; | |
if (predicate.test(awaitEvent)) { | |
if (eventThreadContext == EventThreadContext.SYNC) { | |
getScheduler().runTask(plugin, () -> this.eventConsumer.accept(awaitEvent)); | |
} else if (eventThreadContext == EventThreadContext.ASYNC) { | |
getScheduler().runTaskAsynchronously(plugin, () -> this.eventConsumer.accept(awaitEvent)); | |
} else { | |
throw new RuntimeException("Thread Context"); | |
} | |
this.unregister(); | |
this.executor.shutdownNow(); | |
} | |
} | |
}); | |
executor.schedule(() -> { | |
unregister(); | |
timeoutRunnable.run(); | |
}, time, timeUnit); | |
return this; | |
} | |
private void register(Consumer<Event> onEvent) { | |
this.listener = new RegisteredListener( | |
new Listener() { | |
}, | |
(listener, event) -> onEvent.accept(event), | |
EventPriority.NORMAL, | |
plugin, | |
false | |
); | |
for (HandlerList handler : HandlerList.getHandlerLists()) { | |
handler.register(listener); | |
} | |
} | |
private void unregister() { | |
for (HandlerList handler : HandlerList.getHandlerLists()) { | |
handler.unregister(listener); | |
} | |
} | |
public static class EventSchedulerBuilder<E extends Event> { | |
private final EventScheduler<E> awaiter; | |
public EventSchedulerBuilder(Plugin plugin, Class<E> clazz) { | |
this.awaiter = new EventScheduler<>(plugin, clazz); | |
} | |
public EventSchedulerBuilder(Class<E> clazz) { | |
this(FactionsPlugin.getInstance(), clazz); | |
} | |
public EventSchedulerBuilder<E> awaitIf(Predicate<E> predicate) { | |
Objects.requireNonNull(predicate, "Predicate cannot be null."); | |
awaiter.predicate = predicate; | |
return this; | |
} | |
public EventSchedulerBuilder<E> thenExecuteSync(Consumer<E> consumer) { | |
Objects.requireNonNull(consumer, "Consumer cannot be null."); | |
awaiter.eventThreadContext = EventThreadContext.SYNC; | |
awaiter.eventConsumer = consumer; | |
return this; | |
} | |
public EventSchedulerBuilder<E> thenExecuteAsync(Consumer<E> consumer) { | |
Objects.requireNonNull(consumer, "Consumer cannot be null."); | |
awaiter.eventThreadContext = EventThreadContext.ASYNC; | |
awaiter.eventConsumer = consumer; | |
return this; | |
} | |
public EventSchedulerBuilder<E> orTimeOutAfter(long timeout, TimeUnit unit, Runnable runnable) { | |
awaiter.time = timeout; | |
awaiter.timeUnit = unit; | |
awaiter.timeoutRunnable = runnable; | |
return this; | |
} | |
public EventScheduler<E> schedule() { | |
return awaiter.schedule(); | |
} | |
} | |
private enum EventThreadContext { | |
SYNC, | |
ASYNC | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment