Fix the QuadTree not updating when new LODs are generated

This commit is contained in:
James Seibel
2023-03-11 12:02:22 -06:00
parent 45cc0f38be
commit 4b5bfe6799
3 changed files with 76 additions and 13 deletions
@@ -27,12 +27,18 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
private final AtomicReference<WorldGenerationQueue> worldGenQueueRef = new AtomicReference<>(null);
private final ArrayList<IOnWorldGenCompleteListener> onWorldGenTaskCompleteListeners = new ArrayList<>();
public GeneratedFullDataFileHandler(IDhServerLevel level, File saveRootDir) { super(level, saveRootDir); }
//==================//
// generation queue //
//==================//
/** Assumes there isn't a pre-existing queue. */
public void setGenerationQueue(WorldGenerationQueue newWorldGenQueue)
{
@@ -44,6 +50,26 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
//=================//
// event listeners //
//=================//
public void addWorldGenCompleteListener(IOnWorldGenCompleteListener listener)
{
this.onWorldGenTaskCompleteListeners.add(listener);
}
public void removeWorldGenCompleteListener(IOnWorldGenCompleteListener listener)
{
this.onWorldGenTaskCompleteListeners.remove(listener);
}
//========//
// events //
//========//
@Override
public CompletableFuture<IFullDataSource> onCreateDataFile(FullDataMetaFile file)
{
@@ -115,8 +141,6 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
}
}
private void onWorldGenTaskComplete(Boolean genTaskCompleted, Throwable exception, GenTask genTask, DhSectionPos pos)
{
if (exception != null)
@@ -131,6 +155,12 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
{
this.files.get(genTask.pos).flushAndSave();
// fire the event listeners
for (IOnWorldGenCompleteListener listener : this.onWorldGenTaskCompleteListeners)
{
listener.onWorldGenTaskComplete(genTask.pos);
}
// this.files.get(genTask.pos).metaData.dataVersion.incrementAndGet();
return;
}
@@ -140,9 +170,9 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
//==============//
// helper class //
//==============//
//================//
// helper classes //
//================//
private class GenTask implements IWorldGenTaskTracker
{
@@ -191,5 +221,15 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
}
/**
* used by external event listeners <br>
* TODO may or may not be best to have this in a separate file
*/
@FunctionalInterface
public interface IOnWorldGenCompleteListener
{
/** Fired whenever a section has completed generating */
void onWorldGenTaskComplete(DhSectionPos pos);
}
}
@@ -11,6 +11,7 @@ import com.seibel.lod.core.generation.WorldGenerationQueue;
import com.seibel.lod.core.file.fullDatafile.GeneratedFullDataFileHandler;
import com.seibel.lod.core.level.states.ClientRenderState;
import com.seibel.lod.core.logging.f3.F3Screen;
import com.seibel.lod.core.pos.DhSectionPos;
import com.seibel.lod.core.util.FileScanUtil;
import com.seibel.lod.core.pos.DhBlockPos2D;
import com.seibel.lod.core.config.Config;
@@ -28,7 +29,7 @@ import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicReference;
/** The level used on a singleplayer world */
public class DhClientServerLevel extends AbstractDhClientLevel implements IDhClientLevel, IDhServerLevel
public class DhClientServerLevel extends AbstractDhClientLevel implements IDhClientLevel, IDhServerLevel, GeneratedFullDataFileHandler.IOnWorldGenCompleteListener
{
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class);
@@ -242,6 +243,17 @@ public class DhClientServerLevel extends AbstractDhClientLevel implements IDhCli
}
@Override
public void onWorldGenTaskComplete(DhSectionPos pos)
{
ClientRenderState clientRenderState = this.ClientRenderStateRef.get();
if (clientRenderState != null && clientRenderState.quadtree != null)
{
clientRenderState.quadtree.reloadPos(pos);
}
}
//================//
@@ -255,7 +267,7 @@ public class DhClientServerLevel extends AbstractDhClientLevel implements IDhCli
WorldGenState(IDhLevel level)
WorldGenState(DhClientServerLevel level)
{
IDhApiWorldGenerator worldGenerator = WorldGeneratorInjector.INSTANCE.get(level.getLevelWrapper());
if (worldGenerator == null)
@@ -270,6 +282,7 @@ public class DhClientServerLevel extends AbstractDhClientLevel implements IDhCli
this.worldGenerationQueue = new WorldGenerationQueue(this.chunkGenerator);
DhClientServerLevel.this.generatedFullDataFileHandler.setGenerationQueue(this.worldGenerationQueue);
DhClientServerLevel.this.generatedFullDataFileHandler.addWorldGenCompleteListener(level);
}
@@ -601,12 +601,6 @@ public class LodQuadTree implements AutoCloseable
// load in the new section
section.setRenderSourceProvider(this.renderSourceProvider);
}
// unimplemented, would be needed for dedicated server support
// else if (section.isOutdated())
// {
// // replace the out of date data
// section.reload(this.renderSourceProvider);
// }
// enable rendering if this section is a leaf node in the tree, otherwise disable rendering
@@ -728,6 +722,10 @@ public class LodQuadTree implements AutoCloseable
//=============//
// render data //
//=============//
/**
* Re-creates the color, render data.
* This method should be called after resource packs are changed or LOD settings are modified.
@@ -754,6 +752,18 @@ public class LodQuadTree implements AutoCloseable
LOGGER.info("Render cache invalidated");
}
/**
* Can be called whenever a render section's data needs to be refreshed. <br>
* This should be called whenever a world generation task is completed or if the connected server has new data to show.
*/
public void reloadPos(DhSectionPos pos)
{
LodRenderSection renderSection = this.getSection(pos);
if (renderSection != null)
{
renderSection.reload(this.renderSourceProvider);
}
}