Skip to content

Instantly share code, notes, and snippets.

@MinnDevelopment
Last active February 27, 2021 23:08
Show Gist options
  • Save MinnDevelopment/90155d794cf895d2cbaaf71a4a8ca018 to your computer and use it in GitHub Desktop.
Save MinnDevelopment/90155d794cf895d2cbaaf71a4a8ca018 to your computer and use it in GitHub Desktop.
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;
/* Example:
public void onMessageReceived(MessageReceivedEvent event) {
new Once(MessageReceivedEvent.class)
.filter(it -> it.getAuthor().equals(event.getAuthor()))
.filter(it -> it.getChannel().equals(event.getChannel()))
.timeout(Duration.ofSeconds(30), () -> System.out.println("Timed out"))
.then(it -> System.out.println("Received answer!"))
.register(event.getJDA());
}
*/
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 timeoutCallback;
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 callback) {
timeout = duration;
timeoutCallback = callback;
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 (timeoutCallback != null)
timeoutCallback.run();
}, timeout.toMillis(), TimeUnit.MILLISECONDS);
}
}
@Override
@SubscribeEvent
public void onEvent(@Nonnull GenericEvent event) {
if (!clazz.isInstance(event))
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