Skip to content

Instantly share code, notes, and snippets.

@MinnDevelopment MinnDevelopment/Once.java

Last active May 8, 2020
Embed
What would you like to do?
import net.dv8tion.jda.api.JDA;
import net.dv8tion.jda.api.events.GenericEvent;
import net.dv8tion.jda.api.hooks.EventListener;
import net.dv8tion.jda.api.hooks.SubscribeEvent;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Predicate;
public class Once<T extends GenericEvent> implements EventListener {
private final Class<T> clazz;
private final List<Predicate<? super T>> filters = new CopyOnWriteArrayList<>();
private Consumer<? super T> consumer = (x) -> {};
private boolean started = false;
private Future<?> timeoutHandle;
private Duration timeout;
private Runnable timeoutFallback;
public Once(Class<T> clazz) {
this.clazz = clazz;
}
@Nonnull
public Once<T> filter(final Predicate<? super T> filter) {
this.filters.add(Objects.requireNonNull(filter));
return this;
}
@Nonnull
public Once<T> then(final Consumer<? super T> handler) {
this.consumer = Objects.requireNonNull(handler);
return this;
}
@Nonnull
public Once<T> timeout(Duration duration) {
return timeout(duration, null);
}
@Nonnull
public Once<T> timeout(Duration duration, @Nullable Runnable fallback) {
timeout = duration;
timeoutFallback = fallback;
return this;
}
public void register(JDA api) {
if (started)
throw new IllegalStateException("Cannot register Once instance twice!");
started = true;
api.addEventListener(this);
if (timeout != null) {
timeoutHandle = api.getGatewayPool().schedule(() -> {
api.removeEventListener(this);
if (timeoutFallback != null)
timeoutFallback.run();
}, timeout.toMillis(), TimeUnit.MILLISECONDS);
}
}
@Override
@SubscribeEvent
public void onEvent(@Nonnull GenericEvent event) {
if (!clazz.isAssignableFrom(event.getClass()))
return;
T casted = clazz.cast(event);
if (filters.stream().allMatch(it -> it.test(casted))) {
if (timeoutHandle != null)
timeoutHandle.cancel(false);
consumer.accept(casted);
event.getJDA().removeEventListener(this);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.