Update the DependencyHandler to support circular references
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
package com.seibel.lod.core.handlers;
|
||||
|
||||
import com.seibel.lod.core.enums.rendering.FogDrawMode;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* A singleton used to get variables from methods
|
||||
@@ -34,9 +35,9 @@ import com.seibel.lod.core.enums.rendering.FogDrawMode;
|
||||
* different MC versions.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-14-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IReflectionHandler
|
||||
public interface IReflectionHandler extends IBindable
|
||||
{
|
||||
/** @returns Whether Optifine is set to render fog or not. */
|
||||
FogDrawMode getFogDrawMode();
|
||||
|
||||
+90
-16
@@ -23,15 +23,15 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class takes care of dependency injection
|
||||
* for dependencies.
|
||||
* This class takes care of tracking objects used in dependency injection.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 3-1-2022
|
||||
* @version 3-4-2022
|
||||
*/
|
||||
public class DependencyHandler
|
||||
{
|
||||
private static final Map<Class<?>, Object> dependencies = new HashMap<Class<?>, Object>();
|
||||
private final Map<Class<?>, Object> dependencies = new HashMap<Class<?>, Object>();
|
||||
private boolean bindingFinished = false;
|
||||
|
||||
|
||||
/**
|
||||
@@ -44,6 +44,13 @@ public class DependencyHandler
|
||||
*/
|
||||
public void bind(Class<?> depenencyInterface, Object dependencyImplementation) throws IllegalStateException
|
||||
{
|
||||
// only allow binding before the finishBinding method is called
|
||||
if (bindingFinished)
|
||||
{
|
||||
throw new IllegalStateException("The dependency [" + depenencyInterface.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(depenencyInterface))
|
||||
{
|
||||
@@ -51,24 +58,60 @@ public class DependencyHandler
|
||||
}
|
||||
|
||||
|
||||
// make sure the given dependency implements the interface
|
||||
boolean dependencyImplementsInterface = false;
|
||||
for (Class<?> implementationInterface : dependencyImplementation.getClass().getInterfaces())
|
||||
{
|
||||
if (implementationInterface.equals(depenencyInterface))
|
||||
{
|
||||
dependencyImplementsInterface = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!dependencyImplementsInterface)
|
||||
// make sure the given dependency implements the necessary interfaces
|
||||
boolean implementsInterface = checkIfClassImplements(dependencyImplementation.getClass(), depenencyInterface);
|
||||
boolean implementsBindable = checkIfClassImplements(dependencyImplementation.getClass(), IBindable.class);
|
||||
|
||||
// display any errors
|
||||
if (!implementsInterface)
|
||||
{
|
||||
throw new IllegalStateException("The dependency [" + dependencyImplementation.getClass().getSimpleName() + "] doesn't implement the interface [" + depenencyInterface.getSimpleName() + "].");
|
||||
}
|
||||
if (!implementsBindable)
|
||||
{
|
||||
throw new IllegalStateException("The dependency [" + dependencyImplementation.getClass().getSimpleName() + "] doesn't implement the interface [" + IBindable.class.getSimpleName() + "].");
|
||||
}
|
||||
|
||||
|
||||
dependencies.put(depenencyInterface, dependencyImplementation);
|
||||
}
|
||||
/**
|
||||
* Checks if classToTest (or one of its ancestors)
|
||||
* implements the given interface.
|
||||
*/
|
||||
private boolean checkIfClassImplements(Class<?> classToTest, Class<?> interfaceToLookFor)
|
||||
{
|
||||
// check the parent class (if applicable)
|
||||
if (classToTest.getSuperclass() != Object.class && classToTest.getSuperclass() != null)
|
||||
{
|
||||
if (checkIfClassImplements(classToTest.getSuperclass(), interfaceToLookFor))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// check interfaces
|
||||
for (Class<?> implementationInterface : classToTest.getInterfaces())
|
||||
{
|
||||
// recurse to check interface parents if necessary
|
||||
if (implementationInterface.getInterfaces().length != 0)
|
||||
{
|
||||
if (checkIfClassImplements(implementationInterface, interfaceToLookFor))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (implementationInterface.equals(interfaceToLookFor))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a dependency of type T if one has been bound.
|
||||
@@ -82,9 +125,40 @@ public class DependencyHandler
|
||||
* (this shouldn't normally happen, unless the bound object changed somehow)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T get(Class<T> interfaceClass) throws ClassCastException
|
||||
public <T extends IBindable> T get(Class<?> interfaceClass) throws ClassCastException
|
||||
{
|
||||
// getting dependencies should only happen after everything has been bound
|
||||
if (!bindingFinished)
|
||||
{
|
||||
throw new IllegalStateException("Binding hasn't been finished for [" + this.getClass().getSimpleName() + "]. Make sure you are calling the [bindingFinished] method before calling [get].");
|
||||
}
|
||||
|
||||
return (T) dependencies.get(interfaceClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should only be called after all Binds have been done.
|
||||
* Calls the delayedSetup method for each dependency. <br> <br>
|
||||
*
|
||||
* This is done so we can have circular dependencies.
|
||||
*/
|
||||
public void finishBinding()
|
||||
{
|
||||
// (yes technically the binding isn't finished,
|
||||
// but this needs to be set to "true" so we can use "get")
|
||||
bindingFinished = true;
|
||||
|
||||
for (Class<?> interfaceKey : dependencies.keySet())
|
||||
{
|
||||
IBindable concreteObject = get(interfaceKey);
|
||||
concreteObject.finishDelayedSetup();
|
||||
}
|
||||
}
|
||||
|
||||
/** returns whether the finishBinding method has been called */
|
||||
public boolean getBindingFinished()
|
||||
{
|
||||
return bindingFinished;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.seibel.lod.core.handlers.dependencyInjection;
|
||||
|
||||
/**
|
||||
* Necessary for all singletons that can be dependency injected.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 3-4-2022
|
||||
*/
|
||||
public interface IBindable
|
||||
{
|
||||
/**
|
||||
* Finish initializing this object. <br> <br>
|
||||
*
|
||||
* Generally this should just used for getting other objects through
|
||||
* dependency injection and is specifically designed to allow
|
||||
* for circular references. <br><br>
|
||||
*
|
||||
* If no circular dependencies are required this method
|
||||
* doesn't have to be implemented.
|
||||
*/
|
||||
public default void finishDelayedSetup()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
+18
@@ -70,4 +70,22 @@ public class ModAccessorHandler
|
||||
return dependencyHandler.get(objectClass);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should only be called after all Binds have been done.
|
||||
* Calls the delayedSetup method for each dependency. <br> <br>
|
||||
*
|
||||
* 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();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+19
-1
@@ -24,7 +24,7 @@ package com.seibel.lod.core.handlers.dependencyInjection;
|
||||
* for singletons.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 3-1-2022
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public class SingletonHandler
|
||||
{
|
||||
@@ -69,4 +69,22 @@ public class SingletonHandler
|
||||
return foundObject;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Should only be called after all Binds have been done.
|
||||
* Calls the delayedSetup method for each dependency. <br> <br>
|
||||
*
|
||||
* 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 getBindingFinished()
|
||||
{
|
||||
return dependencyHandler.getBindingFinished();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.seibel.lod.core.wrapperInterfaces;
|
||||
|
||||
import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* A singleton that contains variables specific to each version of Minecraft
|
||||
@@ -8,9 +9,9 @@ import com.seibel.lod.core.enums.config.DistanceGenerationMode;
|
||||
* blocks can be negative, which changes how we generate LODs.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-11-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IVersionConstants {
|
||||
public interface IVersionConstants extends IBindable {
|
||||
/** @returns the minimum height blocks can be generated */
|
||||
int getMinimumWorldHeight();
|
||||
|
||||
|
||||
@@ -20,33 +20,29 @@
|
||||
package com.seibel.lod.core.wrapperInterfaces;
|
||||
|
||||
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.objects.lod.LodDimension;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractBatchGenerationEnvionmentWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractExperimentalWorldGeneratorWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGeneratorWrapper;
|
||||
|
||||
/**
|
||||
* This handles creating abstract wrapper objects.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-14-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IWrapperFactory {
|
||||
public interface IWrapperFactory extends IBindable
|
||||
{
|
||||
AbstractBlockPosWrapper createBlockPos();
|
||||
|
||||
AbstractBlockPosWrapper createBlockPos(int x, int y, int z);
|
||||
|
||||
AbstractChunkPosWrapper createChunkPos();
|
||||
|
||||
AbstractChunkPosWrapper createChunkPos(long xAndZPositionCombined);
|
||||
|
||||
AbstractChunkPosWrapper createChunkPos(int x, int z);
|
||||
|
||||
AbstractChunkPosWrapper createChunkPos(AbstractChunkPosWrapper newChunkPos);
|
||||
|
||||
AbstractChunkPosWrapper createChunkPos(AbstractBlockPosWrapper blockPos);
|
||||
|
||||
AbstractWorldGeneratorWrapper createWorldGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension,
|
||||
|
||||
@@ -19,20 +19,15 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.chunk;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.BlockDetail;
|
||||
import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.world.level.BlockAndTintGetter;
|
||||
import net.minecraft.world.level.block.state.BlockState;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-17-2021
|
||||
*/
|
||||
public interface IChunkWrapper
|
||||
public interface IChunkWrapper extends IBindable
|
||||
{
|
||||
default int getHeight() {
|
||||
return getMaxBuildHeight()-getMinBuildHeight();
|
||||
|
||||
+3
-2
@@ -34,6 +34,7 @@ import com.seibel.lod.core.enums.rendering.DebugMode;
|
||||
import com.seibel.lod.core.enums.rendering.FogColorMode;
|
||||
import com.seibel.lod.core.enums.rendering.FogDistance;
|
||||
import com.seibel.lod.core.enums.rendering.FogDrawMode;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.MinDefaultMax;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
@@ -46,9 +47,9 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper;
|
||||
* the options that should be implemented in a configWrapperSingleton.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-14-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface ILodConfigWrapperSingleton
|
||||
public interface ILodConfigWrapperSingleton extends IBindable
|
||||
{
|
||||
IClient client();
|
||||
|
||||
|
||||
+6
-6
@@ -22,6 +22,7 @@ package com.seibel.lod.core.wrapperInterfaces.minecraft;
|
||||
import java.awt.Color;
|
||||
import java.util.HashSet;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.ModAccessorHandler;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
|
||||
import com.seibel.lod.core.objects.math.Mat4f;
|
||||
@@ -38,12 +39,10 @@ import com.seibel.lod.core.wrapperInterfaces.modAccessor.ISodiumAccessor;
|
||||
* rendering in Minecraft.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 12-14-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IMinecraftRenderWrapper
|
||||
public interface IMinecraftRenderWrapper extends IBindable
|
||||
{
|
||||
static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class);
|
||||
|
||||
Vec3f getLookAtVector();
|
||||
|
||||
AbstractBlockPosWrapper getCameraBlockPosition();
|
||||
@@ -92,6 +91,7 @@ public interface IMinecraftRenderWrapper
|
||||
{
|
||||
IMinecraftWrapper mcWrapper = SingletonHandler.get(IMinecraftWrapper.class);
|
||||
IWrapperFactory factory = SingletonHandler.get(IWrapperFactory.class);
|
||||
IVersionConstants versionConstants = SingletonHandler.get(IVersionConstants.class);
|
||||
|
||||
int chunkDist = this.getRenderDistance();
|
||||
|
||||
@@ -106,8 +106,8 @@ public interface IMinecraftRenderWrapper
|
||||
{
|
||||
for(int deltaChunkZ = -chunkDist; deltaChunkZ <= chunkDist; deltaChunkZ++)
|
||||
{
|
||||
if (!VERSION_CONSTANTS.isVanillaRenderedChunkSquare() &&
|
||||
deltaChunkX*deltaChunkX+deltaChunkZ*deltaChunkZ>chunkDist2) {
|
||||
if (!versionConstants.isVanillaRenderedChunkSquare() &&
|
||||
deltaChunkX*deltaChunkX+deltaChunkZ*deltaChunkZ > chunkDist2) {
|
||||
continue;
|
||||
}
|
||||
renderedPos.add(factory.createChunkPos(centerChunkX + deltaChunkX, centerChunkZ + deltaChunkZ));
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@ import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import com.seibel.lod.core.enums.LodDirection;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.misc.ILightMapWrapper;
|
||||
@@ -36,7 +37,7 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
|
||||
* @author James Seibel
|
||||
* @version 12-8-2021
|
||||
*/
|
||||
public interface IMinecraftWrapper
|
||||
public interface IMinecraftWrapper extends IBindable
|
||||
{
|
||||
//================//
|
||||
// helper methods //
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.minecraft;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-20-2021
|
||||
*/
|
||||
public interface IProfilerWrapper
|
||||
public interface IProfilerWrapper extends IBindable
|
||||
{
|
||||
void push(String newSection);
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.misc;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-20-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface ILightMapWrapper
|
||||
public interface ILightMapWrapper extends IBindable
|
||||
{
|
||||
int getLightValue(int skyLight, int blockLight);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
|
||||
|
||||
public interface IModAccessor {
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* @author Leetom
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IModAccessor extends IBindable {
|
||||
String getModName();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
package com.seibel.lod.core.wrapperInterfaces.modAccessor;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* Checks if a mod is loaded
|
||||
*
|
||||
* @author coolGi2007
|
||||
* @version 1-11-2022
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IModChecker {
|
||||
public interface IModChecker extends IBindable {
|
||||
/** Checks if a mod is loaded */
|
||||
boolean isModLoaded(String modid);
|
||||
}
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
||||
|
||||
public interface IOptifineAccessor extends IModAccessor
|
||||
{
|
||||
// Can be null
|
||||
/** Can be null */
|
||||
HashSet<AbstractChunkPosWrapper> getNormalRenderedChunks();
|
||||
}
|
||||
|
||||
+3
-2
@@ -19,6 +19,7 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.world;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
||||
|
||||
|
||||
@@ -26,9 +27,9 @@ import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper;
|
||||
* Contains everything related to biome colors.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-15-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IBiomeColorWrapperSingleton
|
||||
public interface IBiomeColorWrapperSingleton extends IBindable
|
||||
{
|
||||
IBiomeColorWrapperSingleton getInstance();
|
||||
|
||||
|
||||
@@ -19,11 +19,13 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.world;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-15-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IBiomeWrapper
|
||||
public interface IBiomeWrapper extends IBindable
|
||||
{
|
||||
/** Returns a color int for the given biome. */
|
||||
int getColorForBiome(int x, int z);
|
||||
|
||||
+4
-2
@@ -19,11 +19,13 @@
|
||||
|
||||
package com.seibel.lod.core.wrapperInterfaces.world;
|
||||
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
|
||||
/**
|
||||
* @author James Seibel
|
||||
* @version 11-15-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IDimensionTypeWrapper
|
||||
public interface IDimensionTypeWrapper extends IBindable
|
||||
{
|
||||
String getDimensionName();
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ package com.seibel.lod.core.wrapperInterfaces.world;
|
||||
import java.io.File;
|
||||
|
||||
import com.seibel.lod.core.enums.WorldType;
|
||||
import com.seibel.lod.core.handlers.dependencyInjection.IBindable;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
|
||||
import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
|
||||
@@ -29,9 +30,9 @@ import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper;
|
||||
* Can be either a Server world or a Client world.
|
||||
*
|
||||
* @author James Seibel
|
||||
* @version 11-20-2021
|
||||
* @version 3-5-2022
|
||||
*/
|
||||
public interface IWorldWrapper
|
||||
public interface IWorldWrapper extends IBindable
|
||||
{
|
||||
IDimensionTypeWrapper getDimensionType();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user