diff --git a/src/main/java/net/minestom/server/entity/Entity.java b/src/main/java/net/minestom/server/entity/Entity.java index 07f2218f4..41082744d 100644 --- a/src/main/java/net/minestom/server/entity/Entity.java +++ b/src/main/java/net/minestom/server/entity/Entity.java @@ -449,7 +449,7 @@ public class Entity implements Viewable, Tickable, TagHandler, PermissionHandler update(time); ticks++; - EventDispatcher.call(new EntityTickEvent(this), GlobalHandles.ENTITY_TICK); + GlobalHandles.ENTITY_TICK.call(new EntityTickEvent(this)); // remove expired effects effectTick(time); diff --git a/src/main/java/net/minestom/server/entity/Player.java b/src/main/java/net/minestom/server/entity/Player.java index a3070ceed..aba439774 100644 --- a/src/main/java/net/minestom/server/entity/Player.java +++ b/src/main/java/net/minestom/server/entity/Player.java @@ -351,7 +351,7 @@ public class Player extends LivingEntity implements CommandSender, Localizable, } // Tick event - EventDispatcher.call(new PlayerTickEvent(this), GlobalHandles.PLAYER_TICK); + GlobalHandles.PLAYER_TICK.call(new PlayerTickEvent(this)); } @Override diff --git a/src/main/java/net/minestom/server/event/EventDispatcher.java b/src/main/java/net/minestom/server/event/EventDispatcher.java index 742736e4e..6d0738ef6 100644 --- a/src/main/java/net/minestom/server/event/EventDispatcher.java +++ b/src/main/java/net/minestom/server/event/EventDispatcher.java @@ -10,10 +10,6 @@ public final class EventDispatcher { MinecraftServer.getGlobalEventHandler().call(event); } - public static void call(@NotNull E event, @NotNull ListenerHandle handle) { - MinecraftServer.getGlobalEventHandler().call(event, handle); - } - public static ListenerHandle getHandle(@NotNull Class handleType) { return MinecraftServer.getGlobalEventHandler().getHandle(handleType); } diff --git a/src/main/java/net/minestom/server/event/EventNode.java b/src/main/java/net/minestom/server/event/EventNode.java index 8bb6b6127..621031355 100644 --- a/src/main/java/net/minestom/server/event/EventNode.java +++ b/src/main/java/net/minestom/server/event/EventNode.java @@ -188,23 +188,9 @@ public interface EventNode { */ default void call(@NotNull T event) { //noinspection unchecked - call(event, getHandle((Class) event.getClass())); + getHandle((Class) event.getClass()).call(event); } - /** - * Calls an event starting from this node. - *

