From 3d19fec7230ad3b787614ee114b240b78ed8694b Mon Sep 17 00:00:00 2001 From: James Seibel Date: Fri, 15 Jul 2022 21:58:48 -0500 Subject: [PATCH] Revamp DependencyHandler The dependency handlers are now singletons instead of static, this prevents almost all duplicate code as each handler can now extend the parent DependencyHandler. Handlers no longer have to finish binding before being used, and they no longer have to call runDelayedSetup() before being used either. However dependencies that have circular references still need the runDelayedSetup() method to be called at somepoint; there will just be a warning if they are get() before that setup was done. --- .../java/com/seibel/lod/core/JarMain.java | 1 - .../a7/datatype/column/render/ColumnBox.java | 2 +- .../datatype/full/IdBiomeBlockStateMap.java | 2 +- .../lod/core/a7/level/DhClientLevel.java | 2 +- .../core/a7/level/DhClientServerLevel.java | 2 +- .../core/a7/save/io/LevelToFileMatcher.java | 2 +- .../structure/ClientOnlySaveStructure.java | 2 +- .../a7/save/structure/LocalSaveStructure.java | 2 +- .../lod/core/api/internal/a7/ClientApi.java | 4 +- .../lod/core/api/internal/a7/ServerApi.java | 2 +- .../bufferBuilding/CubicLodTemplate.java | 2 +- .../worldGeneration/BatchGenerator.java | 4 +- .../core/config/file/ConfigFileHandling.java | 4 +- .../lod/core/handlers/ReflectionHandler.java | 15 +++- .../DependencyHandler.java | 76 +++++++++--------- .../dependencyInjection/IBindable.java | 14 +++- .../ModAccessorHandler.java | 66 ++++----------- .../dependencyInjection/SingletonHandler.java | 80 ++++--------------- .../handlers/dimensionFinder/PlayerData.java | 2 +- .../lod/core/jar/JarDependencySetup.java | 2 +- .../seibel/lod/core/jar/gui/BaseJFrame.java | 2 +- .../lod/core/objects/lod/LodRegion.java | 4 +- .../objects/lod/VerticalLevelContainer.java | 4 +- .../lod/core/objects/opengl/LodBox.java | 2 +- .../com/seibel/lod/core/render/GLProxy.java | 2 +- .../seibel/lod/core/render/LodFogConfig.java | 4 +- .../lod/core/render/LodRenderProgram.java | 2 +- .../lod/core/render/RenderSystemTest.java | 2 +- .../seibel/lod/core/render/RenderUtil.java | 2 +- .../seibel/lod/core/render/a7LodRenderer.java | 4 +- .../com/seibel/lod/core/util/LodUtil.java | 4 +- .../config/ILodConfigWrapperSingleton.java | 2 +- .../minecraft/IMinecraftRenderWrapper.java | 10 +-- 33 files changed, 129 insertions(+), 201 deletions(-) diff --git a/src/main/java/com/seibel/lod/core/JarMain.java b/src/main/java/com/seibel/lod/core/JarMain.java index 4ae9e6ccd..414a3588d 100644 --- a/src/main/java/com/seibel/lod/core/JarMain.java +++ b/src/main/java/com/seibel/lod/core/JarMain.java @@ -43,7 +43,6 @@ public class JarMain { JarDependencySetup.createInitialBindings(); - SingletonHandler.finishBinding(); GitlabGetter.init(); System.out.println("WARNING: The standalone jar still work in progress"); diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java index 42dde1168..55fed5c97 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnBox.java @@ -29,7 +29,7 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; public class ColumnBox { - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public static void addBoxQuadsToBuilder(LodQuadBuilder builder, short xSize, short ySize, short zSize, short x, short y, short z, int color, byte skyLight, byte blockLight, long topData, long botData, ColumnArrayView[][] adjData) diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java index 120ec5138..71281b117 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java @@ -12,7 +12,7 @@ import java.util.Objects; // WARNING: This is not THREAD-SAFE! public class IdBiomeBlockStateMap { - public static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class); + public static final IWrapperFactory FACTORY = SingletonHandler.INSTANCE.get(IWrapperFactory.class); public static final class Entry { public final IBiomeWrapper biome; diff --git a/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java index e40da4aa9..7ec47e03d 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java @@ -23,7 +23,7 @@ import java.util.concurrent.CompletableFuture; public class DhClientLevel implements IClientLevel { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public final ClientOnlySaveStructure save; public final RemoteDataFileHandler dataFileHandler; public final RenderFileHandler renderFileHandler; diff --git a/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java index 825c36d2c..969653384 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java @@ -23,7 +23,7 @@ import java.util.concurrent.CompletableFuture; public class DhClientServerLevel implements IClientLevel, IServerLevel { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); - private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public final LocalSaveStructure save; public final LocalDataFileHandler dataFileHandler; public RenderFileHandler renderFileHandler = null; diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/LevelToFileMatcher.java b/src/main/java/com/seibel/lod/core/a7/save/io/LevelToFileMatcher.java index 2483e522b..ff1e3ac3d 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/LevelToFileMatcher.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/LevelToFileMatcher.java @@ -20,7 +20,7 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.atomic.AtomicBoolean; public class LevelToFileMatcher implements AutoCloseable { - private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(), () -> Config.Client.Advanced.Debugging.DebugSwitch.logFileSubDimEvent.get()); diff --git a/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java b/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java index c9602d7c9..8a06f7d2a 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java +++ b/src/main/java/com/seibel/lod/core/a7/save/structure/ClientOnlySaveStructure.java @@ -18,7 +18,7 @@ import java.util.stream.Stream; public class ClientOnlySaveStructure extends SaveStructure { final File folder; - private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public static final String INVALID_FILE_CHARACTERS_REGEX = "[\\\\/:*?\"<>|]"; private static String getServerFolderName() { diff --git a/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java b/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java index 15f906c9b..e36d6fc9d 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java +++ b/src/main/java/com/seibel/lod/core/a7/save/structure/LocalSaveStructure.java @@ -9,7 +9,7 @@ import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import java.io.File; public class LocalSaveStructure extends SaveStructure { - private static final IMinecraftSharedWrapper MC = SingletonHandler.get(IMinecraftSharedWrapper.class); + private static final IMinecraftSharedWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftSharedWrapper.class); private File debugPath = new File(""); diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java index 72359aafc..463261d69 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java @@ -60,8 +60,8 @@ public class ClientApi public static final ClientApi INSTANCE = new ClientApi(); public static RenderSystemTest testRenderer = new RenderSystemTest(); - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.INSTANCE.get(IMinecraftRenderWrapper.class); public static final boolean ENABLE_LAG_SPIKE_LOGGING = false; public static final long LAG_SPIKE_THRESHOLD_NS = TimeUnit.NANOSECONDS.convert(16, TimeUnit.MILLISECONDS); diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java index f138fff31..ee9b32ddd 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java @@ -43,7 +43,7 @@ public class ServerApi public static final boolean ENABLE_STACK_DUMP_LOGGING = false; public static final ServerApi INSTANCE = new ServerApi(); private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); - private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class); + private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.INSTANCE.get(IVersionConstants.class); private ServerApi() { diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java index 18f6a7c03..96945eace 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java @@ -38,7 +38,7 @@ import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; */ public class CubicLodTemplate { - private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.INSTANCE.get(ILodConfigWrapperSingleton.class); public static void addLodToBuffer(long data, long topData, long botData, LodDataView[][] adjData, boolean[] adjFillBlack, byte detailLevel, int offsetPosX, int offsetOosZ, LodQuadBuilder quadBuilder, EDebugMode debugging) diff --git a/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java b/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java index 74fbcea25..4e0b4c751 100644 --- a/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java +++ b/src/main/java/com/seibel/lod/core/builders/worldGeneration/BatchGenerator.java @@ -42,8 +42,8 @@ public class BatchGenerator { public static final boolean ENABLE_GENERATOR_STATS_LOGGING = false; - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); - private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IWrapperFactory FACTORY = SingletonHandler.INSTANCE.get(IWrapperFactory.class); public AbstractBatchGenerationEnvionmentWrapper generationGroup; public ILevel targetLodLevel; public static final int generationGroupSize = 4; diff --git a/src/main/java/com/seibel/lod/core/config/file/ConfigFileHandling.java b/src/main/java/com/seibel/lod/core/config/file/ConfigFileHandling.java index fc3ebb06e..a1dc49dd8 100644 --- a/src/main/java/com/seibel/lod/core/config/file/ConfigFileHandling.java +++ b/src/main/java/com/seibel/lod/core/config/file/ConfigFileHandling.java @@ -24,7 +24,7 @@ import java.nio.file.Path; * @version 2022-5-26 */ public class ConfigFileHandling { - public static final Path ConfigPath = SingletonHandler.get(IMinecraftSharedWrapper.class).getInstallationDirectory().toPath().resolve("config").resolve(ModInfo.NAME+".toml"); + public static final Path ConfigPath = SingletonHandler.INSTANCE.get(IMinecraftSharedWrapper.class).getInstallationDirectory().toPath().resolve("config").resolve(ModInfo.NAME+".toml"); /** Saves the config to the file */ public static void saveToFile() { @@ -170,7 +170,7 @@ public class ConfigFileHandling { } catch (IOException ex) { System.out.println("Creating file failed"); ex.printStackTrace(); - SingletonHandler.get(IMinecraftClientWrapper.class).crashMinecraft("Loading file and resetting config file failed at path ["+ConfigPath+"]. Please check the file is ok and you have the permissions", ex); + SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class).crashMinecraft("Loading file and resetting config file failed at path ["+ConfigPath+"]. Please check the file is ok and you have the permissions", ex); } } } diff --git a/src/main/java/com/seibel/lod/core/handlers/ReflectionHandler.java b/src/main/java/com/seibel/lod/core/handlers/ReflectionHandler.java index 6010c19fd..db045085a 100644 --- a/src/main/java/com/seibel/lod/core/handlers/ReflectionHandler.java +++ b/src/main/java/com/seibel/lod/core/handlers/ReflectionHandler.java @@ -36,7 +36,7 @@ import com.seibel.lod.core.enums.rendering.EFogDrawMode; * presence/absence of Vivecraft. * * @author James Seibel - * @version 12-14-2021 + * @version 2022-7-15 */ public class ReflectionHandler implements IReflectionHandler { @@ -49,14 +49,23 @@ public class ReflectionHandler implements IReflectionHandler private Boolean sodiumPresent = null; private boolean optifinePresent = false; - + + private boolean delayedSetupDone = false; + + + + @Override public void finishDelayedSetup() { - mcOptionsObject = SingletonHandler.get(IMinecraftClientWrapper.class).getOptionsObject(); + mcOptionsObject = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class).getOptionsObject(); setupFogField(mcOptionsObject.getClass().getDeclaredFields()); + + this.delayedSetupDone = true; } + @Override + public boolean getDelayedSetupComplete() { return this.delayedSetupDone; } private ReflectionHandler() { diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/DependencyHandler.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/DependencyHandler.java index e3754a507..db060bff6 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/DependencyHandler.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/DependencyHandler.java @@ -19,19 +19,35 @@ package com.seibel.lod.core.handlers.dependencyInjection; +import org.apache.logging.log4j.Logger; + import java.util.HashMap; import java.util.Map; /** * This class takes care of tracking objects used in dependency injection. - * + * + * @param extends IBindable and defines what interfaces this dependency handler can deal with. * @author James Seibel - * @version 3-4-2022 + * @version 2022-7-15 */ -public class DependencyHandler +public class DependencyHandler { - private final Map, Object> dependencies = new HashMap, Object>(); - private boolean bindingFinished = false; + protected final Logger logger; + + protected final Map, Object> dependencies = new HashMap, Object>(); + + /** Internal class reference to BindableType since we can't get it any other way. */ + protected final Class bindableInterface; + + + + public DependencyHandler(Class newBindableInterface, Logger newLogger) + { + this.bindableInterface = newBindableInterface; + this.logger = newLogger; + } + /** @@ -42,15 +58,8 @@ public class DependencyHandler * @throws IllegalStateException if the implementation object doesn't implement * the interface or the interface has already been bound. */ - public void bind(Class dependencyInterface, Object dependencyImplementation) throws IllegalStateException + public void bind(Class dependencyInterface, Object dependencyImplementation) throws IllegalStateException { - // only allow binding before the finishBinding method is called - if (bindingFinished) - { - throw new IllegalStateException("The dependency [" + dependencyInterface.getSimpleName() + "] cannot be bound, Binding is finished for [" + this.getClass().getSimpleName() + "]. Make sure your bindings are happening before the [bindingFinished] method is being called."); - } - - // make sure we haven't already bound this dependency if (dependencies.containsKey(dependencyInterface)) { @@ -60,7 +69,7 @@ public class DependencyHandler // make sure the given dependency implements the necessary interfaces boolean implementsInterface = checkIfClassImplements(dependencyImplementation.getClass(), dependencyInterface); - boolean implementsBindable = checkIfClassImplements(dependencyImplementation.getClass(), IBindable.class); + boolean implementsBindable = checkIfClassImplements(dependencyImplementation.getClass(), this.bindableInterface); // display any errors if (!implementsInterface) @@ -125,42 +134,31 @@ public class DependencyHandler * (this shouldn't normally happen, unless the bound object changed somehow) */ @SuppressWarnings("unchecked") - public T get(Class interfaceClass) throws ClassCastException + public T get(Class interfaceClass) throws ClassCastException { - // getting dependencies should only happen after everything has been bound - if (!bindingFinished) + T dependency = (T) dependencies.get(interfaceClass); + if (dependency != null && !dependency.getDelayedSetupComplete()) { - throw new IllegalStateException("Binding hasn't been finished for [" + this.getClass().getSimpleName() + "]. Make sure you are calling the [bindingFinished] method before calling [get]."); + // a warning can be used here instead if desired + //this.logger.warn("Got dependency of type [" + interfaceClass.getSimpleName() + "], but the dependency's delayed setup hasn't been run!"); + throw new IllegalStateException("Got dependency of type [" + interfaceClass.getSimpleName() + "], but the dependency's delayed setup hasn't been run!"); } - return (T) dependencies.get(interfaceClass); + return dependency; } - /** - * Should only be called after all Binds have been done. - * Calls the delayedSetup method for each dependency.

- * - * This is done so we can have circular dependencies. - */ - public void finishBinding() + /** Runs delayed setup for any dependencies that require it. */ + public void runDelayedSetup() { - // (yes technically the binding isn't finished, - // but this needs to be set to "true" so we can use "get") - bindingFinished = true; - } - - /** returns whether the finishBinding method has been called */ - public boolean getBindingFinished() - { - return bindingFinished; - } - - public void runDelayedSetup() { for (Class interfaceKey : dependencies.keySet()) { IBindable concreteObject = get(interfaceKey); - concreteObject.finishDelayedSetup(); + if (!concreteObject.getDelayedSetupComplete()) + { + concreteObject.finishDelayedSetup(); + } } } + } diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/IBindable.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/IBindable.java index 601e54b72..f40ac0366 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/IBindable.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/IBindable.java @@ -37,8 +37,14 @@ public interface IBindable * If no circular dependencies are required this method * doesn't have to be implemented. */ - public default void finishDelayedSetup() - { - - } + public default void finishDelayedSetup() { } + + /** + * Returns if this dependency has been setup yet.

+ * + * If this object doesn't require a delayed setup, this + * method doesn't have to be implemented and should always return true. + */ + public default boolean getDelayedSetupComplete() { return true; } + } diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/ModAccessorHandler.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/ModAccessorHandler.java index fe85988e2..d4ce88eb1 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/ModAccessorHandler.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/ModAccessorHandler.java @@ -27,69 +27,37 @@ import java.lang.invoke.MethodHandles; /** * This class takes care of dependency injection for mods accessors. (for mod compatibility - * support). + * support).

* - * This is basically the same as the SingletonHandler, except it can return null. - * Getting null either means the mod isn't loaded in the game - * or it hasn't been implemented for the given Minecraft version. + * If a IModAccessor returns null either that means the mod isn't loaded in the game + * or an Accessor hasn't been implemented for the given Minecraft version. * * @author James Seibel * @author Leetom - * @version 3-1-2022 + * @version 2022-7-15 */ -public class ModAccessorHandler +public class ModAccessorHandler extends DependencyHandler { - private static final DependencyHandler dependencyHandler = new DependencyHandler(); private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); + public static final ModAccessorHandler INSTANCE = new ModAccessorHandler(IModAccessor.class, LOGGER); + + + public ModAccessorHandler(Class newBindableInterface, Logger newLogger) + { + super(newBindableInterface, LOGGER); + } + /** - * Links the given mod accessor to an interface, so it can be referenced later. - * - * @param interfaceClass The interface the mod accessor should implement. - * @param modAccessor An object that implements the interfaceClass interface. - * @throws IllegalStateException if the mod accessor doesn't implement - * the interface or the interface has already been bound. + * Go to {@link DependencyHandler#bind(Class, Object) DependencyHandler.bind()} + * for this method's javadocs. */ - public static void bind(Class interfaceClass, IModAccessor modAccessor) + public void bind(Class interfaceClass, IModAccessor modAccessor) throws IllegalStateException { - dependencyHandler.bind(interfaceClass, modAccessor); + super.bind(interfaceClass, modAccessor); LOGGER.info("Registered mod compatibility accessor for " + modAccessor.getModName()); } - /** - * Returns a mod accessor of type T if one has been bound. - * Returns null otherwise. - * - * @param class of the mod accessor - * (inferred from the objectClass parameter) - * @param objectClass class of the mod accessor, must extend IModAccessor - * @return the dependency of type T - * @throws ClassCastException If the mod accessor isn't able to be cast to type T. - * (this shouldn't normally happen, unless the bound object changed somehow) - */ - public static T get(Class objectClass) throws ClassCastException - { - return dependencyHandler.get(objectClass); - } - - - /** - * Should only be called after all Binds have been done. - * Calls the delayedSetup method for each dependency.

- * - * This is done so we can have circular dependencies. - */ - public static void finishBinding() - { - dependencyHandler.finishBinding(); - } - - /** returns whether the finishBinding method has been called */ - public static boolean bindingFinished() - { - return dependencyHandler.getBindingFinished(); - } - } diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java index cecc5e710..3dd9e6620 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java @@ -19,80 +19,28 @@ package com.seibel.lod.core.handlers.dependencyInjection; +import com.seibel.lod.core.logging.DhLoggerBuilder; +import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModAccessor; +import org.apache.logging.log4j.Logger; + +import java.lang.invoke.MethodHandles; + /** * This class takes care of dependency injection * for singletons. * * @author James Seibel - * @version 3-5-2022 + * @version 2022-7-15 */ -public class SingletonHandler +public class SingletonHandler extends DependencyHandler { - private static final DependencyHandler dependencyHandler = new DependencyHandler(); - - // TODO: FIX Javadoc - // This is the exact same javadoc as in DependencyHandler.java - // Ths method doesnt even use dependencyInterface or dependencyImplementation - /** - * Links the given implementation object to an interface, so it can be referenced later. - * - * @param interfaceClass The interface the implementation object should implement. - * @param singletonReference An object that implements the dependencyInterface interface. - * @throws IllegalStateException if the implementation object doesn't implement - * the interface or the interface has already been bound. - */ - public static void bind(Class interfaceClass, Object singletonReference) throws IllegalStateException - { - dependencyHandler.bind(interfaceClass, singletonReference); - } - - /** - * Returns a dependency of type T if one has been bound. - * Returns null otherwise. - * - * @param class of the dependency - * (inferred from the objectClass parameter) - * @param interfaceClass Interface of the dependency - * @return the dependency of type T - * @throws NullPointerException If no dependency was bound. - * @throws ClassCastException If the dependency isn't able to be cast to type T. - * (this shouldn't normally happen, unless the bound object changed somehow) - */ - public static T get(Class interfaceClass) throws NullPointerException, ClassCastException - { - T foundObject = dependencyHandler.get(interfaceClass); - - // throw an error if the given singleton doesn't exist. - if (foundObject == null) - { - throw new NullPointerException("The singleton [" + interfaceClass.getSimpleName() + "] was never bound. If you are calling [bind], make sure it is happening before you call [get]."); - } - - return foundObject; - } - public static T getOrNull(Class interfaceClass) throws ClassCastException - { - return dependencyHandler.get(interfaceClass); - } - - /** - * Should only be called after all Binds have been done. - * Calls the delayedSetup method for each dependency.

- * - * This is done so we can have circular dependencies. - */ - public static void finishBinding() - { - dependencyHandler.finishBinding(); - } + private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); - /** returns whether the finishBinding method has been called */ - public static boolean getBindingFinished() + public static final SingletonHandler INSTANCE = new SingletonHandler(IBindable.class, LOGGER); + + + public SingletonHandler(Class newBindableInterface, Logger newLogger) { - return dependencyHandler.getBindingFinished(); - } - - public static void runDelayedSetup() { - dependencyHandler.runDelayedSetup(); + super(newBindableInterface, newLogger); } } diff --git a/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java b/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java index cf3b74f40..abdd44163 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java +++ b/src/main/java/com/seibel/lod/core/handlers/dimensionFinder/PlayerData.java @@ -38,7 +38,7 @@ import java.io.File; */ public class PlayerData { - public static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class); + public static final IWrapperFactory FACTORY = SingletonHandler.INSTANCE.get(IWrapperFactory.class); private static final String playerDataFileName = "_playerData.toml"; diff --git a/src/main/java/com/seibel/lod/core/jar/JarDependencySetup.java b/src/main/java/com/seibel/lod/core/jar/JarDependencySetup.java index d30102e2b..dfb07009e 100644 --- a/src/main/java/com/seibel/lod/core/jar/JarDependencySetup.java +++ b/src/main/java/com/seibel/lod/core/jar/JarDependencySetup.java @@ -6,7 +6,7 @@ import com.seibel.lod.core.wrapperInterfaces.config.IConfigWrapper; public class JarDependencySetup { public static void createInitialBindings() { - SingletonHandler.bind(IConfigWrapper.class, ConfigWrapper.INSTANCE); + SingletonHandler.INSTANCE.bind(IConfigWrapper.class, ConfigWrapper.INSTANCE); ConfigWrapper.init(); } } diff --git a/src/main/java/com/seibel/lod/core/jar/gui/BaseJFrame.java b/src/main/java/com/seibel/lod/core/jar/gui/BaseJFrame.java index 673856072..f00c4328f 100644 --- a/src/main/java/com/seibel/lod/core/jar/gui/BaseJFrame.java +++ b/src/main/java/com/seibel/lod/core/jar/gui/BaseJFrame.java @@ -33,7 +33,7 @@ public class BaseJFrame extends JFrame { } public void init() { - setTitle(SingletonHandler.get(IConfigWrapper.class).getLang("lod.title")); + setTitle(SingletonHandler.INSTANCE.get(IConfigWrapper.class).getLang("lod.title")); try { setIconImage(new FlatSVGIcon(JarMain.accessFile("icon.svg")).getImage()); } catch (Exception e) {e.printStackTrace();} diff --git a/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java b/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java index c632cd7f2..d3d85ed82 100644 --- a/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java +++ b/src/main/java/com/seibel/lod/core/objects/lod/LodRegion.java @@ -50,7 +50,7 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; * @version 10-10-2021 */ public class LodRegion { - private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.INSTANCE.get(ILodConfigWrapperSingleton.class); /** Number of detail level supported by a region */ private static final byte POSSIBLE_LOD = LodUtil.DETAIL_OPTIONS; @@ -332,7 +332,7 @@ public class LodRegion { private EGenerationPriority getResolvedGenerationPriority() { EGenerationPriority priority = Config.Client.WorldGenerator.generationPriority.get(); - IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); if (priority == EGenerationPriority.AUTO) priority = MC.hasSinglePlayerServer() ? EGenerationPriority.FAR_FIRST : EGenerationPriority.BALANCED; return priority; diff --git a/src/main/java/com/seibel/lod/core/objects/lod/VerticalLevelContainer.java b/src/main/java/com/seibel/lod/core/objects/lod/VerticalLevelContainer.java index 3d2a839bd..889aaa648 100644 --- a/src/main/java/com/seibel/lod/core/objects/lod/VerticalLevelContainer.java +++ b/src/main/java/com/seibel/lod/core/objects/lod/VerticalLevelContainer.java @@ -68,7 +68,7 @@ public class VerticalLevelContainer implements LevelContainer size = 1 << (LodUtil.REGION_DETAIL_LEVEL - detailLevel); verticalSize = DetailDistanceUtil.getMaxVerticalData(detailLevel); dataContainer = new long[size * size * DetailDistanceUtil.getMaxVerticalData(detailLevel)]; - minHeight = SingletonHandler.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); + minHeight = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); } @Override @@ -319,7 +319,7 @@ public class VerticalLevelContainer implements LevelContainer } public VerticalLevelContainer(DataInputStream inputData, int version, byte expectedDetailLevel) throws IOException { - minHeight = SingletonHandler.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); + minHeight = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class).getWrappedClientWorld().getMinHeight(); detailLevel = inputData.readByte(); if (detailLevel != expectedDetailLevel) throw new IOException("Invalid Data: The expected detail level should be "+expectedDetailLevel+ diff --git a/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java b/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java index 9922a7611..05fb020c5 100644 --- a/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java +++ b/src/main/java/com/seibel/lod/core/objects/opengl/LodBox.java @@ -29,7 +29,7 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; public class LodBox { - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); public static void addBoxQuadsToBuilder(LodQuadBuilder builder, short xSize, short ySize, short zSize, short x, short y, short z, int color, byte skyLight, byte blockLight, long topData, long botData, LodDataView[][] adjData, diff --git a/src/main/java/com/seibel/lod/core/render/GLProxy.java b/src/main/java/com/seibel/lod/core/render/GLProxy.java index c12789057..f264c7b39 100644 --- a/src/main/java/com/seibel/lod/core/render/GLProxy.java +++ b/src/main/java/com/seibel/lod/core/render/GLProxy.java @@ -68,7 +68,7 @@ public class GLProxy { public static final boolean OVERRIDE_VANILLA_GL_LOGGER = ModInfo.IS_DEV_BUILD; - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); private ExecutorService workerThread = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder().setNameFormat(GLProxy.class.getSimpleName() + "-Worker-Thread").build()); diff --git a/src/main/java/com/seibel/lod/core/render/LodFogConfig.java b/src/main/java/com/seibel/lod/core/render/LodFogConfig.java index fa5f32c27..bdda1b374 100644 --- a/src/main/java/com/seibel/lod/core/render/LodFogConfig.java +++ b/src/main/java/com/seibel/lod/core/render/LodFogConfig.java @@ -46,8 +46,8 @@ import static com.seibel.lod.core.render.GLProxy.GL_LOGGER; */ public class LodFogConfig { - private static final IReflectionHandler REFLECTION_HANDLER = SingletonHandler.get(IReflectionHandler.class); - private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); + private static final IReflectionHandler REFLECTION_HANDLER = SingletonHandler.INSTANCE.get(IReflectionHandler.class); + private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.INSTANCE.get(ILodConfigWrapperSingleton.class); public static final boolean DEBUG_DUMP_GENERATED_CODE = false; diff --git a/src/main/java/com/seibel/lod/core/render/LodRenderProgram.java b/src/main/java/com/seibel/lod/core/render/LodRenderProgram.java index f553f12b7..0c8e152e9 100644 --- a/src/main/java/com/seibel/lod/core/render/LodRenderProgram.java +++ b/src/main/java/com/seibel/lod/core/render/LodRenderProgram.java @@ -32,7 +32,7 @@ public class LodRenderProgram extends ShaderProgram { public static final String VERTEX_SHADER_PATH = "shaders/standard.vert"; public static final String VERTEX_CURVE_SHADER_PATH = "shaders/curve.vert"; public static final String FRAGMENT_SHADER_PATH = "shaders/flat_shaded.frag"; - private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class); + private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.INSTANCE.get(IVersionConstants.class); public final VertexAttribute vao; diff --git a/src/main/java/com/seibel/lod/core/render/RenderSystemTest.java b/src/main/java/com/seibel/lod/core/render/RenderSystemTest.java index e538db2ec..0c8137dd9 100644 --- a/src/main/java/com/seibel/lod/core/render/RenderSystemTest.java +++ b/src/main/java/com/seibel/lod/core/render/RenderSystemTest.java @@ -45,7 +45,7 @@ public class RenderSystemTest { LogManager.getLogger(RenderSystemTest.class), () -> ELoggerMode.LOG_ALL_TO_CHAT); public static final ConfigBasedSpamLogger spamLogger = new ConfigBasedSpamLogger( LogManager.getLogger(RenderSystemTest.class), () -> ELoggerMode.LOG_ALL_TO_CHAT, 1); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.INSTANCE.get(IMinecraftRenderWrapper.class); ShaderProgram basicShader; GLVertexBuffer sameContextBuffer; diff --git a/src/main/java/com/seibel/lod/core/render/RenderUtil.java b/src/main/java/com/seibel/lod/core/render/RenderUtil.java index be6c14b2f..e1581bf75 100644 --- a/src/main/java/com/seibel/lod/core/render/RenderUtil.java +++ b/src/main/java/com/seibel/lod/core/render/RenderUtil.java @@ -35,7 +35,7 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; */ public class RenderUtil { - private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.INSTANCE.get(IMinecraftRenderWrapper.class); /** diff --git a/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java b/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java index c31e1fedc..ee51255c7 100644 --- a/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java +++ b/src/main/java/com/seibel/lod/core/render/a7LodRenderer.java @@ -79,8 +79,8 @@ public class a7LodRenderer } } - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class); + private static final IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.INSTANCE.get(IMinecraftRenderWrapper.class); public EDebugMode previousDebugMode = null; public final IClientLevel level; diff --git a/src/main/java/com/seibel/lod/core/util/LodUtil.java b/src/main/java/com/seibel/lod/core/util/LodUtil.java index 931cb213f..d978f5ee6 100644 --- a/src/main/java/com/seibel/lod/core/util/LodUtil.java +++ b/src/main/java/com/seibel/lod/core/util/LodUtil.java @@ -48,8 +48,8 @@ import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; */ public class LodUtil { - private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.getOrNull(IMinecraftClientWrapper.class); - private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.getOrNull(IMinecraftRenderWrapper.class); + private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); + private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.INSTANCE.get(IMinecraftRenderWrapper.class); /** * Vanilla render distances less than or equal to this will not allow partial diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java index 735d21e81..44b9b1caa 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java @@ -264,7 +264,7 @@ public interface ILodConfigWrapperSingleton extends IBindable default EGenerationPriority getResolvedGenerationPriority() { EGenerationPriority priority = Config.Client.WorldGenerator.generationPriority.get(); - IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); + IMinecraftClientWrapper MC = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); if (priority == EGenerationPriority.AUTO) priority = MC.hasSinglePlayerServer() ? EGenerationPriority.FAR_FIRST : EGenerationPriority.BALANCED; return priority; diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java index bf6671583..2d666d041 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftRenderWrapper.java @@ -85,7 +85,7 @@ public interface IMinecraftRenderWrapper extends IBindable */ default HashSet getVanillaRenderedChunks() { - ISodiumAccessor sodium = ModAccessorHandler.get(ISodiumAccessor.class); + ISodiumAccessor sodium = ModAccessorHandler.INSTANCE.get(ISodiumAccessor.class); return sodium==null ? getMaximumRenderedChunks() : sodium.getNormalRenderedChunks(); } @@ -101,10 +101,10 @@ public interface IMinecraftRenderWrapper extends IBindable */ default HashSet getMaximumRenderedChunks() { - IMinecraftClientWrapper mcWrapper = SingletonHandler.get(IMinecraftClientWrapper.class); - IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class); - IVersionConstants versionConstants = SingletonHandler.get(IVersionConstants.class); - IMinecraftClientWrapper minecraft = SingletonHandler.get(IMinecraftClientWrapper.class); + IMinecraftClientWrapper mcWrapper = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); + IWrapperFactory factory = SingletonHandler.INSTANCE.get(IWrapperFactory.class); + IVersionConstants versionConstants = SingletonHandler.INSTANCE.get(IVersionConstants.class); + IMinecraftClientWrapper minecraft = SingletonHandler.INSTANCE.get(IMinecraftClientWrapper.class); ILevelWrapper clientWorld = minecraft.getWrappedClientWorld(); int chunkDist = this.getRenderDistance() + 1; // For some reason having '+1' is actually closer to real value