From d38c0368fc48ef080b387675286760e14a5c8c2d Mon Sep 17 00:00:00 2001 From: Matt Worzala Date: Tue, 8 Jun 2021 16:58:48 -0400 Subject: [PATCH] add event api javadocs v1 --- .../server/event/CancellableEvent.java | 1 + .../java/net/minestom/server/event/Event.java | 2 +- .../minestom/server/event/EventFilter.java | 26 +++ .../minestom/server/event/EventListener.java | 35 +++ .../net/minestom/server/event/EventNode.java | 199 +++++++++++++++++- .../server/event/trait/EntityEvent.java | 3 + .../server/event/trait/InstanceEvent.java | 3 + .../server/event/trait/InventoryEvent.java | 3 + .../server/event/trait/ItemEvent.java | 3 + .../server/event/trait/PlayerEvent.java | 3 + 10 files changed, 270 insertions(+), 8 deletions(-) diff --git a/src/main/java/net/minestom/server/event/CancellableEvent.java b/src/main/java/net/minestom/server/event/CancellableEvent.java index ef821f834..aae8df57d 100644 --- a/src/main/java/net/minestom/server/event/CancellableEvent.java +++ b/src/main/java/net/minestom/server/event/CancellableEvent.java @@ -2,6 +2,7 @@ package net.minestom.server.event; /** * Represents an {@link Event} which can be cancelled. + * Called using {@link EventDispatcher#callCancellable(CancellableEvent, Runnable)}. */ public interface CancellableEvent extends Event { diff --git a/src/main/java/net/minestom/server/event/Event.java b/src/main/java/net/minestom/server/event/Event.java index 6253a2cd4..7c2408b1a 100644 --- a/src/main/java/net/minestom/server/event/Event.java +++ b/src/main/java/net/minestom/server/event/Event.java @@ -5,7 +5,7 @@ import net.minestom.server.event.handler.EventHandler; /** * Event which can be listened to by an {@link EventHandler}. *

- * Called using {@link EventHandler#callEvent(Class, Event)}. + * Called using {@link EventDispatcher#call(Event)}. */ public interface Event { } diff --git a/src/main/java/net/minestom/server/event/EventFilter.java b/src/main/java/net/minestom/server/event/EventFilter.java index 3bdda0dea..4a7740266 100644 --- a/src/main/java/net/minestom/server/event/EventFilter.java +++ b/src/main/java/net/minestom/server/event/EventFilter.java @@ -11,6 +11,20 @@ import org.jetbrains.annotations.Nullable; import java.util.function.Function; +/** + * Represents a filter for a specific {@link Event} type. + *

+ * The handler represents a "target" of the event. This can be used + * to create filters for all events of a specific type using information + * about the target. + *

+ * For example, the target of a {@link PlayerEvent} is a {@link Player} so + * you could create a player event filter which checks if the target player + * is in creative mode. + * + * @param The event type to filter + * @param The handler type to filter on. + */ public interface EventFilter { EventFilter ALL = from(Event.class, null); @@ -35,7 +49,19 @@ public interface EventFilter { }; } + /** + * Gets the handler for the given event instance, or null if the event + * type has no handler. + * + * @param event The event instance + * @return The handler, if it exists for the given event + */ @Nullable H getHandler(@NotNull E event); + /** + * The event type to filter on. + * + * @return The event type. + */ @NotNull Class getEventType(); } diff --git a/src/main/java/net/minestom/server/event/EventListener.java b/src/main/java/net/minestom/server/event/EventListener.java index 63c100c43..3d2c41036 100644 --- a/src/main/java/net/minestom/server/event/EventListener.java +++ b/src/main/java/net/minestom/server/event/EventListener.java @@ -9,6 +9,13 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; import java.util.function.Predicate; +/** + * Represents an event listener (handler) in an event graph. + *

+ * A listener is responsible for executing some action based on an event triggering. + * + * @param The event type being handled. + */ public interface EventListener { @NotNull Class getEventType(); @@ -20,6 +27,15 @@ public interface EventListener { return new EventListener.Builder<>(eventType); } + /** + * Create an event listener without any special options. The given listener will be executed + * if the event passes all parent filtering. + * + * @param eventType The event type to handle + * @param listener The handler function + * @param The event type to handle + * @return An event listener with the given properties + */ @Contract(pure = true) static @NotNull EventListener of(@NotNull Class eventType, @NotNull Consumer<@NotNull T> listener) { return new EventListener<>() { @@ -47,24 +63,43 @@ public interface EventListener { this.eventType = eventType; } + /** + * Adds a filter to the executor of this listener. The executor will only + * be called if this condition passes on the given event. + */ @Contract(value = "_ -> this") public @NotNull EventListener.Builder filter(Predicate filter) { this.filters.add(filter); return this; } + /** + * Removes this listener after it has been executed the given number of times. + * + * @param expireCount The number of times to execute + */ @Contract(value = "_ -> this") public @NotNull EventListener.Builder expireCount(int expireCount) { this.expireCount = expireCount; return this; } + /** + * Expires this listener when it passes the given condition. The expiration will + * happen before the event is executed. + * + * @param expireWhen The condition to test + */ @Contract(value = "_ -> this") public @NotNull EventListener.Builder expireWhen(Predicate expireWhen) { this.expireWhen = expireWhen; return this; } + /** + * Sets the handler for this event listener. This will be executed if the listener passes + * all conditions. + */ @Contract(value = "_ -> this") public @NotNull EventListener.Builder handler(Consumer handler) { this.handler = handler; diff --git a/src/main/java/net/minestom/server/event/EventNode.java b/src/main/java/net/minestom/server/event/EventNode.java index fd6e2dbd0..6b02e7f19 100644 --- a/src/main/java/net/minestom/server/event/EventNode.java +++ b/src/main/java/net/minestom/server/event/EventNode.java @@ -16,26 +16,67 @@ import java.util.function.BiPredicate; import java.util.function.Consumer; import java.util.function.Predicate; +/** + * Represents a single node in an event graph. + *

+ * A node may contain any number of children and/or listeners. When an event is called, + * the node will filter it based on the parameters given at creation and then propagate + * it down to child nodes and listeners if it passes. + * + * @param The event type accepted by this node + */ public class EventNode { + /** + * Creates an event node which accepts any event type with no filtering. + * + * @param name The name of the node + * @return An event node with no filtering + */ @Contract(value = "_ -> new", pure = true) public static @NotNull EventNode all(@NotNull String name) { return type(name, EventFilter.ALL); } - @Contract(value = "_, _, _ -> new", pure = true) - public static @NotNull EventNode type(@NotNull String name, - @NotNull EventFilter filter, - @NotNull BiPredicate predicate) { - return create(name, filter, predicate); - } - + /** + * Creates an event node which accepts any event of the given type. The type is provided + * by the {@link EventFilter}. + *

+ * For example, you could create an event filter which only accepts player events with the following + *

+     * var playerEventNode = EventNode.type("demo", EventFilter.PLAYER);
+     * 
+ * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param The resulting event type of the node + * @return A node with just an event type filter + */ @Contract(value = "_, _ -> new", pure = true) public static @NotNull EventNode type(@NotNull String name, @NotNull EventFilter filter) { return create(name, filter, null); } + /** + * Creates an event node which accepts any event of the given type which passes + * the provided condition. The condition is based on the event object itself. + *

+ * For example, you could create an event filter which only accepts player events + * where the player is in the pos x/z quadrant of the world. + *

+     * var playerInPosXZNode = EventNode.event("abc", EventFilter.PLAYER, event -> {
+     *     var position = event.getPlayer().getPosition();
+     *     return position.getX() > 0 && position.getZ() > 0;
+     * });
+     * 
+ * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param predicate The event condition + * @param The resulting event type of the node + * @return A node with an event type filter as well as a condition on the event. + */ @Contract(value = "_, _, _ -> new", pure = true) public static @NotNull EventNode event(@NotNull String name, @NotNull EventFilter filter, @@ -43,6 +84,52 @@ public class EventNode { return create(name, filter, (e, h) -> predicate.test(e)); } + /** + * Creates an event node which accepts any event of the given type which passes + * the provided condition. The condition is based on the event object as well as + * the event handler type defined in the {@link EventFilter}. + *

+ * For example, you could create an event filter which only accepts player events + * where the player is in the pos x/z quadrant of the world. + *

+     * var playerInPosXZNode = EventNode.type("abc", EventFilter.PLAYER, (event, player) -> {
+     *     var position = player.getPosition();
+     *     return position.getX() > 0 && position.getZ() > 0;
+     * });
+     * 
+ * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param predicate The event condition + * @param The resulting event type of the node + * @param The handler type of the event filter + * @return A node with an event type filter as well as a condition on the event. + */ + @Contract(value = "_, _, _ -> new", pure = true) + public static @NotNull EventNode type(@NotNull String name, + @NotNull EventFilter filter, + @NotNull BiPredicate predicate) { + return create(name, filter, predicate); + } + + /** + * Creates an event node which accepts any event of the given type which passes + * the provided condition. The condition is based on the event handler defined + * by the {@link EventFilter}. + *

+ * For example, you could create an event filter which only accepts player events + * where the player is in creative mode. + *

+     * var playerIsCreative = EventNode.value("abc", EventFilter.PLAYER, Player::isCreative);
+     * 
+ * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param predicate The event condition + * @param The resulting event type of the node + * @param The handler type of the event filter + * @return A node with an event type filter as well as a condition on the event. + */ @Contract(value = "_, _, _ -> new", pure = true) public static @NotNull EventNode value(@NotNull String name, @NotNull EventFilter filter, @@ -50,6 +137,18 @@ public class EventNode { return create(name, filter, (e, h) -> predicate.test(h)); } + /** + * Creates an event node which accepts any event of the given type which has a handler who + * has the given tag. + * + * The {@link EventFilter}'s resulting event type must be {@link TagReadable}. + * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param tag The tag which must be contained on the event handler + * @param The resulting event type of the node + * @return A node with an event type filter as well as a handler with the provided tag + */ @Contract(value = "_, _, _ -> new", pure = true) public static @NotNull EventNode tag(@NotNull String name, @NotNull EventFilter filter, @@ -57,6 +156,17 @@ public class EventNode { return create(name, filter, (e, h) -> h.hasTag(tag)); } + /** + * Creates an event node which accepts any event of the given type which has a handler who + * has an applicable tag. An applicable tag means that it passes the given condition. + * + * @param name The name of the event node + * @param filter The event type filter to apply + * @param tag The tag which must be contained on the event handler + * @param consumer The condition to test against the tag, if it exists. + * @param The resulting event type of the node + * @return A node with an event type filter as well as a handler with the provided tag + */ @Contract(value = "_, _, _, _ -> new", pure = true) public static @NotNull EventNode tag(@NotNull String name, @NotNull EventFilter filter, @@ -106,6 +216,15 @@ public class EventNode { return predicate.test(event, value); } + /** + * Executes the given event on this node. The event must pass all conditions before + * it will be forwarded to the listeners. + *

+ * Calling an event on a node will execute all child nodes, however, an event may be + * called anywhere on the event graph and it will propagate down from there only. + * + * @param event the event to execute + */ public void call(@NotNull T event) { final var eventClass = event.getClass(); if (!eventType.isAssignableFrom(eventClass)) { @@ -140,6 +259,13 @@ public class EventNode { } } + /** + * Execute a cancellable event with a callback to execute if the event is successful. + * Event conditions and propagation is the same as {@link #call(Event)}. + * + * @param event The event to execute + * @param successCallback A callback if the event is not cancelled + */ public void callCancellable(@NotNull T event, @NotNull Runnable successCallback) { call(event); if (!(event instanceof CancellableEvent) || !((CancellableEvent) event).isCancelled()) { @@ -168,11 +294,24 @@ public class EventNode { return parent; } + /** + * Returns an unmodifiable view of the children in this node. + * + * @see #addChild(EventNode) + * @see #removeChild(EventNode) + */ @Contract(pure = true) public @NotNull Set<@NotNull EventNode> getChildren() { return Collections.unmodifiableSet(children); } + /** + * Locates all child nodes with the given name and event type recursively starting at this node. + * + * @param name The event node name to filter for + * @param eventType The event node type to filter for + * @return All matching event nodes + */ @Contract(pure = true) public @NotNull List> findChildren(@NotNull String name, Class eventType) { if (children.isEmpty()) { @@ -190,11 +329,26 @@ public class EventNode { } } + /** + * Locates all child nodes with the given name and event type recursively starting at this node. + * + * @param name The event name to filter for + * @return All matching event nodes + */ @Contract(pure = true) public @NotNull List> findChildren(@NotNull String name) { return findChildren(name, eventType); } + /** + * Replaces all children matching the given name and type recursively starting from this node. + *

+ * Node: The callee may not be replaced by this call. + * + * @param name The event name to filter for + * @param eventType The event node type to filter for + * @param eventNode The replacement node + */ public void replaceChildren(@NotNull String name, @NotNull Class eventType, @NotNull EventNode eventNode) { if (children.isEmpty()) { return; @@ -211,10 +365,24 @@ public class EventNode { } } + /** + * Replaces all children matching the given name and type recursively starting from this node. + *

+ * Node: The callee may not be replaced by this call. + * + * @param name The node name to filter for + * @param eventNode The replacement node + */ public void replaceChildren(@NotNull String name, @NotNull EventNode eventNode) { replaceChildren(name, eventType, eventNode); } + /** + * Recursively removes children with the given name and type starting at this node. + * + * @param name The node name to filter for + * @param eventType The node type to filter for + */ public void removeChildren(@NotNull String name, @NotNull Class eventType) { if (children.isEmpty()) { return; @@ -230,10 +398,21 @@ public class EventNode { } } + /** + * Recursively removes children with the given name starting at this node. + * + * @param name The node name to filter for + */ public void removeChildren(@NotNull String name) { removeChildren(name, eventType); } + /** + * Directly adds a child node to this node. + * + * @param child The child to add + * @return this, can be used for chaining + */ @Contract(value = "_ -> this") public @NotNull EventNode addChild(@NotNull EventNode child) { synchronized (GLOBAL_CHILD_LOCK) { @@ -257,6 +436,12 @@ public class EventNode { return this; } + /** + * Directly removes the given child from this node. + * + * @param child The child to remove + * @return this, can be used for chaining + */ @Contract(value = "_ -> this") public @NotNull EventNode removeChild(@NotNull EventNode child) { synchronized (GLOBAL_CHILD_LOCK) { diff --git a/src/main/java/net/minestom/server/event/trait/EntityEvent.java b/src/main/java/net/minestom/server/event/trait/EntityEvent.java index 44469d44f..dd78a2027 100644 --- a/src/main/java/net/minestom/server/event/trait/EntityEvent.java +++ b/src/main/java/net/minestom/server/event/trait/EntityEvent.java @@ -4,6 +4,9 @@ import net.minestom.server.entity.Entity; import net.minestom.server.event.Event; import org.jetbrains.annotations.NotNull; +/** + * Represents any event called on an {@link Entity}. + */ public interface EntityEvent extends Event { /** diff --git a/src/main/java/net/minestom/server/event/trait/InstanceEvent.java b/src/main/java/net/minestom/server/event/trait/InstanceEvent.java index d122c290a..7defc9b03 100644 --- a/src/main/java/net/minestom/server/event/trait/InstanceEvent.java +++ b/src/main/java/net/minestom/server/event/trait/InstanceEvent.java @@ -4,6 +4,9 @@ import net.minestom.server.event.Event; import net.minestom.server.instance.Instance; import org.jetbrains.annotations.NotNull; +/** + * Represents any event targeting an {@link Instance}. + */ public interface InstanceEvent extends Event { /** diff --git a/src/main/java/net/minestom/server/event/trait/InventoryEvent.java b/src/main/java/net/minestom/server/event/trait/InventoryEvent.java index 25d26d4ad..726741531 100644 --- a/src/main/java/net/minestom/server/event/trait/InventoryEvent.java +++ b/src/main/java/net/minestom/server/event/trait/InventoryEvent.java @@ -4,6 +4,9 @@ import net.minestom.server.event.Event; import net.minestom.server.inventory.Inventory; import org.jetbrains.annotations.Nullable; +/** + * Represents any event inside an {@link Inventory}. + */ public interface InventoryEvent extends Event { /** diff --git a/src/main/java/net/minestom/server/event/trait/ItemEvent.java b/src/main/java/net/minestom/server/event/trait/ItemEvent.java index 5ccecded4..fc30a769d 100644 --- a/src/main/java/net/minestom/server/event/trait/ItemEvent.java +++ b/src/main/java/net/minestom/server/event/trait/ItemEvent.java @@ -4,6 +4,9 @@ import net.minestom.server.event.Event; import net.minestom.server.item.ItemStack; import org.jetbrains.annotations.NotNull; +/** + * Represents any event called about an {@link ItemStack}. + */ public interface ItemEvent extends Event { @NotNull ItemStack getItemStack(); } diff --git a/src/main/java/net/minestom/server/event/trait/PlayerEvent.java b/src/main/java/net/minestom/server/event/trait/PlayerEvent.java index 2fb8834fd..8ca030995 100644 --- a/src/main/java/net/minestom/server/event/trait/PlayerEvent.java +++ b/src/main/java/net/minestom/server/event/trait/PlayerEvent.java @@ -3,6 +3,9 @@ package net.minestom.server.event.trait; import net.minestom.server.entity.Player; import org.jetbrains.annotations.NotNull; +/** + * Represents any event called on a {@link Player}. + */ public interface PlayerEvent extends EntityEvent { /**