Refactor
This commit is contained in:
@@ -322,7 +322,9 @@ public class ClientApi
|
||||
|
||||
// Ignore local world gen, as it's managed by server ticking
|
||||
if (!(clientWorld instanceof DhClientServerWorld))
|
||||
{
|
||||
SharedApi.worldGenTick(clientWorld::doWorldGen);
|
||||
}
|
||||
}
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
+3
@@ -11,11 +11,13 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface IWorldGenerationQueue extends Closeable
|
||||
{
|
||||
/** the largest numerical detail level */
|
||||
byte largestDataDetail();
|
||||
|
||||
CompletableFuture<WorldGenResult> submitGenTask(DhLodPos pos, byte requiredDataDetail, IWorldGenTaskTracker tracker);
|
||||
void cancelGenTasks(Iterable<DhSectionPos> positions);
|
||||
|
||||
/** @param targetPos the position that world generation should be centered around, generally this will be the player's position. */
|
||||
void runCurrentGenTasksUntilBusy(DhBlockPos2D targetPos);
|
||||
|
||||
int getWaitingTaskCount();
|
||||
@@ -23,4 +25,5 @@ public interface IWorldGenerationQueue extends Closeable
|
||||
|
||||
CompletableFuture<Void> startClosing(boolean cancelCurrentGeneration, boolean alsoInterruptRunning);
|
||||
void close();
|
||||
|
||||
}
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ public class WorldGenerationQueue implements IWorldGenerationQueue, IDebugRender
|
||||
@Override
|
||||
public void cancelGenTasks(Iterable<DhSectionPos> positions)
|
||||
{
|
||||
// TODO Should anything be here?
|
||||
// TODO Should we cancel generation of chunks that were loaded by the player?
|
||||
}
|
||||
|
||||
//===============//
|
||||
|
||||
@@ -42,7 +42,7 @@ public class DhClientServerLevel extends DhLevel implements IDhClientLevel, IDhS
|
||||
LOGGER.warn("unable to create data folder.");
|
||||
}
|
||||
this.serverLevelWrapper = serverLevelWrapper;
|
||||
this.serverside = new ServerLevelModule(this, serverLevelWrapper, saveStructure);
|
||||
this.serverside = new ServerLevelModule(this, saveStructure);
|
||||
this.clientside = new ClientLevelModule(this);
|
||||
LOGGER.info("Started " + DhClientServerLevel.class.getSimpleName() + " for " + serverLevelWrapper + " with saves at " + saveStructure);
|
||||
}
|
||||
@@ -129,7 +129,7 @@ public class DhClientServerLevel extends DhLevel implements IDhClientLevel, IDhS
|
||||
}
|
||||
|
||||
@Override
|
||||
public IClientLevelWrapper getClientLevelWrapper() { return serverside.levelWrapper.tryGetClientLevelWrapper(); }
|
||||
public IClientLevelWrapper getClientLevelWrapper() { return this.serverLevelWrapper.tryGetClientLevelWrapper(); }
|
||||
|
||||
@Override
|
||||
public void clearRenderCache()
|
||||
|
||||
@@ -27,7 +27,7 @@ public class DhServerLevel extends DhLevel implements IDhServerLevel
|
||||
LOGGER.warn("unable to create data folder.");
|
||||
}
|
||||
this.serverLevelWrapper = serverLevelWrapper;
|
||||
serverside = new ServerLevelModule(this, serverLevelWrapper, saveStructure);
|
||||
this.serverside = new ServerLevelModule(this, saveStructure);
|
||||
LOGGER.info("Started DHLevel for {} with saves at {}", serverLevelWrapper, saveStructure);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,7 @@ public class ServerLevelModule
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
|
||||
public final IServerLevelWrapper levelWrapper;
|
||||
public final IDhServerLevel parent;
|
||||
public final IDhServerLevel parentServerLevel;
|
||||
public final AbstractSaveStructure saveStructure;
|
||||
public final GeneratedFullDataFileHandler dataFileHandler;
|
||||
public final AppliedConfigState<Boolean> worldGeneratorEnabledConfig;
|
||||
@@ -26,24 +25,22 @@ public class ServerLevelModule
|
||||
|
||||
|
||||
|
||||
public ServerLevelModule(IDhServerLevel parent, IServerLevelWrapper levelWrapper, AbstractSaveStructure saveStructure)
|
||||
public ServerLevelModule(IDhServerLevel parentServerLevel, AbstractSaveStructure saveStructure)
|
||||
{
|
||||
this.parent = parent;
|
||||
this.levelWrapper = levelWrapper;
|
||||
this.parentServerLevel = parentServerLevel;
|
||||
this.saveStructure = saveStructure;
|
||||
this.dataFileHandler = new GeneratedFullDataFileHandler(parent, saveStructure);
|
||||
this.dataFileHandler = new GeneratedFullDataFileHandler(parentServerLevel, saveStructure);
|
||||
this.worldGeneratorEnabledConfig = new AppliedConfigState<>(Config.Client.Advanced.WorldGenerator.enableDistantGeneration);
|
||||
this.worldGenModule = new WorldGenModule(this.dataFileHandler, this.parent);
|
||||
this.worldGenModule = new WorldGenModule(this.dataFileHandler, this.parentServerLevel);
|
||||
}
|
||||
|
||||
//===============//
|
||||
// data handling //
|
||||
//===============//
|
||||
|
||||
|
||||
public void close()
|
||||
{
|
||||
// shutdown the world-gen
|
||||
this.worldGenModule.close();
|
||||
dataFileHandler.close();
|
||||
this.dataFileHandler.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +49,7 @@ public class ServerLevelModule
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
public static class WorldGenState extends WorldGenModule.WorldGenState
|
||||
public static class WorldGenState extends WorldGenModule.AbstractWorldGenState
|
||||
{
|
||||
WorldGenState(IDhServerLevel level)
|
||||
{
|
||||
|
||||
@@ -18,10 +18,127 @@ public class WorldGenModule implements Closeable
|
||||
private final GeneratedFullDataFileHandler dataFileHandler;
|
||||
private final GeneratedFullDataFileHandler.IOnWorldGenCompleteListener onWorldGenCompleteListener;
|
||||
|
||||
private final AtomicReference<WorldGenState> worldGenStateRef = new AtomicReference<>();
|
||||
private final AtomicReference<AbstractWorldGenState> worldGenStateRef = new AtomicReference<>();
|
||||
private final F3Screen.DynamicMessage worldGenF3Message;
|
||||
|
||||
public static abstract class WorldGenState
|
||||
|
||||
|
||||
public WorldGenModule(GeneratedFullDataFileHandler dataFileHandler, GeneratedFullDataFileHandler.IOnWorldGenCompleteListener onWorldGenCompleteListener)
|
||||
{
|
||||
this.dataFileHandler = dataFileHandler;
|
||||
this.onWorldGenCompleteListener = onWorldGenCompleteListener;
|
||||
this.worldGenF3Message = new F3Screen.DynamicMessage(() ->
|
||||
{
|
||||
AbstractWorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
int waitingCount = worldGenState.worldGenerationQueue.getWaitingTaskCount();
|
||||
int inProgressCount = worldGenState.worldGenerationQueue.getInProgressTaskCount();
|
||||
|
||||
return "World Gen Tasks: "+waitingCount+", (in progress: "+inProgressCount+")";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "World Gen Disabled";
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===================//
|
||||
// world gen control //
|
||||
//===================//
|
||||
|
||||
public void startWorldGen(GeneratedFullDataFileHandler dataFileHandler, AbstractWorldGenState newWgs)
|
||||
{
|
||||
// create the new world generator
|
||||
if (!this.worldGenStateRef.compareAndSet(null, newWgs))
|
||||
{
|
||||
LOGGER.warn("Failed to start world gen due to concurrency");
|
||||
newWgs.closeAsync(false);
|
||||
}
|
||||
dataFileHandler.addWorldGenCompleteListener(this.onWorldGenCompleteListener);
|
||||
dataFileHandler.setGenerationQueue(newWgs.worldGenerationQueue);
|
||||
}
|
||||
|
||||
public void stopWorldGen(GeneratedFullDataFileHandler dataFileHandler)
|
||||
{
|
||||
AbstractWorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
LOGGER.warn("Attempted to stop world gen when it was not running");
|
||||
return;
|
||||
}
|
||||
|
||||
// shut down the world generator
|
||||
while (!this.worldGenStateRef.compareAndSet(worldGenState, null))
|
||||
{
|
||||
worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
dataFileHandler.clearGenerationQueue();
|
||||
worldGenState.closeAsync(true).join(); //TODO: Make it async.
|
||||
dataFileHandler.removeWorldGenCompleteListener(this.onWorldGenCompleteListener);
|
||||
}
|
||||
|
||||
/** @param targetPosForGeneration the position that world generation should be centered around */
|
||||
public void worldGenTick(DhBlockPos2D targetPosForGeneration)
|
||||
{
|
||||
AbstractWorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
// queue new world generation requests
|
||||
worldGenState.tick(targetPosForGeneration);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
// shutdown the world-gen
|
||||
AbstractWorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
while (!this.worldGenStateRef.compareAndSet(worldGenState, null))
|
||||
{
|
||||
worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (worldGenState != null)
|
||||
{
|
||||
worldGenState.closeAsync(true).join(); //TODO: Make it async.
|
||||
}
|
||||
}
|
||||
|
||||
this.dataFileHandler.close();
|
||||
this.worldGenF3Message.close();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//=========//
|
||||
// getters //
|
||||
//=========//
|
||||
|
||||
public boolean isWorldGenRunning() { return this.worldGenStateRef.get() != null; }
|
||||
|
||||
|
||||
|
||||
//================//
|
||||
// helper classes //
|
||||
//================//
|
||||
|
||||
/** Handles the {@link IWorldGenerationQueue} and any other necessary world gen information. */
|
||||
public static abstract class AbstractWorldGenState
|
||||
{
|
||||
public IWorldGenerationQueue worldGenerationQueue;
|
||||
|
||||
@@ -41,105 +158,8 @@ public class WorldGenModule implements Closeable
|
||||
});
|
||||
}
|
||||
|
||||
public void tick(DhBlockPos2D targetPosForGeneration)
|
||||
{
|
||||
worldGenerationQueue.runCurrentGenTasksUntilBusy(targetPosForGeneration);
|
||||
}
|
||||
/** @param targetPosForGeneration the position that world generation should be centered around */
|
||||
public void tick(DhBlockPos2D targetPosForGeneration) { this.worldGenerationQueue.runCurrentGenTasksUntilBusy(targetPosForGeneration); }
|
||||
}
|
||||
|
||||
public WorldGenModule(GeneratedFullDataFileHandler dataFileHandler, GeneratedFullDataFileHandler.IOnWorldGenCompleteListener onWorldGenCompleteListener)
|
||||
{
|
||||
this.dataFileHandler = dataFileHandler;
|
||||
this.onWorldGenCompleteListener = onWorldGenCompleteListener;
|
||||
this.worldGenF3Message = new F3Screen.DynamicMessage(() ->
|
||||
{
|
||||
WorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
int waiting = worldGenState.worldGenerationQueue.getWaitingTaskCount();
|
||||
int inProgress = worldGenState.worldGenerationQueue.getInProgressTaskCount();
|
||||
|
||||
return "World Gen Tasks: "+waiting+", (in progress: "+inProgress+")";
|
||||
}
|
||||
else
|
||||
{
|
||||
return "World Gen Disabled";
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public void startWorldGen(GeneratedFullDataFileHandler dataFileHandler, WorldGenState newWgs)
|
||||
{
|
||||
// create the new world generator
|
||||
if (!this.worldGenStateRef.compareAndSet(null, newWgs))
|
||||
{
|
||||
LOGGER.warn("Failed to start world gen due to concurrency");
|
||||
newWgs.closeAsync(false);
|
||||
}
|
||||
dataFileHandler.addWorldGenCompleteListener(onWorldGenCompleteListener);
|
||||
dataFileHandler.setGenerationQueue(newWgs.worldGenerationQueue);
|
||||
}
|
||||
|
||||
public void stopWorldGen(GeneratedFullDataFileHandler dataFileHandler)
|
||||
{
|
||||
WorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
LOGGER.warn("Attempted to stop world gen when it was not running");
|
||||
return;
|
||||
}
|
||||
|
||||
// shut down the world generator
|
||||
while (!this.worldGenStateRef.compareAndSet(worldGenState, null))
|
||||
{
|
||||
worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
dataFileHandler.clearGenerationQueue();
|
||||
worldGenState.closeAsync(true).join(); //TODO: Make it async.
|
||||
dataFileHandler.removeWorldGenCompleteListener(onWorldGenCompleteListener);
|
||||
}
|
||||
|
||||
public boolean isWorldGenRunning()
|
||||
{
|
||||
return this.worldGenStateRef.get() != null;
|
||||
}
|
||||
|
||||
public void worldGenTick(DhBlockPos2D targetPosForGeneration)
|
||||
{
|
||||
WorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
// queue new world generation requests
|
||||
worldGenState.tick(targetPosForGeneration);
|
||||
}
|
||||
}
|
||||
|
||||
public void close()
|
||||
{
|
||||
// shutdown the world-gen
|
||||
WorldGenState worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState != null)
|
||||
{
|
||||
while (!this.worldGenStateRef.compareAndSet(worldGenState, null))
|
||||
{
|
||||
worldGenState = this.worldGenStateRef.get();
|
||||
if (worldGenState == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (worldGenState != null)
|
||||
{
|
||||
worldGenState.closeAsync(true).join(); //TODO: Make it async.
|
||||
}
|
||||
}
|
||||
dataFileHandler.close();
|
||||
this.worldGenF3Message.close();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user