Shuffling

This commit is contained in:
mcrcortex
2025-03-11 08:09:52 +10:00
parent aae089404d
commit c6fd3b19f9
5 changed files with 68 additions and 38 deletions

View File

@@ -113,7 +113,7 @@ public class VoxelCore {
//this.world.getMapper().forceResaveStates();
this.importer.shutdown();
Logger.info("Shutting down world engine");
try {this.world.shutdown();} catch (Exception e) {Logger.error("Error shutting down world engine", e);}
try {this.world.free();} catch (Exception e) {Logger.error("Error shutting down world engine", e);}
Logger.info("Shutting down service thread pool");
this.serviceThreadPool.shutdown();
Logger.info("Voxel core shut down");

View File

@@ -18,6 +18,10 @@ public abstract class TrackedObject {
this.ref = register(shouldTrack, this);
}
protected TrackedObject(Object forObj, boolean shouldTrack) {
this.ref = register(shouldTrack, forObj);
}
protected void free0() {
if (this.isFreed()) {
throw new IllegalStateException("Object " + this + " was double freed.");
@@ -78,4 +82,20 @@ public abstract class TrackedObject {
}
return new Ref(cleanable, freed);
}
public static final class TrackedObjectObject extends TrackedObject {
private TrackedObjectObject(Object forObj) {
super(forObj, true);
}
@Override
public void free() {
this.free0();
}
}
public static TrackedObject createTrackedObject(Object forObj) {
return new TrackedObjectObject(forObj);
}
}

View File

@@ -2,6 +2,7 @@ package me.cortex.voxy.common.world;
import me.cortex.voxy.common.Logger;
import me.cortex.voxy.common.config.section.SectionStorage;
import me.cortex.voxy.common.util.TrackedObject;
import me.cortex.voxy.common.voxelization.VoxelizedSection;
import me.cortex.voxy.common.world.other.Mapper;
@@ -16,6 +17,7 @@ public class WorldEngine {
public interface ISectionChangeCallback {void accept(WorldSection section, int updateFlags);}
public interface ISectionSaveCallback {void save(WorldEngine engine, WorldSection section);}
private final TrackedObject thisTracker = TrackedObject.createTrackedObject(this);
public final SectionStorage storage;
private final Mapper mapper;
@@ -207,7 +209,8 @@ public class WorldEngine {
debug.add("ACC/SCC: " + this.sectionTracker.getLoadedCacheCount()+"/"+this.sectionTracker.getSecondaryCacheSize());//Active cache count, Secondary cache counts
}
public void shutdown() {
public void free() {
this.thisTracker.free();
this.isLive = false;
try {this.mapper.close();} catch (Exception e) {Logger.error(e);}
try {this.storage.flush();} catch (Exception e) {Logger.error(e);}

View File

@@ -7,8 +7,6 @@ import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
public class VoxyCommon implements ModInitializer {
private static VoxyInstance INSTANCE;
public static final String MOD_VERSION;
public static final boolean IS_DEDICATED_SERVER;
@@ -27,21 +25,24 @@ public class VoxyCommon implements ModInitializer {
}
}
@Override
public void onInitialize() {
//This is hardcoded like this because people do not understand what they are doing
private static final boolean GlobalVerificationDisableOverride = false;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true");
public static boolean isVerificationFlagOn(String name) {
return (!GlobalVerificationDisableOverride) && System.getProperty("voxy."+name, "true").equals("true");
}
public static void breakpoint() {
int breakpoint = 0;
}
//This is hardcoded like this because people do not understand what they are doing
private static final boolean GlobalVerificationDisableOverride = false;//System.getProperty("voxy.verificationDisableOverride", "false").equals("true");
public static boolean isVerificationFlagOn(String name) {
return (!GlobalVerificationDisableOverride) && System.getProperty("voxy."+name, "true").equals("true");
@Override
public void onInitialize() {
}
public interface IInstanceFactory {VoxyInstance create();}
private static VoxyInstance INSTANCE;
private static IInstanceFactory FACTORY;
public static VoxyInstance getInstance() {
return INSTANCE;
}
@@ -57,6 +58,9 @@ public class VoxyCommon implements ModInitializer {
if (INSTANCE != null) {
throw new IllegalStateException("Cannot create multiple instances");
}
INSTANCE = new VoxyInstance(12);
if (FACTORY == null) {
throw new IllegalStateException("Instance factory null");
}
INSTANCE = FACTORY.create();
}
}

View File

@@ -17,10 +17,10 @@ import java.util.Set;
//TODO: add thread access verification (I.E. only accessible on a single thread)
public class VoxyInstance {
private final ServiceThreadPool threadPool;
private final SectionSavingService savingService;
private final VoxelIngestService ingestService;
private final Set<WorldEngine> activeWorlds = new HashSet<>();
protected final ServiceThreadPool threadPool;
protected final SectionSavingService savingService;
protected final VoxelIngestService ingestService;
protected final Set<WorldEngine> activeWorlds = new HashSet<>();
public VoxyInstance(int threadCount) {
this.threadPool = new ServiceThreadPool(threadCount);
@@ -66,7 +66,7 @@ public class VoxyInstance {
}
}
private WorldEngine createWorld(SectionStorage storage) {
protected WorldEngine createWorld(SectionStorage storage) {
var world = new WorldEngine(storage, 1024);
world.setSaveCallback(this.savingService::enqueueSave);
this.activeWorlds.add(world);
@@ -83,6 +83,30 @@ public class VoxyInstance {
// so if make into singleplayer as host, would need to reload the system into that mode
// so that the world renderer uses the WorldEngine of the server
public void stopWorld(WorldEngine world) {
if (!this.activeWorlds.contains(world)) {
if (world.isLive()) {
throw new IllegalStateException("World cannot be live and not in world set");
}
throw new IllegalStateException("Cannot close world which is not part of instance");
}
if (!world.isLive()) {
throw new IllegalStateException("World cannot be in world set and not alive");
}
if (this.importWrapper != null) {
this.importWrapper.stopImporter();
this.importWrapper = null;
}
this.flush();
world.free();
this.activeWorlds.remove(world);
}
private static final ContextSelectionSystem SELECTOR = new ContextSelectionSystem();
public WorldImportWrapper importWrapper;
public WorldEngine getOrMakeWorld(ClientWorld world) {
@@ -95,25 +119,4 @@ public class VoxyInstance {
return vworld;
}
public void stopWorld(WorldEngine world) {
if (!this.activeWorlds.contains(world)) {
if (world.isLive()) {
throw new IllegalStateException("World cannot be live and not in world set");
}
throw new IllegalStateException("Cannot close world which is not part of instance");
}
if (!world.isLive()) {
throw new IllegalStateException("World cannot be in world set and not alive");
}
if (this.importWrapper != null) {
this.importWrapper.stopImporter();
}
this.flush();
world.shutdown();
this.activeWorlds.remove(world);
}
}