From 8d8f42c1a5ad73658fcd84ebf27b4382a8b93191 Mon Sep 17 00:00:00 2001 From: Scribble Date: Fri, 23 Feb 2024 13:10:35 +0100 Subject: [PATCH] [MCTCommon/Events] Switched to new event system - Added tests --- .../mctcommon/events/EventClient.java | 7 +- .../mctcommon/events/EventException.java | 16 ++ .../events/EventListenerRegistry.java | 226 +++++++++++++----- .../mctcommon/events/EventServer.java | 110 ++------- .../mctcommon/mixin/MixinMinecraft.java | 69 +++--- .../mctcommon/mixin/MixinMinecraftServer.java | 9 +- .../mixin/MixinNetHandlerPlayClient.java | 5 +- .../mctcommon/mixin/MixinPlayerList.java | 19 +- .../mctcommon/mixin/MixinWorldClient.java | 3 +- .../minecrafttas/mctcommon/server/Client.java | 9 +- .../minecrafttas/mctcommon/server/Server.java | 3 +- .../com/minecrafttas/tasmod/TASmodClient.java | 5 - .../tasmod/events/EventClient.java | 43 +--- .../tasmod/events/EventServer.java | 78 +----- .../tasmod/mixin/MixinMinecraft.java | 3 +- .../tasmod/mixin/MixinMinecraftServer.java | 3 +- .../tasmod/mixin/events/MixinGuiIngame.java | 3 +- .../savestates/SavestateHandlerServer.java | 13 +- .../TickrateChangerClient.java | 7 +- .../TickrateChangerServer.java | 7 +- src/test/java/mctcommon/event/EventTest.java | 188 ++++++++++++--- 21 files changed, 468 insertions(+), 358 deletions(-) create mode 100644 src/main/java/com/minecrafttas/mctcommon/events/EventException.java diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java b/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java index be971974..78159c02 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventClient.java @@ -8,6 +8,11 @@ import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.gui.GuiScreen; +/** + * Contains all events fired on the client side + * + * @author Scribble + */ public interface EventClient { /** @@ -180,7 +185,7 @@ public static interface EventOtherPlayerJoinedClientSide extends EventBase { /** * Fired when a different player other than yourself joins a server or a world - * @param player The game profile of the player that joins the server or the world + * @param profile The game profile of the player that joins the server or the world */ public void onOtherPlayerJoinedClientSide(GameProfile profile); } diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventException.java b/src/main/java/com/minecrafttas/mctcommon/events/EventException.java new file mode 100644 index 00000000..3a1815ff --- /dev/null +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventException.java @@ -0,0 +1,16 @@ +package com.minecrafttas.mctcommon.events; + +public class EventException extends RuntimeException { + + public EventException(String message, Class eventClass) { + super(eventClass.getName() + ": " + message); + } + + public EventException(String message, Class eventClass, Throwable cause) { + super(eventClass.getName() + ": " + message, cause); + } + + public EventException(Class eventClass, Throwable cause) { + super(eventClass.getName(), cause); + } +} diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java index 67623afb..9e012877 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventListenerRegistry.java @@ -1,72 +1,172 @@ package com.minecrafttas.mctcommon.events; +import org.apache.commons.lang3.ClassUtils; + import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; public class EventListenerRegistry { - - private static HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); - - - public static void register(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to register a packethandler with value null"); - } - for (Class type : eventListener.getClass().getInterfaces()) { - if(EventBase.class.isAssignableFrom(type)) { - ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); - if(registryList==null) { - registryList = EVENTLISTENER_REGISTRY.get(type); - } - registryList.add(eventListener); - } - } - } - - public static void unregister(EventBase eventListener) { - if (eventListener == null) { - throw new NullPointerException("Tried to unregister a packethandler with value null"); - } - EVENTLISTENER_REGISTRY.remove(eventListener); - } - - public static Object fireEvent(Class eventClass) throws Exception { - return fireEvent(eventClass, new Object[] {}); - } - - public static Object fireEvent(Class eventClass, Object... eventParams) throws Exception { - ArrayList registryList = EVENTLISTENER_REGISTRY.get(eventClass); - if(registryList == null) { - throw new Exception(String.format("The event {} has not been registered yet", eventClass)); - } - - Method methodToCheck = getEventMethod(eventClass); - - for (EventBase eventListener : registryList) { - Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); - - for (Method method : methodsInListener) { - if(method.getName().equals(methodToCheck.getName())) { - method.setAccessible(true); - return method.invoke(eventListener, eventParams); - } - } - } - throw new Exception(String.format("The event {} has not been registered yet", eventClass)); - } - - public static Method getEventMethod(Class eventClass) throws Exception { - Method[] test = eventClass.getDeclaredMethods(); - if(test.length != 1) { - throw new Exception("The event method is not properly defined. Only one method is allowed inside of an event"); - } - - return test[0]; - } - - public static interface EventBase { - - } + + /** + * Eventlistener Registry.
+ *
+ * Consists of multiple lists seperated by event types.
+ * If it were a single ArrayList, firing an event means that you'd have to unnecessarily iterate over the entire list,
+ * to find the correct events.
+ *
+ * With multiple lists like this, you iterate only over the objects, that have the correct event applied. + */ + private static final HashMap, ArrayList> EVENTLISTENER_REGISTRY = new HashMap<>(); + + + public static void register(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to register a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { + + // If a new event type is being registered, add a new arraylist + ArrayList registryList = EVENTLISTENER_REGISTRY.putIfAbsent(type, new ArrayList<>()); + if (registryList == null) { + registryList = EVENTLISTENER_REGISTRY.get(type); + } + registryList.add(eventListener); + } + } + } + + public static void unregister(EventBase eventListener) { + if (eventListener == null) { + throw new NullPointerException("Tried to unregister a packethandler with value null"); + } + for (Class type : eventListener.getClass().getInterfaces()) { + if (EventBase.class.isAssignableFrom(type)) { + ArrayList registryList = EVENTLISTENER_REGISTRY.get(type); + if (registryList != null) { + registryList.remove(eventListener); + + if (registryList.isEmpty()) { + EVENTLISTENER_REGISTRY.remove(type); + } + } + } + } + } + + /** + * Fires an event without parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass) { + return fireEvent(eventClass, new Object[]{}); + } + + /** + * Fires an event with parameters + * + * @param eventClass The event class to fire e.g. EventClientInit.class + * @param eventParams List of parameters for the event. Number of arguments and types have to match. + * @return The result of the event, might be null if the event returns nothing + */ + public static Object fireEvent(Class eventClass, Object... eventParams) { + ArrayList registryList = EVENTLISTENER_REGISTRY.get(eventClass); + if (registryList == null) { + throw new EventException("The event has not been registered yet", eventClass); + } + + EventException toThrow = null; + + Method methodToCheck = getEventMethod(eventClass); + + Object returnValue = null; + for (EventBase eventListener : registryList) { + Method[] methodsInListener = eventListener.getClass().getDeclaredMethods(); + + for (Method method : methodsInListener) { + + if (!checkName(method, methodToCheck.getName())) { + continue; + } + + if (!checkLength(method, eventParams)) { + toThrow = new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass); + continue; + } + + if (checkTypes(method, eventParams)) { + toThrow = null; + method.setAccessible(true); + try { + returnValue = method.invoke(eventListener, eventParams); + } catch (IllegalAccessException | InvocationTargetException e) { + throw new EventException(eventClass, e); + } catch (IllegalArgumentException e) { + throw new EventException(String.format("Event fired with the wrong number of parameters. Expected: %s, Actual: %s", method.getParameterCount(), eventParams.length), eventClass, e); + } + } else { + toThrow = new EventException("Event seems to be fired with the wrong parameter types or in the wrong order", eventClass); + } + } + } + + if (toThrow != null) { + throw toThrow; + } + + return returnValue; + } + + private static Method getEventMethod(Class eventClass) { + Method[] test = eventClass.getDeclaredMethods(); + if (test.length != 1) { + throw new EventException("The event method is not properly defined. Only one method is allowed inside of an event", eventClass); + } + + return test[0]; + } + + private static boolean checkName(Method method, String name) { + return method.getName().equals(name); + } + + private static boolean checkLength(Method method, Object... parameters) { + return method.getParameterCount() == parameters.length; + } + + private static boolean checkTypes(Method method, Object... parameters) { + Class[] methodParameterTypes = ClassUtils.primitivesToWrappers(method.getParameterTypes()); + Class[] eventParameterTypes = getParameterTypes(parameters); + + for (int i = 0; i < methodParameterTypes.length; i++) { + Class paramName = methodParameterTypes[i]; + Class eventName = eventParameterTypes[i]; + if (!paramName.equals(eventName)) { + return false; + } + } + return true; + } + + private static Class[] getParameterTypes(Object... parameters) { + Class[] out = new Class[parameters.length]; + for (int i = 0; i < parameters.length; i++) { + out[i] = parameters[i].getClass(); + } + return out; + } + + /** + * Removes all registry entries + */ + public static void clear() { + EVENTLISTENER_REGISTRY.clear(); + } + + public interface EventBase { + } } diff --git a/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java b/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java index 51446b52..471baa00 100644 --- a/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java +++ b/src/main/java/com/minecrafttas/mctcommon/events/EventServer.java @@ -1,19 +1,22 @@ package com.minecrafttas.mctcommon.events; -import com.minecrafttas.mctcommon.MCTCommon; import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; import com.minecrafttas.mctcommon.server.Client; import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.server.MinecraftServer; +/** + * Contains all events fired on the server side + * + * @author Scribble + */ public interface EventServer { /** * Fired, when the server is initialised, for both integrated and dedicated server. - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerInit extends EventBase { /** @@ -21,23 +24,12 @@ public static interface EventServerInit extends EventBase { * @param server The server */ public void onServerInit(MinecraftServer server); - - public static void fireServerStartEvent(MinecraftServer server) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing ServerStartEvent"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventServerInit) { - EventServerInit event = (EventServerInit) eventListener; - event.onServerInit(server); - } - } - } } /** * Fired when the server ticks. - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerTick extends EventBase { /** @@ -45,22 +37,12 @@ public static interface EventServerTick extends EventBase { * @param server The ticking server */ public void onServerTick(MinecraftServer server); - - public static void fireOnServerTick(MinecraftServer server) { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventServerTick) { - EventServerTick event = (EventServerTick) eventListener; - event.onServerTick(server); - } - } - } } /** * Fired when the server is about to stop - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerStop extends EventBase { /** @@ -71,61 +53,37 @@ public static interface EventServerStop extends EventBase { * @param server The stopping server */ public void onServerStop(MinecraftServer server); - - public static void fireOnServerStop(MinecraftServer server) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing ServerStopEvent"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventServerStop) { - EventServerStop event = (EventServerStop) eventListener; - event.onServerStop(server); - } - } - } } - /** * Fired on a server game loop, which is independent from ticks - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerGameLoop extends EventBase { /** * Fired on a server game loop, which is independent from ticks * @param server The server this event is fired on */ public void onRunServerGameLoop(MinecraftServer server); - - public static void fireOnServerGameLoop(MinecraftServer server) { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventServerGameLoop) { - EventServerGameLoop event = (EventServerGameLoop) eventListener; - event.onRunServerGameLoop(server); - } - } - } } + /** + * Fired on the server side when a player joins + */ + @FunctionalInterface public static interface EventPlayerJoinedServerSide extends EventBase { + /** + * Fired when a player joins on the server side + * @param player The player that is joining + */ public void onPlayerJoinedServerSide(EntityPlayerMP player); - - public static void firePlayerJoinedServerSide(EntityPlayerMP player) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing PlayerJoinedServerSide"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventPlayerJoinedServerSide) { - EventPlayerJoinedServerSide event = (EventPlayerJoinedServerSide) eventListener; - event.onPlayerJoinedServerSide(player); - } - } - } } /** * Fired when a player leaves the server. - * @author Scribble - * */ + @FunctionalInterface public static interface EventPlayerLeaveServerSide extends EventBase { /** @@ -133,21 +91,12 @@ public static interface EventPlayerLeaveServerSide extends EventBase { * @param player The player that is leaving */ public void onPlayerLeaveServerSide(EntityPlayerMP player); - - public static void firePlayerLeaveServerSide(EntityPlayerMP player) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing PlayerLeaveServerSideEvent"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventPlayerLeaveServerSide) { - EventPlayerLeaveServerSide event = (EventPlayerLeaveServerSide) eventListener; - event.onPlayerLeaveServerSide(player); - } - } - } } /** * Fired when authentication was successful on the server side */ + @FunctionalInterface public static interface EventClientCompleteAuthentication extends EventBase { /** @@ -155,21 +104,12 @@ public static interface EventClientCompleteAuthentication extends EventBase { * @param username The username of the client that is connecting */ public void onClientCompleteAuthentication(String username); - - public static void fireClientCompleteAuthentication(String username) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing ClientCompleteAuthenticationEvent"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if (eventListener instanceof EventClientCompleteAuthentication) { - EventClientCompleteAuthentication event = (EventClientCompleteAuthentication) eventListener; - event.onClientCompleteAuthentication(username); - } - } - } } /** * Fired when the connection to the custom server was closed on the server side. */ + @FunctionalInterface public static interface EventDisconnectServer extends EventBase { /** @@ -177,15 +117,5 @@ public static interface EventDisconnectServer extends EventBase { * @param client The client that is disconnecting */ public void onDisconnectServer(Client client); - - public static void fireDisconnectServer(Client client) { - MCTCommon.LOGGER.trace(MCTCommon.Event, "Firing CustomServerClientDisconnect"); - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if(eventListener instanceof EventDisconnectServer) { - EventDisconnectServer event = (EventDisconnectServer) eventListener; - event.onDisconnectServer(client); - } - } - } } } diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraft.java index 3a515a65..54f7ccd2 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraft.java @@ -1,5 +1,6 @@ package com.minecrafttas.mctcommon.mixin; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.objectweb.asm.Opcodes; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; @@ -20,38 +21,38 @@ @Mixin(Minecraft.class) public class MixinMinecraft { - - @Inject(method = "init", at = @At(value = "RETURN")) - public void inject_init(CallbackInfo ci) { - EventClientInit.fireOnClientInit((Minecraft)(Object)this); - } - - @Inject(method = "runGameLoop", at = @At(value = "HEAD")) - public void inject_runGameLoop(CallbackInfo ci) { - EventClientGameLoop.fireOnClientGameLoop((Minecraft)(Object)this); - } - - @Inject(method = "runTick", at = @At("HEAD")) - public void inject_runTick(CallbackInfo ci) { - EventClientTick.fireOnClientTick((Minecraft)(Object)this); - } - - @Inject(method = "launchIntegratedServer", at = @At("HEAD")) - public void inject_launchIntegratedServer(CallbackInfo ci) { - EventLaunchIntegratedServer.fireOnLaunchIntegratedServer(); - } - - @Inject(method = "Lnet/minecraft/client/Minecraft;loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/PlayerControllerMP;flipPlayer(Lnet/minecraft/entity/player/EntityPlayer;)V")) - public void inject_loadWorld(CallbackInfo ci) { - EventDoneLoadingWorld.fireOnDoneLoadingWorld(); - } - - @Shadow - private GuiScreen currentScreen; - - @Redirect(method = "displayGuiScreen", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;currentScreen:Lnet/minecraft/client/gui/GuiScreen;", opcode = Opcodes.PUTFIELD)) - public void modify_displayGuiScreen(Minecraft mc, GuiScreen guiScreen) { - guiScreen = EventOpenGui.fireOpenGuiEvent(guiScreen); - currentScreen = guiScreen; - } + + @Inject(method = "init", at = @At(value = "RETURN")) + public void inject_init(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventClientInit.class, (Minecraft) (Object) this); + } + + @Inject(method = "runGameLoop", at = @At(value = "HEAD")) + public void inject_runGameLoop(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventClientGameLoop.class, (Minecraft) (Object) this); + } + + @Inject(method = "runTick", at = @At("HEAD")) + public void inject_runTick(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventClientTick.class, (Minecraft) (Object) this); + } + + @Inject(method = "launchIntegratedServer", at = @At("HEAD")) + public void inject_launchIntegratedServer(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventLaunchIntegratedServer.class); + } + + @Inject(method = "Lnet/minecraft/client/Minecraft;loadWorld(Lnet/minecraft/client/multiplayer/WorldClient;Ljava/lang/String;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/multiplayer/PlayerControllerMP;flipPlayer(Lnet/minecraft/entity/player/EntityPlayer;)V")) + public void inject_loadWorld(CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventDoneLoadingWorld.class); + } + + @Shadow + private GuiScreen currentScreen; + + @Redirect(method = "displayGuiScreen", at = @At(value = "FIELD", target = "Lnet/minecraft/client/Minecraft;currentScreen:Lnet/minecraft/client/gui/GuiScreen;", opcode = Opcodes.PUTFIELD)) + public void modify_displayGuiScreen(Minecraft mc, GuiScreen guiScreen) { + guiScreen = (GuiScreen) EventListenerRegistry.fireEvent(EventOpenGui.class, guiScreen); + currentScreen = guiScreen; + } } diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java index 3b911a8b..8e6ba7fc 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinMinecraftServer.java @@ -1,5 +1,6 @@ package com.minecrafttas.mctcommon.mixin; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At.Shift; @@ -18,21 +19,21 @@ public class MixinMinecraftServer { @Inject(method = "run", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/MinecraftServer;init()Z", shift = Shift.AFTER)) public void inject_init(CallbackInfo ci) { - EventServerInit.fireServerStartEvent((MinecraftServer)(Object)this); + EventListenerRegistry.fireEvent(EventServerInit.class, (MinecraftServer)(Object)this); } @Inject(method = "initiateShutdown", at = @At("HEAD")) public void inject_initiateShutDown(CallbackInfo ci) { - EventServerStop.fireOnServerStop((MinecraftServer)(Object)this); + EventListenerRegistry.fireEvent(EventServerStop.class, (MinecraftServer)(Object)this); } @Inject(method = "tick", at = @At("HEAD")) public void inject_tick(CallbackInfo ci) { - EventServerTick.fireOnServerTick((MinecraftServer)(Object)this); + EventListenerRegistry.fireEvent(EventServerTick.class, (MinecraftServer)(Object)this); } // @Inject(method = "run", at = @At(value = "FIELD", target = "Lnet/minecraft/server/MinecraftServer;serverRunning:Z", shift = Shift.AFTER)) public void inject_run(CallbackInfo ci) { - EventServerGameLoop.fireOnServerGameLoop((MinecraftServer)(Object)this); + EventListenerRegistry.fireEvent(EventServerGameLoop.class, (MinecraftServer)(Object)this); } } diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinNetHandlerPlayClient.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinNetHandlerPlayClient.java index 562b3a56..87e0aca2 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinNetHandlerPlayClient.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinNetHandlerPlayClient.java @@ -2,6 +2,7 @@ import java.net.ConnectException; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -23,14 +24,14 @@ public class MixinNetHandlerPlayClient { @Inject(method = "handleJoinGame", at = @At(value = "RETURN")) public void clientJoinServerEvent(CallbackInfo ci) throws ConnectException { - EventPlayerJoinedClientSide.firePlayerJoinedClientSide(gameController.player); + EventListenerRegistry.fireEvent(EventPlayerJoinedClientSide.class, gameController.player); } @Inject(method = "handlePlayerListItem", at = @At(value = "HEAD")) public void otherClientJoinServerEvent(SPacketPlayerListItem packet, CallbackInfo ci) { for (int i = 0; i < packet.getEntries().size(); i++) { if (packet.getAction() == Action.ADD_PLAYER) { - EventOtherPlayerJoinedClientSide.fireOtherPlayerJoinedClientSide(packet.getEntries().get(i).getProfile()); + EventListenerRegistry.fireEvent(EventOtherPlayerJoinedClientSide.class, packet.getEntries().get(i).getProfile()); } } } diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinPlayerList.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinPlayerList.java index bf806f42..024b3250 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinPlayerList.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinPlayerList.java @@ -1,5 +1,6 @@ package com.minecrafttas.mctcommon.mixin; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,13 +15,13 @@ @Mixin(PlayerList.class) public class MixinPlayerList { - @Inject(method="initializeConnectionToPlayer", at=@At("RETURN"), remap = false) - public void inject_initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, CallbackInfo ci){ - EventPlayerJoinedServerSide.firePlayerJoinedServerSide(playerIn); - } - - @Inject(method = "playerLoggedOut", at = @At("HEAD")) - public void inject_playerLoggedOut(EntityPlayerMP playerIn, CallbackInfo ci) { - EventPlayerLeaveServerSide.firePlayerLeaveServerSide(playerIn); - } + @Inject(method = "initializeConnectionToPlayer", at = @At("RETURN"), remap = false) + public void inject_initializeConnectionToPlayer(NetworkManager netManager, EntityPlayerMP playerIn, CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventPlayerJoinedServerSide.class, playerIn); + } + + @Inject(method = "playerLoggedOut", at = @At("HEAD")) + public void inject_playerLoggedOut(EntityPlayerMP playerIn, CallbackInfo ci) { + EventListenerRegistry.fireEvent(EventPlayerLeaveServerSide.class, playerIn); + } } diff --git a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinWorldClient.java b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinWorldClient.java index 5dd01531..abf39e22 100644 --- a/src/main/java/com/minecrafttas/mctcommon/mixin/MixinWorldClient.java +++ b/src/main/java/com/minecrafttas/mctcommon/mixin/MixinWorldClient.java @@ -1,5 +1,6 @@ package com.minecrafttas.mctcommon.mixin; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,6 +15,6 @@ public class MixinWorldClient { @Inject(method = "sendQuittingDisconnectingPacket", at = @At(value = "HEAD")) public void clientLeaveServerEvent(CallbackInfo ci) { - EventPlayerLeaveClientSide.firePlayerLeaveClientSide(Minecraft.getMinecraft().player); + EventListenerRegistry.fireEvent(EventPlayerLeaveClientSide.class, Minecraft.getMinecraft().player); } } \ No newline at end of file diff --git a/src/main/java/com/minecrafttas/mctcommon/server/Client.java b/src/main/java/com/minecrafttas/mctcommon/server/Client.java index 0ffdf9ce..c3856df8 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/Client.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/Client.java @@ -219,10 +219,9 @@ public void failed(Throwable exc, Object attachment) { } /** - * Write packet to server + * Sends a packet to the server * - * @param id Buffer id - * @param buf Buffer + * @param bufferBuilder The bufferbuilder to use for sending a packet * @throws Exception Networking exception */ public void send(ByteBufferBuilder bufferBuilder) throws Exception { @@ -293,7 +292,7 @@ private void completeAuthentication(ByteBuffer buf) throws Exception { this.username = ByteBufferBuilder.readString(buf); LOGGER.debug(getLoggerMarker(), "Completing authentication for user {}", username); - EventClientCompleteAuthentication.fireClientCompleteAuthentication(username); + EventListenerRegistry.fireEvent(EventClientCompleteAuthentication.class, username); } private void handle(ByteBuffer buf) { @@ -327,7 +326,7 @@ private PacketID getPacketFromID(int id) throws InvalidPacketException { return packet; } } - throw new InvalidPacketException(String.format("Received invalid packet with id {}", id)); + throw new InvalidPacketException(String.format("Received invalid packet with id %s", id)); } public boolean isClosed() { diff --git a/src/main/java/com/minecrafttas/mctcommon/server/Server.java b/src/main/java/com/minecrafttas/mctcommon/server/Server.java index 3da5497a..d10ff67a 100644 --- a/src/main/java/com/minecrafttas/mctcommon/server/Server.java +++ b/src/main/java/com/minecrafttas/mctcommon/server/Server.java @@ -13,6 +13,7 @@ import java.util.List; import com.minecrafttas.mctcommon.MCTCommon; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventServer.EventDisconnectServer; import com.minecrafttas.mctcommon.server.Client.ClientCallback; import com.minecrafttas.mctcommon.server.interfaces.PacketID; @@ -49,7 +50,7 @@ public Server(int port, PacketID[] packetIDs) throws Exception { public void completed(AsynchronousSocketChannel clientSocket, Object attachment) { ClientCallback callback = (client) -> { - EventDisconnectServer.fireDisconnectServer(client); + EventListenerRegistry.fireEvent(EventDisconnectServer.class, client); clients.remove(client); LOGGER.debug(Server, "Disconnecting player from server"); }; diff --git a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java index 7c96bddb..7a40fb75 100644 --- a/src/main/java/com/minecrafttas/tasmod/TASmodClient.java +++ b/src/main/java/com/minecrafttas/tasmod/TASmodClient.java @@ -23,7 +23,6 @@ import com.minecrafttas.mctcommon.server.PacketHandlerRegistry; import com.minecrafttas.mctcommon.server.Server; import com.minecrafttas.tasmod.gui.InfoHud; -import com.minecrafttas.tasmod.handlers.InterpolationHandler; import com.minecrafttas.tasmod.handlers.LoadingScreenHandler; import com.minecrafttas.tasmod.networking.TASmodBufferBuilder; import com.minecrafttas.tasmod.networking.TASmodPackets; @@ -83,8 +82,6 @@ public class TASmodClient implements ClientModInitializer, EventClientInit, Even public static KeybindManager keybindManager; - public static InterpolationHandler interpolation = new InterpolationHandler(); - public static SavestateHandlerClient savestateHandlerClient = new SavestateHandlerClient(); public static Client client; @@ -150,7 +147,6 @@ public void onInitializeClient() { EventListenerRegistry.register(loadingScreenHandler); EventListenerRegistry.register(ticksyncClient); EventListenerRegistry.register(keybindManager); -// EventListenerRegistry.register(interpolation); EventListenerRegistry.register((EventOpenGui)(gui -> { if(gui instanceof GuiMainMenu) { openMainMenuScheduler.runAllTasks(); @@ -312,5 +308,4 @@ public GuiScreen onOpenGui(GuiScreen gui) { } return gui; } - } diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventClient.java b/src/main/java/com/minecrafttas/tasmod/events/EventClient.java index b60540fe..fe55d3b4 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventClient.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventClient.java @@ -1,74 +1,47 @@ package com.minecrafttas.tasmod.events; -import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; - import net.minecraft.client.Minecraft; +/** + * TASmod specific events fired on the client side + * + * @author Scribble + */ public interface EventClient { /** * Fired when the hotbar is drawn on screen - * @author Scribble - * */ + @FunctionalInterface public static interface EventDrawHotbar extends EventBase{ /** * Fired when the hotbar is drawn on screen */ public void onDrawHotbar(); - - public static void fireOnDrawHotbar() { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if(eventListener instanceof EventDrawHotbar) { - EventDrawHotbar event = (EventDrawHotbar) eventListener; - event.onDrawHotbar(); - } - } - } } /** * Fired at the end of a client tick - * @author Scribble - * */ + @FunctionalInterface public static interface EventClientTickPost extends EventBase{ /** * Fired at the end of a client tick */ public void onClientTickPost(Minecraft mc); - - public static void fireOnClientPostTick(Minecraft mc) { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if(eventListener instanceof EventClientTickPost) { - EventClientTickPost event = (EventClientTickPost) eventListener; - event.onClientTickPost(mc); - } - } - } } /** * Fired when the tickrate changes on the client side - * @author Scribble - * */ + @FunctionalInterface public static interface EventClientTickrateChange extends EventBase{ /** * Fired at the end of a client tick */ public void onClientTickrateChange(float tickrate); - - public static void fireOnClientTickrateChange(float tickrate) { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if(eventListener instanceof EventClientTickrateChange) { - EventClientTickrateChange event = (EventClientTickrateChange) eventListener; - event.onClientTickrateChange(tickrate); - } - } - } } } diff --git a/src/main/java/com/minecrafttas/tasmod/events/EventServer.java b/src/main/java/com/minecrafttas/tasmod/events/EventServer.java index acd5b432..a3c15f63 100644 --- a/src/main/java/com/minecrafttas/tasmod/events/EventServer.java +++ b/src/main/java/com/minecrafttas/tasmod/events/EventServer.java @@ -1,22 +1,21 @@ package com.minecrafttas.tasmod.events; -import static com.minecrafttas.tasmod.TASmod.LOGGER; - -import java.io.File; - -import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; -import com.minecrafttas.tasmod.util.LoggerMarkers; - import net.minecraft.server.MinecraftServer; +import java.io.File; + +/** + * TASmod specific events fired on the server side + * + * @author Scribble + */ public interface EventServer { /** * Fired when saving a savestate, before the savestate folder is copied - * @author Scribble - * */ + @FunctionalInterface public static interface EventSavestate extends EventBase { /** @@ -26,23 +25,12 @@ public static interface EventSavestate extends EventBase { * @param current The current folder that will be copied from */ public void onSavestateEvent(int index, File target, File current); - - public static void fireSavestateEvent(int index, File target, File current) { - LOGGER.trace(LoggerMarkers.Event, "SavestateEvent {} {} {}", index, target, current); - for (EventBase eventListener : TASmodEventListener.getEventListeners()) { - if(eventListener instanceof EventSavestate) { - EventSavestate event = (EventSavestate) eventListener; - event.onSavestateEvent(index, target, current); - } - } - } } /** * Fired when loading a savestate, before the savestate folder is copied - * @author Scribble - * */ + @FunctionalInterface public static interface EventLoadstate extends EventBase { /** @@ -52,85 +40,43 @@ public static interface EventLoadstate extends EventBase { * @param current The current folder that will be copied from */ public void onLoadstateEvent(int index, File target, File current); - - public static void fireLoadstateEvent(int index, File target, File current) { - LOGGER.trace(LoggerMarkers.Event, "LoadstateEvent {} {} {}", index, target, current); - for (EventBase eventListener : TASmodEventListener.getEventListeners()) { - if(eventListener instanceof EventLoadstate) { - EventLoadstate event = (EventLoadstate) eventListener; - event.onLoadstateEvent(index, target, current); - } - } - } } /** * Fired one tick after a loadstate was carried out - * @author Scribble - * */ + @FunctionalInterface public static interface EventCompleteLoadstate extends EventBase{ /** * Fired one tick after a loadstate was carried out */ public void onLoadstateComplete(); - - public static void fireLoadstateComplete() { - LOGGER.trace(LoggerMarkers.Event, "LoadstateCompleteEvent"); - for (EventBase eventListener : TASmodEventListener.getEventListeners()) { - if(eventListener instanceof EventCompleteLoadstate) { - EventCompleteLoadstate event = (EventCompleteLoadstate) eventListener; - event.onLoadstateComplete(); - } - } - } } /** * Fired at the end of a server tick - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerTickPost extends EventBase{ /** * Fired at the end of a server tick */ public void onServerTickPost(MinecraftServer minecraftServer); - - public static void fireServerTickPost(MinecraftServer minecraftServer) { -// LOGGER.trace(LoggerMarkers.Event, "ServerTickPostEvent"); - for (EventBase eventListener : TASmodEventListener.getEventListeners()) { - if(eventListener instanceof EventServerTickPost) { - EventServerTickPost event = (EventServerTickPost) eventListener; - event.onServerTickPost(minecraftServer); - } - } - } } /** * Fired when the tickrate changes on the server side - * @author Scribble - * */ + @FunctionalInterface public static interface EventServerTickrateChange extends EventBase{ /** * Fired at the end of a client tick */ public void onServerTickrateChange(float tickrate); - - public static void fireOnServerTickrateChange(float tickrate) { - for (EventBase eventListener : EventListenerRegistry.getEventListeners()) { - if(eventListener instanceof EventServerTickrateChange) { - EventServerTickrateChange event = (EventServerTickrateChange) eventListener; - event.onServerTickrateChange(tickrate); - } - } - } } } diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java index d6acae24..75a2e914 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraft.java @@ -2,6 +2,7 @@ import java.io.IOException; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -57,7 +58,7 @@ public void redirectRunTick(Minecraft mc) { TASmodClient.tickratechanger.advanceTick = false; TASmodClient.tickratechanger.changeClientTickrate(0F); } - EventClientTickPost.fireOnClientPostTick((Minecraft)(Object)this); + EventListenerRegistry.fireEvent(EventClientTickPost.class, (Minecraft)(Object)this); } @Shadow diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java index 11b8e8ed..7146a961 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/MixinMinecraftServer.java @@ -3,6 +3,7 @@ import java.util.Queue; import java.util.concurrent.FutureTask; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; @@ -76,7 +77,7 @@ public void redirectThreadSleep(long msToTick) { TASmod.tickratechanger.changeServerTickrate(0F); TASmod.tickratechanger.advanceTick = false; } - EventServerTickPost.fireServerTickPost((MinecraftServer)(Object)this); + EventListenerRegistry.fireEvent(EventServerTickPost.class, (MinecraftServer)(Object)this); long tickDuration = System.currentTimeMillis() - timeBeforeTick; diff --git a/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinGuiIngame.java b/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinGuiIngame.java index 693de69b..ebeeb56f 100644 --- a/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinGuiIngame.java +++ b/src/main/java/com/minecrafttas/tasmod/mixin/events/MixinGuiIngame.java @@ -1,5 +1,6 @@ package com.minecrafttas.tasmod.mixin.events; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; @@ -14,6 +15,6 @@ public class MixinGuiIngame { @Inject(method = "renderHotbar", at = @At("HEAD")) public void inject_renderHotbar(CallbackInfo ci) { - EventDrawHotbar.fireOnDrawHotbar(); + EventListenerRegistry.fireEvent(EventDrawHotbar.class); } } diff --git a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java index e72e2f51..23fd1d68 100644 --- a/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/savestates/SavestateHandlerServer.java @@ -15,6 +15,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.apache.commons.io.FileUtils; import org.apache.logging.log4j.Logger; @@ -196,7 +197,7 @@ public void saveState(int savestateIndex, boolean tickrate0, boolean changeIndex File currentfolder = new File(savestateDirectory, ".." + File.separator + worldname); File targetfolder = getSavestateFile(indexToSave); - EventSavestate.fireSavestateEvent(indexToSave, targetfolder, currentfolder); + EventListenerRegistry.fireEvent(EventSavestate.class, indexToSave, targetfolder, currentfolder); if (targetfolder.exists()) { logger.warn(LoggerMarkers.Savestate, "WARNING! Overwriting the savestate with the index {}", indexToSave); @@ -339,7 +340,7 @@ public void loadState(int savestateIndex, boolean tickrate0, boolean changeIndex File currentfolder = new File(savestateDirectory, ".." + File.separator + worldname); File targetfolder = getSavestateFile(indexToLoad); - EventLoadstate.fireLoadstateEvent(indexToLoad, targetfolder, currentfolder); + EventListenerRegistry.fireEvent(EventLoadstate.class, indexToLoad, targetfolder, currentfolder); /* * Prevents loading an InputSavestate when loading index 0 (Index 0 is the @@ -418,7 +419,7 @@ public void loadState(int savestateIndex, boolean tickrate0, boolean changeIndex TASmod.tickSchedulerServer.add(()->{ - EventCompleteLoadstate.fireLoadstateComplete(); + EventListenerRegistry.fireEvent(EventCompleteLoadstate.class); onLoadstateComplete(); // Unlock savestating @@ -922,7 +923,7 @@ public static void reattachEntityToPlayer(NBTTagCompound nbttagcompound, World w } /** - * Loads all worlds and players from the disk. Also sends the playerdata to the client in {@linkplain SavestatePlayerLoadingPacketHandler} + * Loads all worlds and players from the disk. Also sends the playerdata to the client in {@linkplain SavestateHandlerClient#onClientPacket(PacketID, ByteBuffer, String)} * * Side: Server */ @@ -1065,7 +1066,7 @@ public static void flushSaveHandler(MinecraftServer server) { * This adds the player to the chunk map so the server knows it can send the information to the client
*
* Side: Server - * @see disconnectPlayersFromChunkMap + * @see #disconnectPlayersFromChunkMap(MinecraftServer) */ public static void addPlayersToChunkMap(MinecraftServer server) { List players=server.getPlayerList().getPlayers(); @@ -1094,7 +1095,7 @@ public static void addPlayersToChunkMap(MinecraftServer server) { * Removing the player stops the server from sending chunks to the client.
*
* Side: Server - * @see SavestatesChunkControl#addPlayersToChunkMap() + * @see #addPlayersToChunkMap(MinecraftServer) */ public static void disconnectPlayersFromChunkMap(MinecraftServer server) { List players=server.getPlayerList().getPlayers(); diff --git a/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerClient.java b/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerClient.java index 858283da..9363b006 100644 --- a/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerClient.java +++ b/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerClient.java @@ -4,6 +4,7 @@ import java.nio.ByteBuffer; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.server.Client.Side; import com.minecrafttas.mctcommon.server.exception.PacketNotImplementedException; import com.minecrafttas.mctcommon.server.exception.WrongSideException; @@ -88,16 +89,16 @@ public void changeClientTickrate(float tickrate, boolean log) { mc.timer.tickLength = Float.MAX_VALUE; } ticksPerSecond = tickrate; - EventClientTickrateChange.fireOnClientTickrateChange(tickrate); + EventListenerRegistry.fireEvent(EventClientTickrateChange.class, tickrate); if (log) log("Setting the client tickrate to " + ticksPerSecond); } /** * Attempts to change the tickrate on the server. Sends a - * {@link ChangeTickratePacket} to the server + * {@link TASmodPackets#TICKRATE_CHANGE} packet to the server * - * @param tickrate + * @param tickrate The new server tickrate */ public void changeServerTickrate(float tickrate) { if (tickrate < 0) { diff --git a/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerServer.java b/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerServer.java index dab3898e..c05ae665 100644 --- a/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerServer.java +++ b/src/main/java/com/minecrafttas/tasmod/tickratechanger/TickrateChangerServer.java @@ -2,6 +2,7 @@ import java.nio.ByteBuffer; +import com.minecrafttas.mctcommon.events.EventListenerRegistry; import org.apache.logging.log4j.Logger; import com.minecrafttas.mctcommon.events.EventServer.EventPlayerJoinedServerSide; @@ -87,7 +88,7 @@ public void changeClientTickrate(float tickrate) { } /** - * Changes the tickrate of all clients. Sends a {@link ChangeTickratePacket} + * Changes the tickrate of all clients. Sends a {@link TASmodPackets#TICKRATE_CHANGE} packet to all clients * * @param tickrate The new tickrate of the client * @param log If a message should logged @@ -127,7 +128,7 @@ public void changeServerTickrate(float tickrate, boolean log) { } } ticksPerSecond = tickrate; - EventServerTickrateChange.fireOnServerTickrateChange(tickrate); + EventListenerRegistry.fireEvent(EventServerTickrateChange.class, tickrate); if (log) { log("Setting the server tickrate to " + ticksPerSecond); } @@ -180,7 +181,7 @@ public void advanceTick() { } /** - * Sends a {@link AdvanceTickratePacket} to all clients + * Sends a {@link TASmodPackets#TICKRATE_ADVANCE} packet to all clients */ private void advanceClientTick() { // Do not check for ticksPerSecond==0 here, because at this point, ticksPerSecond is 20 for one tick! diff --git a/src/test/java/mctcommon/event/EventTest.java b/src/test/java/mctcommon/event/EventTest.java index 72dd9c27..d1b98727 100644 --- a/src/test/java/mctcommon/event/EventTest.java +++ b/src/test/java/mctcommon/event/EventTest.java @@ -1,38 +1,172 @@ package mctcommon.event; +import com.minecrafttas.mctcommon.events.EventException; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; import com.minecrafttas.mctcommon.events.EventListenerRegistry; import com.minecrafttas.mctcommon.events.EventListenerRegistry.EventBase; +import static org.junit.jupiter.api.Assertions.*; + public class EventTest { - @FunctionalInterface - private interface TestEvent extends EventBase{ - - public void onTestEvent(); - - public static void test() {}; - } - - @Test - void testRegisteringEvents() { - - - TestEvent event = new TestEvent() { - @Override - public void onTestEvent() { - System.out.println("Test"); - } - }; - - EventListenerRegistry.register(event); - - try { - EventListenerRegistry.fireEvent(TestEvent.class); - } catch (Exception e) { - e.printStackTrace(); - } - } + @FunctionalInterface + private interface TestEvent extends EventBase { + + public int onTestEvent(); + + } + + @FunctionalInterface + private interface AdditionEvent extends EventBase { + + public int onAdditionEvent(int left, int right); + + } + + @AfterEach + void afterEach() { + EventListenerRegistry.clear(); + } + + /** + * Registers an event which returns 5 + */ + @Test + void testSimpleEvent() { + TestEvent event = () -> 5; + + EventListenerRegistry.register(event); + + int actual = (int) EventListenerRegistry.fireEvent(TestEvent.class); + assertEquals(5, actual); + } + + /** + * Test event with parameters + */ + @Test + void testParameterEvent() { + AdditionEvent event = Integer::sum; + + EventListenerRegistry.register(event); + + int actual = (int) EventListenerRegistry.fireEvent(AdditionEvent.class, 3, 6); + + assertEquals(9, actual); + } + + /** + * Test event with parameters, but too few parameters are fired + */ + @Test + void testParameterEventTooFew() { + AdditionEvent event = Integer::sum; + + EventListenerRegistry.register(event); + + Exception exception = assertThrows(EventException.class, () -> { + EventListenerRegistry.fireEvent(AdditionEvent.class, 3); + }); + + String expected = "mctcommon.event.EventTest$AdditionEvent: Event fired with the wrong number of parameters. Expected: 2, Actual: 1"; + assertEquals(expected, exception.getMessage()); + } + + /** + * Test event with parameters, but too many parameters are fired + */ + @Test + void testParameterEventTooMany() { + AdditionEvent event = new AdditionEvent() { + @Override + public int onAdditionEvent(int left, int right) { + return left + right; + } + }; + + EventListenerRegistry.register(event); + + Exception exception = assertThrows(EventException.class, () -> { + EventListenerRegistry.fireEvent(AdditionEvent.class, 3, 1, 3); + }); + + String expected = "mctcommon.event.EventTest$AdditionEvent: Event fired with the wrong number of parameters. Expected: 2, Actual: 3"; + assertEquals(expected, exception.getMessage()); + } + + /** + * Test multiple return values + */ + @Test + void testMultipleReturnValues() { + TestEvent event = () -> 5; + TestEvent event2 = () -> 7; + + EventListenerRegistry.register(event); + EventListenerRegistry.register(event2); + + int actual = (int) EventListenerRegistry.fireEvent(TestEvent.class); + assertEquals(7, actual); + } + + /** + * Tests a class which has an additional method with the same name but different parameters + */ + @Test + void testEventMethodwithSameName() { + + class TestClass implements TestEvent { + + public int onTestEvent(int test) { + return test; + } + + @Override + public int onTestEvent() { + return 1; + } + } + + TestClass test = new TestClass(); + + EventListenerRegistry.register(test); + + int actual = (int) EventListenerRegistry.fireEvent(TestEvent.class); + + assertEquals(1, actual); + } + + /** + * Test mismatched types + */ + @Test + void testParameterEventWrongTypes() { + AdditionEvent event = Integer::sum; + + EventListenerRegistry.register(event); + + Exception exception = assertThrows(EventException.class, () -> EventListenerRegistry.fireEvent(AdditionEvent.class, 3, 6D)); + + String expected = "mctcommon.event.EventTest$AdditionEvent: Event seems to be fired with the wrong parameter types or in the wrong order"; + assertEquals(expected, exception.getMessage()); + } + + /** + * Test unregistering eventlistener + */ + @Test + void testUnregister() { + TestEvent event = () -> 5; + + EventListenerRegistry.register(event); + + EventListenerRegistry.unregister(event); + + Exception exception = assertThrows(EventException.class, () -> EventListenerRegistry.fireEvent(TestEvent.class)); + String expected = "mctcommon.event.EventTest$TestEvent: The event has not been registered yet"; + assertEquals(expected, exception.getMessage()); + } }