diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/hullhider/HullHiderCommand.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/hullhider/HullHiderCommand.java index 76f333d1..fc7a606c 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/hullhider/HullHiderCommand.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/hullhider/HullHiderCommand.java @@ -57,10 +57,10 @@ public class HullHiderCommand extends SWCommand implements Listener { public HullHiderCommand() { super("hullhider"); - Bukkit.getPluginManager().registerEvents(hullHider, BauSystem.getInstance()); Bukkit.getScheduler().runTaskTimer(BauSystem.getInstance(), this::onTick, 1, 1); } + @Linked private final HullHider hullHider = new HullHider<>(); // Read on netty threads by the BauTechHider private final Map hulls = new ConcurrentHashMap<>(); diff --git a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java index 2789c4bf..7c503168 100644 --- a/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java +++ b/BauSystem/BauSystem_Main/src/de/steamwar/bausystem/features/tpslimit/TPSSystem.java @@ -50,6 +50,9 @@ import java.util.Arrays; @Linked public class TPSSystem implements Listener { + @Linked + private final TickManager tickManager = TickManager.impl; + public TPSSystem() { if (TickManager.impl.canFreeze()) { new TPSFreezeCommand(); @@ -68,7 +71,6 @@ public class TPSSystem implements Listener { new TickDefaultCommand(); new TPSBaseCommand(); new TickBaseCommand(); - Bukkit.getPluginManager().registerEvents(TickManager.impl, BauSystem.getInstance()); } @EventHandler diff --git a/CommonCore/Linkage/src/de/steamwar/linkage/AbstractLinker.java b/CommonCore/Linkage/src/de/steamwar/linkage/AbstractLinker.java index 4a2db53d..00d4b43a 100644 --- a/CommonCore/Linkage/src/de/steamwar/linkage/AbstractLinker.java +++ b/CommonCore/Linkage/src/de/steamwar/linkage/AbstractLinker.java @@ -28,6 +28,7 @@ import java.io.BufferedReader; import java.io.InputStreamReader; import java.lang.reflect.Field; import java.lang.reflect.Modifier; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -38,6 +39,7 @@ public abstract class AbstractLinker { protected final T plugin; private Map, Object> instances = new HashMap<>(); + private final List fieldInstances = new ArrayList<>(); protected AbstractLinker(@NonNull T plugin) { this.plugin = plugin; @@ -90,6 +92,7 @@ public abstract class AbstractLinker { ((Enable) any).enable(); } linkObject(any); + linkFields(any); }); } catch (SecurityException e) { Throwable cause = e.getCause(); @@ -119,6 +122,31 @@ public abstract class AbstractLinker { } } + private void linkFields(Object any) { + for (Field field : any.getClass().getDeclaredFields()) { + if (field.getAnnotation(Linked.class) == null) continue; + + Object value; + try { + field.setAccessible(true); + value = field.get(Modifier.isStatic(field.getModifiers()) ? null : any); + } catch (IllegalAccessException e) { + throw new SecurityException(e.getMessage(), e); + } + + if (value == null) { + String message = "Linked field " + any.getClass().getName() + "." + field.getName() + " is not initialised"; + throw new SecurityException(message, new IllegalStateException(message)); + } + + fieldInstances.add(value); + if (value instanceof Enable) { + ((Enable) value).enable(); + } + linkObject(value); + } + } + public final void unlink() { instances.forEach((aClass, any) -> { unlinkObject(any); @@ -126,6 +154,12 @@ public abstract class AbstractLinker { ((Disable) any).disable(); } }); + fieldInstances.forEach(any -> { + unlinkObject(any); + if (any instanceof Disable) { + ((Disable) any).disable(); + } + }); } public final void addLinkableInstance(@NonNull Object instance) { diff --git a/CommonCore/Linkage/src/de/steamwar/linkage/Linked.java b/CommonCore/Linkage/src/de/steamwar/linkage/Linked.java index 465600b1..6e1c6a8f 100644 --- a/CommonCore/Linkage/src/de/steamwar/linkage/Linked.java +++ b/CommonCore/Linkage/src/de/steamwar/linkage/Linked.java @@ -26,8 +26,12 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +/** + * On a class: the class is instantiated and linked. + * On a field of a linked class: the (already initialised) value of the field is linked as well, e.g. registered as listener. + */ @IndexAnnotated -@Retention(RetentionPolicy.SOURCE) -@Target({ElementType.TYPE}) +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.FIELD}) public @interface Linked { }