Added botched render cache
This commit is contained in:
@@ -60,10 +60,10 @@ public class VoxelCore {
|
|||||||
//Trigger the shared index buffer loading
|
//Trigger the shared index buffer loading
|
||||||
SharedIndexBuffer.INSTANCE.id();
|
SharedIndexBuffer.INSTANCE.id();
|
||||||
this.renderer = new Gl46FarWorldRenderer();
|
this.renderer = new Gl46FarWorldRenderer();
|
||||||
this.world = new WorldEngine(new File("storagefile.db"), 5, 5);//"storagefile.db"//"ethoslab.db"
|
this.world = new WorldEngine(new File("storagefile.db"), 20, 5);//"storagefile.db"//"ethoslab.db"
|
||||||
|
|
||||||
this.renderTracker = new RenderTracker(this.world, this.renderer);
|
this.renderTracker = new RenderTracker(this.world, this.renderer);
|
||||||
this.renderGen = new RenderGenerationService(this.world, this.renderTracker,4);
|
this.renderGen = new RenderGenerationService(this.world,4, this.renderTracker::processBuildResult);
|
||||||
this.world.setRenderTracker(this.renderTracker);
|
this.world.setRenderTracker(this.renderTracker);
|
||||||
this.renderTracker.setRenderGen(this.renderGen);
|
this.renderTracker.setRenderGen(this.renderGen);
|
||||||
|
|
||||||
@@ -179,8 +179,8 @@ public class VoxelCore {
|
|||||||
|
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
try {this.renderGen.shutdown();} catch (Exception e) {System.err.println(e);}
|
try {this.renderGen.shutdown();} catch (Exception e) {System.err.println(e);}
|
||||||
|
try {this.world.shutdown();} catch (Exception e) {System.err.println(e);}
|
||||||
try {this.renderer.shutdown();} catch (Exception e) {System.err.println(e);}
|
try {this.renderer.shutdown();} catch (Exception e) {System.err.println(e);}
|
||||||
try {this.postProcessing.shutdown();} catch (Exception e) {System.err.println(e);}
|
try {this.postProcessing.shutdown();} catch (Exception e) {System.err.println(e);}
|
||||||
try {this.world.shutdown();} catch (Exception e) {System.err.println(e);}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ public class RenderTracker {
|
|||||||
public void setRenderGen(RenderGenerationService renderGen) {
|
public void setRenderGen(RenderGenerationService renderGen) {
|
||||||
this.renderGen = renderGen;
|
this.renderGen = renderGen;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RenderTracker(WorldEngine world, AbstractFarWorldRenderer renderer) {
|
public RenderTracker(WorldEngine world, AbstractFarWorldRenderer renderer) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.renderer = renderer;
|
this.renderer = renderer;
|
||||||
@@ -76,14 +77,15 @@ public class RenderTracker {
|
|||||||
|
|
||||||
//Adds a lvl 0 section into the world renderer
|
//Adds a lvl 0 section into the world renderer
|
||||||
public void addLvl0(int x, int y, int z) {
|
public void addLvl0(int x, int y, int z) {
|
||||||
this.renderGen.enqueueTask(0, x, y, z);
|
|
||||||
this.activeSections.put(WorldEngine.getWorldSectionId(0, x, y, z), O);
|
this.activeSections.put(WorldEngine.getWorldSectionId(0, x, y, z), O);
|
||||||
|
this.renderGen.enqueueTask(0, x, y, z, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Removes a lvl 0 section from the world renderer
|
//Removes a lvl 0 section from the world renderer
|
||||||
public void remLvl0(int x, int y, int z) {
|
public void remLvl0(int x, int y, int z) {
|
||||||
this.activeSections.remove(WorldEngine.getWorldSectionId(0, x, y, z));
|
this.activeSections.remove(WorldEngine.getWorldSectionId(0, x, y, z));
|
||||||
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(0, x, y, z), null, null));
|
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(0, x, y, z), null, null));
|
||||||
|
this.renderGen.removeTask(0, x, y, z);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Increases from lvl-1 to lvl at the coordinates (which are in lvl space)
|
//Increases from lvl-1 to lvl at the coordinates (which are in lvl space)
|
||||||
@@ -102,7 +104,7 @@ public class RenderTracker {
|
|||||||
// concurrent hashmap or something, this is so that e.g. the build data position
|
// concurrent hashmap or something, this is so that e.g. the build data position
|
||||||
// can be updated
|
// can be updated
|
||||||
|
|
||||||
this.renderGen.enqueueTask(lvl, x, y, z);
|
this.renderGen.enqueueTask(lvl, x, y, z, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
|
|
||||||
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)), null, null));
|
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)), null, null));
|
||||||
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)+1), null, null));
|
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1), (y<<1), (z<<1)+1), null, null));
|
||||||
@@ -114,8 +116,14 @@ public class RenderTracker {
|
|||||||
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1), null, null));
|
this.renderer.enqueueResult(new BuiltSectionGeometry(WorldEngine.getWorldSectionId(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1), null, null));
|
||||||
|
|
||||||
|
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1), (y<<1), (z<<1));
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1), (y<<1), (z<<1)+1);
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1), (y<<1)+1, (z<<1));
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1), (y<<1)+1, (z<<1)+1);
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1)+1, (y<<1), (z<<1));
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1)+1, (y<<1), (z<<1)+1);
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1));
|
||||||
|
this.renderGen.removeTask(lvl-1, (x<<1)+1, (y<<1)+1, (z<<1)+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Decreases from lvl to lvl-1 at the coordinates (which are in lvl space)
|
//Decreases from lvl to lvl-1 at the coordinates (which are in lvl space)
|
||||||
@@ -131,15 +139,16 @@ public class RenderTracker {
|
|||||||
this.activeSections.remove(WorldEngine.getWorldSectionId(lvl, x, y, z));
|
this.activeSections.remove(WorldEngine.getWorldSectionId(lvl, x, y, z));
|
||||||
|
|
||||||
this.renderer.enqueueResult(new BuiltSectionGeometry(lvl, x, y, z, null, null));
|
this.renderer.enqueueResult(new BuiltSectionGeometry(lvl, x, y, z, null, null));
|
||||||
|
this.renderGen.removeTask(lvl, x, y, z);
|
||||||
|
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1), (z<<1));
|
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1), (z<<1), this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1), (z<<1)+1);
|
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1), (z<<1)+1, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1)+1, (z<<1));
|
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1)+1, (z<<1), this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1)+1, (z<<1)+1);
|
this.renderGen.enqueueTask(lvl - 1, (x<<1), (y<<1)+1, (z<<1)+1, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1), (z<<1));
|
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1), (z<<1), this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1), (z<<1)+1);
|
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1), (z<<1)+1, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1)+1, (z<<1));
|
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1)+1, (z<<1), this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1)+1, (z<<1)+1);
|
this.renderGen.enqueueTask(lvl - 1, (x<<1)+1, (y<<1)+1, (z<<1)+1, this::shouldStillBuild, this::getBuildFlagsOrAbort);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +196,7 @@ public class RenderTracker {
|
|||||||
buildMask |= 1<<Direction.WEST.getId();
|
buildMask |= 1<<Direction.WEST.getId();
|
||||||
}
|
}
|
||||||
buildMask |= 1<<Direction.UP.getId();
|
buildMask |= 1<<Direction.UP.getId();
|
||||||
//buildMask |= ((1<<6)-1)^(1);
|
buildMask |= ((1<<6)-1)^(1);
|
||||||
}
|
}
|
||||||
return buildMask;
|
return buildMask;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,4 +26,8 @@ public class BuiltSectionGeometry {
|
|||||||
this.translucentGeometryBuffer.free();
|
this.translucentGeometryBuffer.free();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BuiltSectionGeometry clone() {
|
||||||
|
return new BuiltSectionGeometry(this.position, this.geometryBuffer!=null?this.geometryBuffer.copy():null, this.translucentGeometryBuffer!=null?this.translucentGeometryBuffer.copy():null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ import net.minecraft.util.math.Direction;
|
|||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//TODO: make this only emit quads that are facing the rebuild location
|
|
||||||
// HAVE IT AS FLAGS so that a range around the player can be built with all quads etc
|
|
||||||
// this will cut down on the amount of quads by an insane about and help alot overall
|
|
||||||
public class RenderDataFactory {
|
public class RenderDataFactory {
|
||||||
private final Mesher2D mesher = new Mesher2D(5,15);//15
|
private final Mesher2D mesher = new Mesher2D(5,15);//15
|
||||||
private final LongArrayList outData = new LongArrayList(1000);
|
private final LongArrayList outData = new LongArrayList(1000);
|
||||||
|
|||||||
@@ -11,27 +11,27 @@ import net.minecraft.world.chunk.WorldChunk;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
import java.util.concurrent.Semaphore;
|
import java.util.concurrent.Semaphore;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.IntFunction;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.function.ToIntFunction;
|
||||||
|
|
||||||
//TODO: Add a render cache
|
//TODO: Add a render cache
|
||||||
public class RenderGenerationService {
|
public class RenderGenerationService {
|
||||||
//TODO: make it accept either a section or section position and have a concurrent hashset to determine if
|
public interface TaskChecker {boolean check(int lvl, int x, int y, int z);}
|
||||||
// a section is in the build queue
|
private record BuildTask(Supplier<WorldSection> sectionSupplier, ToIntFunction<WorldSection> flagSupplier) {}
|
||||||
private record BuildTask(Supplier<WorldSection> sectionSupplier) {}
|
|
||||||
|
|
||||||
private volatile boolean running = true;
|
private volatile boolean running = true;
|
||||||
private final Thread[] workers;
|
private final Thread[] workers;
|
||||||
|
|
||||||
private final ConcurrentLinkedDeque<BuildTask> taskQueue = new ConcurrentLinkedDeque<>();
|
private final Long2ObjectLinkedOpenHashMap<BuildTask> taskQueue = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
private final Semaphore taskCounter = new Semaphore(0);
|
private final Semaphore taskCounter = new Semaphore(0);
|
||||||
|
|
||||||
private final WorldEngine world;
|
private final WorldEngine world;
|
||||||
private final RenderTracker tracker;
|
private final Consumer<BuiltSectionGeometry> resultConsumer;
|
||||||
|
|
||||||
public RenderGenerationService(WorldEngine world, RenderTracker tracker, int workers) {
|
public RenderGenerationService(WorldEngine world, int workers, Consumer<BuiltSectionGeometry> consumer) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.tracker = tracker;
|
this.resultConsumer = consumer;
|
||||||
|
|
||||||
this.workers = new Thread[workers];
|
this.workers = new Thread[workers];
|
||||||
for (int i = 0; i < workers; i++) {
|
for (int i = 0; i < workers; i++) {
|
||||||
this.workers[i] = new Thread(this::renderWorker);
|
this.workers[i] = new Thread(this::renderWorker);
|
||||||
@@ -41,6 +41,7 @@ public class RenderGenerationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ConcurrentHashMap<Long, BuiltSectionGeometry> renderCache = new ConcurrentHashMap<>(1000,0.75f,10);
|
||||||
|
|
||||||
//TODO: add a generated render data cache
|
//TODO: add a generated render data cache
|
||||||
private void renderWorker() {
|
private void renderWorker() {
|
||||||
@@ -49,15 +50,23 @@ public class RenderGenerationService {
|
|||||||
while (this.running) {
|
while (this.running) {
|
||||||
this.taskCounter.acquireUninterruptibly();
|
this.taskCounter.acquireUninterruptibly();
|
||||||
if (!this.running) break;
|
if (!this.running) break;
|
||||||
var task = this.taskQueue.pop();
|
BuildTask task;
|
||||||
|
synchronized (this.taskQueue) {
|
||||||
|
task = this.taskQueue.removeFirst();
|
||||||
|
}
|
||||||
var section = task.sectionSupplier.get();
|
var section = task.sectionSupplier.get();
|
||||||
if (section == null) {
|
if (section == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
section.assertNotFree();
|
section.assertNotFree();
|
||||||
int buildFlags = this.tracker.getBuildFlagsOrAbort(section);
|
int buildFlags = task.flagSupplier.applyAsInt(section);
|
||||||
if (buildFlags != 0) {
|
if (buildFlags != 0) {
|
||||||
this.tracker.processBuildResult(factory.generateMesh(section, buildFlags));
|
var mesh = factory.generateMesh(section, buildFlags);
|
||||||
|
this.resultConsumer.accept(mesh.clone());
|
||||||
|
var prevCache = this.renderCache.put(mesh.position, mesh);
|
||||||
|
if (prevCache != null) {
|
||||||
|
prevCache.free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
section.release();
|
section.release();
|
||||||
}
|
}
|
||||||
@@ -79,26 +88,39 @@ public class RenderGenerationService {
|
|||||||
// like if its in the render queue and if we should abort building the render data
|
// like if its in the render queue and if we should abort building the render data
|
||||||
//1 proposal fix is a Long2ObjectLinkedOpenHashMap<WorldSection> which means we can abort if needed,
|
//1 proposal fix is a Long2ObjectLinkedOpenHashMap<WorldSection> which means we can abort if needed,
|
||||||
// also gets rid of dependency on a WorldSection (kinda)
|
// also gets rid of dependency on a WorldSection (kinda)
|
||||||
public void enqueueTask(int lvl, int x, int y, int z) {
|
public void enqueueTask(int lvl, int x, int y, int z, ToIntFunction<WorldSection> flagSupplier) {
|
||||||
this.taskQueue.add(new BuildTask(()->{
|
this.enqueueTask(lvl, x, y, z, (l,x1,y1,z1)->true, flagSupplier);
|
||||||
if (this.tracker.shouldStillBuild(lvl, x, y, z)) {
|
}
|
||||||
|
|
||||||
|
public void enqueueTask(int lvl, int x, int y, int z, TaskChecker checker, ToIntFunction<WorldSection> flagSupplier) {
|
||||||
|
long ikey = WorldEngine.getWorldSectionId(lvl, x, y, z);
|
||||||
|
{
|
||||||
|
var cache = this.renderCache.get(ikey);
|
||||||
|
if (cache != null) {
|
||||||
|
this.resultConsumer.accept(cache.clone());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
synchronized (this.taskQueue) {
|
||||||
|
this.taskQueue.computeIfAbsent(ikey, key->{
|
||||||
|
this.taskCounter.release();
|
||||||
|
return new BuildTask(()->{
|
||||||
|
if (checker.check(lvl, x, y, z)) {
|
||||||
return this.world.acquire(lvl, x, y, z);
|
return this.world.acquire(lvl, x, y, z);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}));
|
}, flagSupplier);
|
||||||
this.taskCounter.release();
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enqueueTask(WorldSection section) {
|
public void removeTask(int lvl, int x, int y, int z) {
|
||||||
//TODO: fixme! buildMask could have changed
|
synchronized (this.taskQueue) {
|
||||||
//if (!section.inRenderQueue.getAndSet(true)) {
|
if (this.taskQueue.remove(WorldEngine.getWorldSectionId(lvl, x, y, z)) != null) {
|
||||||
// //TODO: add a boolean for needsRenderUpdate that can be set to false if the section is no longer needed
|
this.taskCounter.acquireUninterruptibly();
|
||||||
// // to be rendered, e.g. LoD level changed so that lod is no longer being rendered
|
}
|
||||||
// section.acquire();
|
}
|
||||||
// this.taskQueue.add(new BuildTask(()->section));
|
|
||||||
// this.taskCounter.release();
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getTaskCount() {
|
public int getTaskCount() {
|
||||||
@@ -129,7 +151,8 @@ public class RenderGenerationService {
|
|||||||
|
|
||||||
//Cleanup any remaining data
|
//Cleanup any remaining data
|
||||||
while (!this.taskQueue.isEmpty()) {
|
while (!this.taskQueue.isEmpty()) {
|
||||||
this.taskQueue.pop();
|
this.taskQueue.removeFirst();
|
||||||
}
|
}
|
||||||
|
this.renderCache.values().forEach(BuiltSectionGeometry::free);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,4 +21,10 @@ public class MemoryBuffer extends TrackedObject {
|
|||||||
super.free0();
|
super.free0();
|
||||||
MemoryUtil.nmemFree(this.address);
|
MemoryUtil.nmemFree(this.address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MemoryBuffer copy() {
|
||||||
|
var copy = new MemoryBuffer(this.size);
|
||||||
|
this.cpyTo(copy.address);
|
||||||
|
return copy;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class SaveLoadSystem {
|
|||||||
raw.limit(raw.position());
|
raw.limit(raw.position());
|
||||||
raw.rewind();
|
raw.rewind();
|
||||||
ByteBuffer compressedData = MemoryUtil.memAlloc((int)ZSTD_COMPRESSBOUND(raw.remaining()));
|
ByteBuffer compressedData = MemoryUtil.memAlloc((int)ZSTD_COMPRESSBOUND(raw.remaining()));
|
||||||
long compressedSize = ZSTD_compress(compressedData, raw, 19);
|
long compressedSize = ZSTD_compress(compressedData, raw, 15);
|
||||||
byte[] out = new byte[(int) compressedSize];
|
byte[] out = new byte[(int) compressedSize];
|
||||||
compressedData.limit((int) compressedSize);
|
compressedData.limit((int) compressedSize);
|
||||||
compressedData.get(out);
|
compressedData.get(out);
|
||||||
|
|||||||
@@ -69,18 +69,28 @@ public class SectionSavingService {
|
|||||||
|
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
boolean anyAlive = false;
|
boolean anyAlive = false;
|
||||||
|
boolean allAlive = true;
|
||||||
for (var worker : this.workers) {
|
for (var worker : this.workers) {
|
||||||
anyAlive |= worker.isAlive();
|
anyAlive |= worker.isAlive();
|
||||||
|
allAlive &= worker.isAlive();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!anyAlive) {
|
if (!anyAlive) {
|
||||||
System.err.println("Section saving workers already dead on shutdown! this is very very bad, check log for errors from this thread");
|
System.err.println("Section saving workers already dead on shutdown! this is very very bad, check log for errors from this thread");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!allAlive) {
|
||||||
|
System.err.println("Some section saving works have died, please check log and report errors.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
//Wait for all the saving to finish
|
//Wait for all the saving to finish
|
||||||
while (this.saveCounter.availablePermits() != 0) {
|
while (this.saveCounter.availablePermits() != 0) {
|
||||||
Thread.onSpinWait();
|
try {Thread.sleep(500);} catch (InterruptedException e) {break;}
|
||||||
|
if (i++%10 == 0) {
|
||||||
|
System.out.println("Section saving shutdown has " + this.saveCounter.availablePermits() + " tasks remaining");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//Shutdown
|
//Shutdown
|
||||||
this.running = false;
|
this.running = false;
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ public class WorldImporter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void importRegionFile(Path file, int x, int z) throws IOException {
|
private void importRegionFile(Path file, int x, int z) throws IOException {
|
||||||
|
//if (true) return;
|
||||||
try (var fileStream = FileChannel.open(file, StandardOpenOption.READ)) {
|
try (var fileStream = FileChannel.open(file, StandardOpenOption.READ)) {
|
||||||
var sectorsSavesBB = MemoryUtil.memAlloc(8192);
|
var sectorsSavesBB = MemoryUtil.memAlloc(8192);
|
||||||
if (fileStream.read(sectorsSavesBB, 0) != 8192) {
|
if (fileStream.read(sectorsSavesBB, 0) != 8192) {
|
||||||
|
|||||||
Reference in New Issue
Block a user