diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java index e30072e8f..aa3c4e17b 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java @@ -22,12 +22,8 @@ public class ColumnRenderLoader extends RenderSourceLoader { @Override public LodRenderSource loadRender(RenderMetaFile dataFile, InputStream data, ILevel level) throws IOException { - try ( - //TODO: Add decompressor here - DataInputStream dis = new DataInputStream(data); - ) { - return new ColumnRenderSource(dataFile.pos, dis, dataFile.metaData.loaderVersion, level); - } + DataInputStream dis = new DataInputStream(data); // DO NOT CLOSE + return new ColumnRenderSource(dataFile.pos, dis, dataFile.metaData.loaderVersion, level); } @Override diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java index 907554844..9a19dffe2 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java @@ -369,9 +369,8 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype { @Override public void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException { - try (DataOutputStream dos = new DataOutputStream(dataStream)) { - writeData(dos); - } + DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE + writeData(dos); } @Override diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataLoader.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataLoader.java index 3da73017d..e45002822 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataLoader.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataLoader.java @@ -16,11 +16,7 @@ public class FullDataLoader extends DataSourceLoader { @Override public LodDataSource loadData(DataMetaFile dataFile, InputStream data, ILevel level) throws IOException { - try ( - //TODO: Add decompressor here - DataInputStream dis = new DataInputStream(data); - ) { - return FullDataSource.loadData(dataFile, dis, level); - } + //TODO: Add decompressor here + return FullDataSource.loadData(dataFile, data, level); } } diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java index 819c7f069..231a0a4d7 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDataSource.java @@ -10,6 +10,7 @@ import com.seibel.lod.core.a7.save.io.file.DataMetaFile; import com.seibel.lod.core.a7.datatype.LodDataSource; import com.seibel.lod.core.a7.util.IdMappingUtil; import com.seibel.lod.core.a7.pos.DhSectionPos; +import com.seibel.lod.core.a7.util.UnclosableInputStream; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.util.LodUtil; @@ -102,7 +103,8 @@ public class FullDataSource extends FullArrayView implements LodDataSource { // @Override public void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException { - try (DataOutputStream dos = new DataOutputStream(dataStream)) { + DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE + { dos.writeInt(getDataDetail()); dos.writeInt(size); dos.writeInt(level.getMinY()); @@ -138,7 +140,8 @@ public class FullDataSource extends FullArrayView implements LodDataSource { // public static FullDataSource loadData(DataMetaFile dataFile, InputStream dataStream, ILevel level) throws IOException { - try (DataInputStream dos = new DataInputStream(dataStream)) { + DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE + { int dataDetail = dos.readInt(); if(dataDetail != dataFile.metaData.dataLevel) throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel)); @@ -175,7 +178,7 @@ public class FullDataSource extends FullArrayView implements LodDataSource { // // Id mapping end = dos.readInt(); if (end != 0xFFFFFFFF) throw new IOException("invalid data content end guard"); - IdBiomeBlockStateMap mapping = IdBiomeBlockStateMap.deserialize(dos); + IdBiomeBlockStateMap mapping = IdBiomeBlockStateMap.deserialize(new UnclosableInputStream(dos)); end = dos.readInt(); if (end != 0xFFFFFFFF) throw new IOException("invalid id mapping end guard"); return new FullDataSource(dataFile.pos, mapping, data); diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java index a8d00ec5a..2ea0ba4dd 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/IdBiomeBlockStateMap.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.a7.datatype.full; +import com.seibel.lod.core.a7.util.UnclosableInputStream; import com.seibel.lod.core.handlers.dependencyInjection.SingletonInjector; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; @@ -77,28 +78,21 @@ public class IdBiomeBlockStateMap { return mapper; } - void serialize(OutputStream os) { - try (DataOutputStream dos = new DataOutputStream(os)) { - dos.writeInt(entries.size()); - for (Entry e : entries) { - dos.writeUTF(e.serialize()); - } - } catch (IOException e) { - e.printStackTrace(); + void serialize(OutputStream os) throws IOException { + DataOutputStream dos = new DataOutputStream(os); // DO NOT CLOSE! + dos.writeInt(entries.size()); + for (Entry e : entries) { + dos.writeUTF(e.serialize()); } } - static IdBiomeBlockStateMap deserialize(InputStream is) { - try (DataInputStream dis = new DataInputStream(is)) { - int size = dis.readInt(); - IdBiomeBlockStateMap map = new IdBiomeBlockStateMap(); - for (int i = 0; i < size; i++) { - map.entries.add(Entry.deserialize(dis.readUTF())); - } - return map; - } catch (IOException e) { - e.printStackTrace(); - return null; + static IdBiomeBlockStateMap deserialize(InputStream is) throws IOException { + DataInputStream dis = new DataInputStream(is); // DO NOT CLOSE! + int size = dis.readInt(); + IdBiomeBlockStateMap map = new IdBiomeBlockStateMap(); + for (int i = 0; i < size; i++) { + map.entries.add(Entry.deserialize(dis.readUTF())); } + return map; } @Override diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataLoader.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataLoader.java index 8bc2cc844..eaed74dcf 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataLoader.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataLoader.java @@ -16,11 +16,6 @@ public class SparseDataLoader extends DataSourceLoader { @Override public LodDataSource loadData(DataMetaFile dataFile, InputStream data, ILevel level) throws IOException { - try ( - //TODO: Add decompressor here - DataInputStream dis = new DataInputStream(data); - ) { - return SparseDataSource.loadData(dataFile, dis, level); - } + return SparseDataSource.loadData(dataFile, data, level); } } diff --git a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataSource.java b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataSource.java index 61d36736b..aaae0b1a6 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/a7/datatype/full/SparseDataSource.java @@ -7,6 +7,7 @@ import com.seibel.lod.core.a7.level.ILevel; import com.seibel.lod.core.a7.pos.DhLodPos; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.save.io.file.DataMetaFile; +import com.seibel.lod.core.a7.util.UnclosableInputStream; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.util.LodUtil; import org.apache.logging.log4j.Logger; @@ -205,7 +206,8 @@ public class SparseDataSource implements LodDataSource { public static SparseDataSource loadData(DataMetaFile dataFile, InputStream dataStream, ILevel level) throws IOException { LodUtil.assertTrue(dataFile.pos.sectionDetail > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(dataFile.pos.sectionDetail <= MAX_SECTION_DETAIL); - try (DataInputStream dos = new DataInputStream(dataStream)) { + DataInputStream dos = new DataInputStream(dataStream); // DO NOT CLOSE! + { int dataDetail = dos.readShort(); if(dataDetail != dataFile.metaData.dataLevel) throw new IOException(LodUtil.formatLog("Data level mismatch: {} != {}", dataDetail, dataFile.metaData.dataLevel)); diff --git a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataFileHandler.java b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataFileHandler.java index 025ef7cef..feebfbdfe 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataFileHandler.java @@ -301,10 +301,12 @@ public class DataFileHandler implements IDataSourceProvider { return source; } @Override - public LodDataSource onDataFileRefresh(LodDataSource source, Consumer updater) { - updater.accept(source); - if (source instanceof SparseDataSource) return ((SparseDataSource) source).trySelfPromote(); - return source; + public CompletableFuture onDataFileRefresh(LodDataSource source, Consumer updater) { + return CompletableFuture.supplyAsync(() -> { + updater.accept(source); + if (source instanceof SparseDataSource) return ((SparseDataSource) source).trySelfPromote(); + return source; + }, fileReaderThread); } @Override diff --git a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java index c58174286..7cb7267ab 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java +++ b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java @@ -230,16 +230,20 @@ public class DataMetaFile extends MetaFile // For now, I'll go for the latter option and just hope nothing goes wrong... if (inCacheWriteAccessAsserter.getAndSet(true) == false) { try { - inner = handler.onDataFileRefresh((LodDataSource) inner, this::applyWriteQueue); + return handler.onDataFileRefresh((LodDataSource) inner, this::applyWriteQueue); } catch (Exception e) { LOGGER.error("Error while applying changes to LodDataSource at {}: ", pos, e); } finally { inCacheWriteAccessAsserter.set(false); } + } else { + // or, return the cached data. FIXME: See above. + return CompletableFuture.completedFuture((LodDataSource) inner); } + } else { + // or, return the cached data. + return CompletableFuture.completedFuture((LodDataSource) inner); } - // Finally, return the cached data. - return CompletableFuture.completedFuture((LodDataSource)inner); } } diff --git a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java index bc009acaf..4f5963dea 100644 --- a/core/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java +++ b/core/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java @@ -11,6 +11,7 @@ import javax.annotation.Nullable; import java.io.File; import java.nio.file.Path; import java.util.Collection; +import java.util.Collections; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -26,7 +27,7 @@ public interface IDataSourceProvider extends AutoCloseable { CompletableFuture onCreateDataFile(DataMetaFile file); LodDataSource onDataFileLoaded(LodDataSource source, Consumer updater); - LodDataSource onDataFileRefresh(LodDataSource source, Consumer updater); + CompletableFuture onDataFileRefresh(LodDataSource source, Consumer updater); File computeDataFilePath(DhSectionPos pos); Executor getIOExecutor();