package cz.jzitnik.game.handlers.events; import cz.jzitnik.game.Game; import cz.jzitnik.game.annotations.MineEventHandler; import cz.jzitnik.game.annotations.PlaceEventHandler; import cz.jzitnik.tui.ScreenRenderer; import org.reflections.Reflections; import org.reflections.scanners.Scanners; import org.reflections.util.ConfigurationBuilder; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import java.util.Set; public class EventHandlerProvider { @FunctionalInterface public interface Function { void accept(T t, U u, V v, W w); } public final List> mineHandlers = new ArrayList<>(); public final List> placeHandlers = new ArrayList<>(); public EventHandlerProvider() { registerHandlers(); } public void handlePlace(ScreenRenderer screenRenderer, Game game, int x, int y) { for (Function handler : placeHandlers) { handler.accept(screenRenderer, game, x, y); } } public void handleMine(ScreenRenderer screenRenderer, Game game, int x, int y) { for (Function handler : mineHandlers) { handler.accept(screenRenderer, game, x, y); } } private void registerHandlers() { Reflections reflections = new Reflections( new ConfigurationBuilder() .forPackage("cz.jzitnik.game.handlers.events.handlers.mine") .addScanners(Scanners.MethodsAnnotated) ); Set mineHandlers = reflections.getMethodsAnnotatedWith(MineEventHandler.class); for (Method method : mineHandlers) { if (method.getParameterCount() == 4 && method.getParameterTypes()[0] == ScreenRenderer.class && method.getParameterTypes()[1] == Game.class && method.getParameterTypes()[2] == int.class && method.getParameterTypes()[3] == int.class && method.getReturnType() == void.class) { try { Object instance = method.getDeclaringClass().getDeclaredConstructor().newInstance(); Function handler = (screenRenderer, game, x, y) -> { try { method.invoke(instance, screenRenderer, game, x, y); } catch (Exception e) { e.printStackTrace(); } }; this.mineHandlers.add(handler); } catch (Exception e) { e.printStackTrace(); } } } Set placeHandlers = reflections.getMethodsAnnotatedWith(PlaceEventHandler.class); for (Method method : placeHandlers) { if (method.getParameterCount() == 4 && method.getParameterTypes()[0] == ScreenRenderer.class && method.getParameterTypes()[1] == Game.class && method.getParameterTypes()[2] == int.class && method.getParameterTypes()[3] == int.class && method.getReturnType() == void.class) { try { Object instance = method.getDeclaringClass().getDeclaredConstructor().newInstance(); Function handler = (screenRenderer, game, x, y) -> { try { method.invoke(instance, screenRenderer, game, x, y); } catch (Exception e) { e.printStackTrace(); } }; this.placeHandlers.add(handler); } catch (Exception e) { e.printStackTrace(); } } } } }