Added ModAccessor sturcture for adding mod compats

This commit is contained in:
tom lee
2022-01-09 14:56:49 +08:00
parent 943a2d5cad
commit d1e1970c18
7 changed files with 72 additions and 19 deletions
@@ -60,7 +60,6 @@ public class ClientApi
private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class);
private static final IMinecraftRenderWrapper MC_RENDER = SingletonHandler.get(IMinecraftRenderWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IWrapperFactory WRAPPER_FACTORY = SingletonHandler.get(IWrapperFactory.class);
private static final EventApi EVENT_API = EventApi.INSTANCE;
/**
@@ -19,14 +19,11 @@
package com.seibel.lod.core.api;
import java.util.HashSet;
import org.lwjgl.glfw.GLFW;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.worldGeneration.LodWorldGenerator;
import com.seibel.lod.core.enums.WorldType;
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.RegionPos;
import com.seibel.lod.core.render.GLProxy;
@@ -36,8 +33,6 @@ import com.seibel.lod.core.util.DetailDistanceUtil;
import com.seibel.lod.core.util.LodUtil;
import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.util.ThreadMapUtil;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
@@ -0,0 +1,53 @@
package com.seibel.lod.core.api;
import java.util.HashMap;
import java.util.Map;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.IModAccessor;
/**
* This class takes care of dependency injection
* for mods (for mod compatibility support).
*
* (Basically the same as SingletonHandler, except
* it can return null which means that mod aren't
* loaded in the game, or it haven't been implemented
* for that build.)
*/
public class ModAccessorApi {
private static final Map<Class<? extends IModAccessor>, IModAccessor> singletons = new HashMap<Class<? extends IModAccessor>, IModAccessor>();
public static void bind(Class<? extends IModAccessor> interfaceClass, IModAccessor modAccessor) throws IllegalStateException
{
// make sure we haven't already bound this singleton
if (singletons.containsKey(interfaceClass))
{
throw new IllegalStateException("The modAccessor [" + interfaceClass.getSimpleName() + "] has already been bound.");
}
// make sure the given singleton implements the interface
boolean singletonImplementsInterface = false;
for (Class<?> singletonInterface : modAccessor.getClass().getInterfaces())
{
if (singletonInterface.equals(interfaceClass))
{
singletonImplementsInterface = true;
break;
}
}
if (!singletonImplementsInterface)
{
throw new IllegalStateException("The singleton [" + interfaceClass.getSimpleName() + "] doesn't implement the interface [" + interfaceClass.getSimpleName() + "].");
}
ClientApi.LOGGER.info("DistantHorizon: Registored mod comatibility accessor for "+modAccessor.getModName());
singletons.put(interfaceClass, modAccessor);
}
@SuppressWarnings("unchecked")
public static <T extends IModAccessor> T get(Class<T> objectClass) throws ClassCastException
{
IModAccessor modAccessor = singletons.get(objectClass);
return modAccessor==null ? null : (T) modAccessor;
}
}
@@ -364,7 +364,7 @@ public class LodUtil
// get the chunks that are going to be rendered by Minecraft
HashSet<AbstractChunkPosWrapper> posToSkip = REFLECTION_HANDLER.sodiumPresent() ? MC_RENDER.getSodiumRenderedChunks() : MC_RENDER.getVanillaRenderedChunks();
HashSet<AbstractChunkPosWrapper> posToSkip = MC_RENDER.getVanillaRenderedChunks();
// remove everything outside the skipRadius,
@@ -22,6 +22,7 @@ package com.seibel.lod.core.wrapperInterfaces.minecraft;
import java.awt.Color;
import java.util.HashSet;
import com.seibel.lod.core.api.ModAccessorApi;
import com.seibel.lod.core.objects.math.Mat4f;
import com.seibel.lod.core.objects.math.Vec3d;
import com.seibel.lod.core.objects.math.Vec3f;
@@ -29,6 +30,7 @@ import com.seibel.lod.core.util.SingletonHandler;
import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory;
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
/**
* Contains everything related to
@@ -77,18 +79,8 @@ public interface IMinecraftRenderWrapper
*/
public default HashSet<AbstractChunkPosWrapper> getVanillaRenderedChunks()
{
return getMaximumRenderedChunks();
}
/**
* This method returns the ChunkPos of every chunk that
* Sodium is going to render this frame.
* <br>
* If not implemented this calls {@link #getMaximumRenderedChunks()}.
*/
public default HashSet<AbstractChunkPosWrapper> getSodiumRenderedChunks()
{
return getMaximumRenderedChunks();
ISodiumAccessor sodium = ModAccessorApi.get(ISodiumAccessor.class);
return sodium==null ? getMaximumRenderedChunks() : sodium.getNormalRenderedChunks();
}
/**
@@ -0,0 +1,5 @@
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
public abstract interface IModAccessor {
String getModName();
}
@@ -0,0 +1,9 @@
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
import java.util.HashSet;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
public interface ISodiumAccessor extends IModAccessor {
HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks();
}