- * The event handle can be retrieved using {@link #getHandle(Class)} - * and is useful to avoid map lookups for high-frequency events. - * - * @param event the event to call - * @param handle the event handle linked to this node - * @param the event type - * @throws IllegalArgumentException if {@code handle}'s owner is not {@code this} - */ - @ApiStatus.Experimental - void call(@NotNull E event, @NotNull ListenerHandle handle); - /** * Gets the handle of an event type. * @@ -215,20 +201,6 @@ public interface EventNode { @ApiStatus.Experimental @NotNull ListenerHandle getHandle(@NotNull Class handleType); - /** - * Gets if any listener has been registered for the given handle. - * May trigger an update if the cached data is not correct. - *

- * Useful if you are able to avoid expensive computation in the case where - * the event is unused. Be aware that {@link #call(Event, ListenerHandle)} - * has similar optimization built-in. - * - * @param handle the listener handle - * @return true if the event has 1 or more listeners - */ - @ApiStatus.Experimental - boolean hasListener(@NotNull ListenerHandle handle); - /** * 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)}. diff --git a/src/main/java/net/minestom/server/event/EventNodeImpl.java b/src/main/java/net/minestom/server/event/EventNodeImpl.java index bf759a991..b646be2b4 100644 --- a/src/main/java/net/minestom/server/event/EventNodeImpl.java +++ b/src/main/java/net/minestom/server/event/EventNodeImpl.java @@ -39,18 +39,6 @@ class EventNodeImpl implements EventNode { this.eventType = filter.eventType(); } - @Override - public void call(@NotNull E event, @NotNull ListenerHandle handle) { - final Handle castedHandle = (Handle) handle; - Check.argCondition(castedHandle.node != this, "Invalid handle owner"); - if (!castedHandle.updated) castedHandle.update(); - final Consumer[] listeners = castedHandle.listeners; - if (listeners.length == 0) return; - for (Consumer listener : listeners) { - listener.accept(event); - } - } - @Override public @NotNull ListenerHandle getHandle(@NotNull Class handleType) { //noinspection unchecked @@ -58,13 +46,6 @@ class EventNodeImpl implements EventNode { aClass -> new Handle<>(this, (Class) aClass)); } - @Override - public boolean hasListener(@NotNull ListenerHandle handle) { - final Handle castedHandle = (Handle) handle; - if (!castedHandle.updated) castedHandle.update(); - return castedHandle.listeners.length > 0; - } - @Override public @NotNull List> findChildren(@NotNull String name, Class eventType) { synchronized (GLOBAL_CHILD_LOCK) { @@ -286,6 +267,22 @@ class EventNodeImpl implements EventNode { this.eventType = eventType; } + @Override + public void call(@NotNull E event) { + if (!updated) update(); + final Consumer[] listeners = this.listeners; + if (listeners.length == 0) return; + for (Consumer listener : listeners) { + listener.accept(event); + } + } + + @Override + public boolean hasListener() { + if (!updated) update(); + return listeners.length > 0; + } + void update() { synchronized (GLOBAL_CHILD_LOCK) { this.listenersCache.clear(); @@ -325,7 +322,7 @@ class EventNodeImpl implements EventNode { for (var mappedEntry : mappedNodeCache.entrySet()) { final EventNodeImpl mappedNode = mappedEntry.getValue(); final Handle handle = (Handle) mappedNode.getHandle(eventType); - if (!mappedNode.hasListener(handle)) continue; // Implicit update + if (!handle.hasListener()) continue; // Implicit update filters.add(mappedNode.filter); handlers.put(mappedEntry.getKey(), handle); } diff --git a/src/main/java/net/minestom/server/event/ListenerHandle.java b/src/main/java/net/minestom/server/event/ListenerHandle.java index 9e610d19a..eb3f82362 100644 --- a/src/main/java/net/minestom/server/event/ListenerHandle.java +++ b/src/main/java/net/minestom/server/event/ListenerHandle.java @@ -1,6 +1,7 @@ package net.minestom.server.event; import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.NotNull; /** * Represents a key to access an {@link EventNode} listeners. @@ -11,4 +12,17 @@ import org.jetbrains.annotations.ApiStatus; @ApiStatus.Experimental @ApiStatus.NonExtendable public interface ListenerHandle { + void call(@NotNull E event); + + /** + * Gets if any listener has been registered for the given handle. + * May trigger an update if the cached data is not correct. + *

+ * Useful if you are able to avoid expensive computation in the case where + * the event is unused. Be aware that {@link #call(Event)} + * has similar optimization built-in. + * + * @return true if the event has 1 or more listeners + */ + boolean hasListener(); } diff --git a/src/main/java/net/minestom/server/instance/Chunk.java b/src/main/java/net/minestom/server/instance/Chunk.java index 7c486c0a7..0e4f0aa68 100644 --- a/src/main/java/net/minestom/server/instance/Chunk.java +++ b/src/main/java/net/minestom/server/instance/Chunk.java @@ -280,7 +280,7 @@ public abstract class Chunk implements BlockGetter, BlockSetter, Viewable, Ticka if (result) { PlayerChunkLoadEvent playerChunkLoadEvent = new PlayerChunkLoadEvent(player, chunkX, chunkZ); - EventDispatcher.call(playerChunkLoadEvent, GlobalHandles.PLAYER_CHUNK_LOAD); + GlobalHandles.PLAYER_CHUNK_LOAD.call(playerChunkLoadEvent); } return result; diff --git a/src/main/java/net/minestom/server/instance/Instance.java b/src/main/java/net/minestom/server/instance/Instance.java index 222cee95e..46991b268 100644 --- a/src/main/java/net/minestom/server/instance/Instance.java +++ b/src/main/java/net/minestom/server/instance/Instance.java @@ -732,7 +732,7 @@ public abstract class Instance implements BlockGetter, BlockSetter, Tickable, Ta // Tick event { // Process tick events - EventDispatcher.call(new InstanceTickEvent(this, time, lastTickAge), GlobalHandles.INSTANCE_TICK); + GlobalHandles.INSTANCE_TICK.call(new InstanceTickEvent(this, time, lastTickAge)); // Set last tick age this.lastTickAge = time; } diff --git a/src/main/java/net/minestom/server/instance/InstanceContainer.java b/src/main/java/net/minestom/server/instance/InstanceContainer.java index ed177b272..52f3fd3ae 100644 --- a/src/main/java/net/minestom/server/instance/InstanceContainer.java +++ b/src/main/java/net/minestom/server/instance/InstanceContainer.java @@ -275,7 +275,7 @@ public class InstanceContainer extends Instance { .whenComplete((chunk, throwable) -> { // TODO run in the instance thread? cacheChunk(chunk); - EventDispatcher.call(new InstanceChunkLoadEvent(this, chunkX, chunkZ), GlobalHandles.INSTANCE_CHUNK_LOAD); + GlobalHandles.INSTANCE_CHUNK_LOAD.call(new InstanceChunkLoadEvent(this, chunkX, chunkZ)); synchronized (loadingChunks) { this.loadingChunks.remove(ChunkUtils.getChunkIndex(chunk)); } diff --git a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java index 9ca1e1f3d..52132c004 100644 --- a/src/main/java/net/minestom/server/listener/PlayerPositionListener.java +++ b/src/main/java/net/minestom/server/listener/PlayerPositionListener.java @@ -2,7 +2,6 @@ package net.minestom.server.listener; import net.minestom.server.coordinate.Pos; import net.minestom.server.entity.Player; -import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.GlobalHandles; import net.minestom.server.event.player.PlayerMoveEvent; import net.minestom.server.instance.Instance; @@ -54,7 +53,7 @@ public class PlayerPositionListener { } PlayerMoveEvent playerMoveEvent = new PlayerMoveEvent(player, newPosition); - EventDispatcher.call(playerMoveEvent, GlobalHandles.PLAYER_MOVE); + GlobalHandles.PLAYER_MOVE.call(playerMoveEvent); // True if the event call changed the player position (possibly a teleport) if (!playerMoveEvent.isCancelled() && currentPosition.equals(player.getPosition())) { // Move the player diff --git a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java index e75d83e5a..b0ec7d267 100644 --- a/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java +++ b/src/main/java/net/minestom/server/listener/manager/PacketListenerManager.java @@ -2,7 +2,6 @@ package net.minestom.server.listener.manager; import net.minestom.server.MinecraftServer; import net.minestom.server.entity.Player; -import net.minestom.server.event.EventDispatcher; import net.minestom.server.event.GlobalHandles; import net.minestom.server.event.player.PlayerPacketEvent; import net.minestom.server.listener.*; @@ -90,7 +89,7 @@ public final class PacketListenerManager { // Event PlayerPacketEvent playerPacketEvent = new PlayerPacketEvent(player, packet); - EventDispatcher.call(playerPacketEvent, GlobalHandles.PLAYER_PACKET); + GlobalHandles.PLAYER_PACKET.call(playerPacketEvent); if (playerPacketEvent.isCancelled()) { return; }