diff --git a/src/main/java/com/seibel/lod/core/objects/a7/DHLevel.java b/src/main/java/com/seibel/lod/core/objects/a7/DHLevel.java index 06863c418..13b075c8d 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/DHLevel.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/DHLevel.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.objects.a7; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.objects.a7.data.DataHandler; +import com.seibel.lod.core.objects.a7.data.DataFileHandler; import com.seibel.lod.core.objects.a7.pos.DhBlockPos2D; import com.seibel.lod.core.objects.a7.render.RenderBufferHandler; import com.seibel.lod.core.render.LodRenderProgram; @@ -18,7 +18,7 @@ public class DHLevel extends LodQuadTree { private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); public final File saveFolder; // Could be null, for no saving - public final DataHandler dataHandler; // Could be null, for no saving + public final DataFileHandler dataFileHandler; // Could be null, for no saving public final RenderBufferHandler renderBufferHandler; public final ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHLevelTickerThread", 2); private final AtomicBoolean isRunning = new AtomicBoolean(false); @@ -30,9 +30,9 @@ public class DHLevel extends LodQuadTree { MC.getPlayerBlockPos().z); this.saveFolder = saveFolder; if (saveFolder != null) { - dataHandler = new DataHandler(saveFolder); + dataFileHandler = new DataFileHandler(saveFolder); } else { - dataHandler = null; + dataFileHandler = null; } renderBufferHandler = new RenderBufferHandler(this); this.level = level; @@ -61,7 +61,7 @@ public class DHLevel extends LodQuadTree { @Override public RenderDataSource getRenderDataSource() { - return dataHandler; + return dataFileHandler; } public void render(LodRenderProgram renderContext) { diff --git a/src/main/java/com/seibel/lod/core/objects/a7/data/DataFileHandler.java b/src/main/java/com/seibel/lod/core/objects/a7/data/DataFileHandler.java new file mode 100644 index 000000000..e54756299 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/objects/a7/data/DataFileHandler.java @@ -0,0 +1,56 @@ +package com.seibel.lod.core.objects.a7.data; + +import com.seibel.lod.core.objects.a7.RenderDataSource; +import com.seibel.lod.core.objects.a7.pos.DhSectionPos; +import com.seibel.lod.core.objects.a7.render.EmptyRenderContainer; +import com.seibel.lod.core.objects.a7.render.RenderContainer; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.HashMap; + +public class DataFileHandler implements RenderDataSource { + public final File folder; + private final HashMap dataSourceCache; + + public DataFileHandler(File folderPath) { + this.folder = folderPath; + dataSourceCache = new HashMap<>(); + } + + @Override + public RenderContainer createRenderData(DhSectionPos pos) { + LodDataSource dataSource = getDataSource(pos); + RenderContainer renderContainer = RenderContainer.tryConstruct(dataSource, pos); + if (renderContainer == null) renderContainer = EmptyRenderContainer.INSTANCE; + return renderContainer; + } + + private LodDataSource getDataSource(DhSectionPos pos) { + return dataSourceCache.computeIfAbsent(pos, this::loadOrCreateDataSource); + } + + private LodDataSource loadOrCreateDataSource(DhSectionPos pos) { + File dataFile = getDataFile(pos); + if (dataFile.exists()) { + String format = getFormat(dataFile); + try { + LodDataSource data = LodDataSource.loadData(format, new FileInputStream(dataFile)); + return data; + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } + } + return new CompleteDataContainer(); + } + + private String getFormat(File targetFile) { + return null; //TODO + } + + private File getDataFile(DhSectionPos pos) { + return null; //TODO + } + +} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/data/DataHandler.java b/src/main/java/com/seibel/lod/core/objects/a7/data/DataHandler.java deleted file mode 100644 index 7030c358f..000000000 --- a/src/main/java/com/seibel/lod/core/objects/a7/data/DataHandler.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.seibel.lod.core.objects.a7.data; - -import com.seibel.lod.core.objects.a7.RenderDataSource; -import com.seibel.lod.core.objects.a7.pos.DhSectionPos; -import com.seibel.lod.core.objects.a7.render.EmptyRenderContainer; -import com.seibel.lod.core.objects.a7.render.RenderContainer; - -import java.io.File; - -public class DataHandler implements RenderDataSource { - public final File folder; - - public DataHandler(File folderPath) { - this.folder = folderPath; - } - - @Override - public RenderContainer createRenderData(DhSectionPos pos) { - //TODO - return EmptyRenderContainer.INSTANCE; - } -} diff --git a/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataSource.java b/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataSource.java index 89ae563f0..32c9ab09f 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataSource.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/data/LodDataSource.java @@ -1,15 +1,16 @@ package com.seibel.lod.core.objects.a7.data; +import java.io.InputStream; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.function.Function; public abstract class LodDataSource { private static final String REGISTER_STRING_FILTER_REGEX = "^[a-zA-Z0-9_]*$"; - public static final HashMap> - dataSourceLoaderRegistry = new HashMap>(); + public static final HashMap> + dataSourceLoaderRegistry = new HashMap>(); - public static void registerDataSourceLoader(String name, int version, Function loader) { + public static void registerDataSourceLoader(String name, int version, Function loader) { if (name == null || loader == null || name.isEmpty()) { throw new IllegalArgumentException("Name and loader must be non-null, and not empty"); } @@ -19,14 +20,14 @@ public abstract class LodDataSource { if (dataSourceLoaderRegistry.containsKey(name)) { throw new IllegalArgumentException("Data source loader already registered for " + name); } - dataSourceLoaderRegistry.put(name, loader); + dataSourceLoaderRegistry.put(name+"$"+version, loader); } - public static LodDataSource loadData(String dataSourceTypeName, ByteBuffer data) { + public static LodDataSource loadData(String dataSourceTypeNameVersion, InputStream data) { - Function loader = dataSourceLoaderRegistry.get(dataSourceTypeName); + Function loader = dataSourceLoaderRegistry.get(dataSourceTypeNameVersion); if (loader == null) { - throw new IllegalArgumentException("No loader for data source type " + dataSourceTypeName); + throw new IllegalArgumentException("No loader for data source type " + dataSourceTypeNameVersion); } return loader.apply(data); } diff --git a/src/main/java/com/seibel/lod/core/objects/a7/render/ColumnRenderContainer.java b/src/main/java/com/seibel/lod/core/objects/a7/render/ColumnRenderContainer.java index bd7a44ce6..14f484961 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/render/ColumnRenderContainer.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/render/ColumnRenderContainer.java @@ -1,5 +1,8 @@ package com.seibel.lod.core.objects.a7.render; +import com.seibel.lod.core.objects.a7.LodSection; +import com.seibel.lod.core.objects.a7.RenderDataContainer; +import com.seibel.lod.core.objects.a7.data.LodDataSource; import com.seibel.lod.core.objects.a7.pos.DhSectionPos; import com.seibel.lod.core.objects.opengl.RenderBuffer; import com.seibel.lod.core.objects.opengl.RenderRegion; @@ -10,32 +13,29 @@ import java.util.concurrent.atomic.AtomicReference; public class ColumnRenderContainer extends RenderContainer { public static final int columnWidth = DhSectionPos.DATA_WIDTH_PER_SECTION; public static final int columnCount = LodUtil.pow2(DhSectionPos.DATA_WIDTH_PER_SECTION); - private long[] columnData; + + public RenderDataContainer dataContainer = null; + public final int maxColumnHeight; public final int minWorldHeight; - public RenderRegion renderRegion = null; + public static RenderContainer testAndConstruct(LodDataSource dataSource, DhSectionPos sectionPos) { + ColumnRenderContainer container = new ColumnRenderContainer(10, -100); //FIXME: Use actual config value + container.startFillData(dataSource); + return container; + } + static { + RenderContainer.registorLoader(ColumnRenderContainer::testAndConstruct, 0); + } public ColumnRenderContainer(int maxColumnHeight, int minWorldHeight) { this.maxColumnHeight = maxColumnHeight; - columnData = new long[columnCount * maxColumnHeight]; + //columnData = new long[columnCount * maxColumnHeight]; this.minWorldHeight = minWorldHeight; - renderRegion = new RenderRegion(); } - @Override - public void notifyRenderable() { - - } - - @Override - public void notifyUnrenderable() { - - } - - @Override - public boolean isRenderable() { - return false; + private void startFillData(LodDataSource dataSource) { + //TODO } @Override diff --git a/src/main/java/com/seibel/lod/core/objects/a7/render/EmptyRenderContainer.java b/src/main/java/com/seibel/lod/core/objects/a7/render/EmptyRenderContainer.java index 02278d81b..cf63d8d5c 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/render/EmptyRenderContainer.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/render/EmptyRenderContainer.java @@ -7,21 +7,6 @@ import java.util.concurrent.atomic.AtomicReference; public class EmptyRenderContainer extends RenderContainer { public static final EmptyRenderContainer INSTANCE = new EmptyRenderContainer(); - @Override - public void notifyRenderable() { - - } - - @Override - public void notifyUnrenderable() { - - } - - @Override - public boolean isRenderable() { - return false; - } - @Override public void notifyLoad() { diff --git a/src/main/java/com/seibel/lod/core/objects/a7/render/RenderContainer.java b/src/main/java/com/seibel/lod/core/objects/a7/render/RenderContainer.java index 0257ded54..9062b75ce 100644 --- a/src/main/java/com/seibel/lod/core/objects/a7/render/RenderContainer.java +++ b/src/main/java/com/seibel/lod/core/objects/a7/render/RenderContainer.java @@ -1,11 +1,36 @@ package com.seibel.lod.core.objects.a7.render; +import com.seibel.lod.core.objects.a7.LodSection; +import com.seibel.lod.core.objects.a7.data.LodDataSource; +import com.seibel.lod.core.objects.a7.pos.DhSectionPos; import com.seibel.lod.core.objects.opengl.RenderBuffer; -import com.seibel.lod.core.objects.opengl.RenderRegion; - +import java.util.SortedMap; +import java.util.TreeMap; import java.util.concurrent.atomic.AtomicReference; public abstract class RenderContainer { + interface RenderContainerConstructor { + // Can return null as meaning the requirement is not met + RenderContainer testAndConstruct(LodDataSource dataSource, DhSectionPos sectionPos); + } + public static final SortedMap + renderContainerLoaderRegistry = new TreeMap(); + public static void registorLoader(RenderContainerConstructor func, int priority) { + if (func == null) { + throw new IllegalArgumentException("loader must be non-null"); + } + renderContainerLoaderRegistry.put(priority, func); + } + + public static RenderContainer tryConstruct(LodDataSource dataSource, DhSectionPos pos) { + for (RenderContainerConstructor func : renderContainerLoaderRegistry.values()) { + RenderContainer container = func.testAndConstruct(dataSource, pos); + if (container != null) { + return container; + } + } + return null; + } private boolean isLoaded = false; public final void load() {