mirror of
https://github.com/Minestom/Minestom.git
synced 2024-12-30 21:17:53 +01:00
Move optimized event calling inside ListenerHandle
This commit is contained in:
parent
aed441123e
commit
5ddd97cee2
@ -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);
|
||||
|
@ -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
|
||||
|
@ -10,10 +10,6 @@ public final class EventDispatcher {
|
||||
MinecraftServer.getGlobalEventHandler().call(event);
|
||||
}
|
||||
|
||||
public static <E extends Event> void call(@NotNull E event, @NotNull ListenerHandle<E> handle) {
|
||||
MinecraftServer.getGlobalEventHandler().call(event, handle);
|
||||
}
|
||||
|
||||
public static <E extends Event> ListenerHandle<E> getHandle(@NotNull Class<E> handleType) {
|
||||
return MinecraftServer.getGlobalEventHandler().getHandle(handleType);
|
||||
}
|
||||
|
@ -188,23 +188,9 @@ public interface EventNode<T extends Event> {
|
||||
*/
|
||||
default void call(@NotNull T event) {
|
||||
//noinspection unchecked
|
||||
call(event, getHandle((Class<T>) event.getClass()));
|
||||
getHandle((Class<T>) event.getClass()).call(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls an event starting from this node.
|
||||
* <p>
|
||||
* 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 <E> the event type
|
||||
* @throws IllegalArgumentException if {@code handle}'s owner is not {@code this}
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
<E extends T> void call(@NotNull E event, @NotNull ListenerHandle<E> handle);
|
||||
|
||||
/**
|
||||
* Gets the handle of an event type.
|
||||
*
|
||||
@ -215,20 +201,6 @@ public interface EventNode<T extends Event> {
|
||||
@ApiStatus.Experimental
|
||||
<E extends T> @NotNull ListenerHandle<E> getHandle(@NotNull Class<E> handleType);
|
||||
|
||||
/**
|
||||
* Gets if any listener has been registered for the given handle.
|
||||
* May trigger an update if the cached data is not correct.
|
||||
* <p>
|
||||
* 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<? extends T> 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)}.
|
||||
|
@ -39,18 +39,6 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
||||
this.eventType = filter.eventType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends T> void call(@NotNull E event, @NotNull ListenerHandle<E> handle) {
|
||||
final Handle<T> castedHandle = (Handle<T>) handle;
|
||||
Check.argCondition(castedHandle.node != this, "Invalid handle owner");
|
||||
if (!castedHandle.updated) castedHandle.update();
|
||||
final Consumer<T>[] listeners = castedHandle.listeners;
|
||||
if (listeners.length == 0) return;
|
||||
for (Consumer<T> listener : listeners) {
|
||||
listener.accept(event);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends T> @NotNull ListenerHandle<E> getHandle(@NotNull Class<E> handleType) {
|
||||
//noinspection unchecked
|
||||
@ -58,13 +46,6 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
||||
aClass -> new Handle<>(this, (Class<T>) aClass));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasListener(@NotNull ListenerHandle<? extends T> handle) {
|
||||
final Handle<T> castedHandle = (Handle<T>) handle;
|
||||
if (!castedHandle.updated) castedHandle.update();
|
||||
return castedHandle.listeners.length > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <E extends T> @NotNull List<EventNode<E>> findChildren(@NotNull String name, Class<E> eventType) {
|
||||
synchronized (GLOBAL_CHILD_LOCK) {
|
||||
@ -286,6 +267,22 @@ class EventNodeImpl<T extends Event> implements EventNode<T> {
|
||||
this.eventType = eventType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void call(@NotNull E event) {
|
||||
if (!updated) update();
|
||||
final Consumer<E>[] listeners = this.listeners;
|
||||
if (listeners.length == 0) return;
|
||||
for (Consumer<E> 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<T extends Event> implements EventNode<T> {
|
||||
for (var mappedEntry : mappedNodeCache.entrySet()) {
|
||||
final EventNodeImpl<E> mappedNode = mappedEntry.getValue();
|
||||
final Handle<E> handle = (Handle<E>) 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);
|
||||
}
|
||||
|
@ -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<E extends Event> {
|
||||
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.
|
||||
* <p>
|
||||
* 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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user