Create new world gen tasks when moving into new areas

This commit is contained in:
James Seibel
2023-05-04 07:31:35 -05:00
parent 05ca9bca15
commit 2cb044f4b5
2 changed files with 66 additions and 18 deletions
@@ -61,6 +61,8 @@ public interface IFullDataSource
FullDataPointIdMap getMapping();
/** @return true if every datapoint in this object has been generated, false otherwise. */
default boolean isCompletelyGenerated() { return this.getUngeneratedPosList().size() == 0; }
/** @return the list of {@link DhSectionPos} that aren't generated in this data source. */
ArrayList<DhSectionPos> getUngeneratedPosList();
@@ -30,12 +30,32 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
private final ArrayList<IOnWorldGenCompleteListener> onWorldGenTaskCompleteListeners = new ArrayList<>();
/**
* Keeps track of which partially generated {@link IFullDataSource} {@link DhSectionPos}' are waiting to be generated.
* This is done to prevent sending duplicate generation requests for the same position.
*/
private final HashSet<DhSectionPos> incompleteSourceGenRequests = new HashSet<>();
public GeneratedFullDataFileHandler(IDhServerLevel level, File saveRootDir) { super(level, saveRootDir); }
//======//
// data //
//======//
public CompletableFuture<IFullDataSource> read(DhSectionPos pos)
{
return super.read(pos).whenComplete((fullDataSource, ex) ->
{
this.checkIfSectionNeedsAdditionalGeneration(pos, fullDataSource);
});
}
//==================//
// generation queue //
//==================//
@@ -55,15 +75,8 @@ 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);
}
public void addWorldGenCompleteListener(IOnWorldGenCompleteListener listener) { this.onWorldGenTaskCompleteListeners.add(listener); }
public void removeWorldGenCompleteListener(IOnWorldGenCompleteListener listener) { this.onWorldGenTaskCompleteListeners.remove(listener); }
@@ -126,22 +139,26 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
}
}
LOGGER.debug("Creating {} from sampling {} files: {}", pos, existingFiles.size(), existingFiles);
// LOGGER.debug("Creating "+pos+" from sampling "+existingFiles.size()+" files: "+existingFiles);
// read in the existing data
final ArrayList<CompletableFuture<Void>> loadDataFutures = new ArrayList<>(existingFiles.size());
for (FullDataMetaFile existingFile : existingFiles)
{
loadDataFutures.add(existingFile.loadOrGetCachedAsync()
.exceptionally((ex) -> /*Ignore file read errors*/null)
.thenAccept((data) ->
.exceptionally((ex) -> /*Ignore file read errors*/null)
.thenAccept((fullDataSource) ->
{
if (fullDataSource == null)
{
if (data != null)
{
//LOGGER.info("Merging data from {} into {}", data.getSectionPos(), pos);
incompleteFullDataSource.sampleFrom(data);
}
})
return;
}
this.checkIfSectionNeedsAdditionalGeneration(pos, fullDataSource);
//LOGGER.info("Merging data from {} into {}", data.getSectionPos(), pos);
incompleteFullDataSource.sampleFrom(fullDataSource);
})
);
}
@@ -150,6 +167,34 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
}
}
/**
* Checks if the given {@link IFullDataSource} is fully generated and
* if it isn't, new world gen request(s) will be created.
*/
private void checkIfSectionNeedsAdditionalGeneration(DhSectionPos pos, IFullDataSource fullDataSource)
{
if (!fullDataSource.isCompletelyGenerated() && !incompleteSourceGenRequests.contains(pos))
{
WorldGenerationQueue worldGenQueue = this.worldGenQueueRef.get();
if (worldGenQueue != null)
{
incompleteSourceGenRequests.add(pos);
//LOGGER.info("["+ungeneratedPosList.size()+"] missing sub positions for pos: ["+pos+"]. Number of gen requests queued: ["+queuedGenRequests.size()+"].");
// note: this will potentially re-generate terrain, however due to the generator setup this is currently unavoidable and probably not worth worrying about
GenTask genTask = new GenTask(pos, new WeakReference<>(fullDataSource));
worldGenQueue.submitGenTask(fullDataSource.getSectionPos().getSectionBBoxPos(), fullDataSource.getDataDetailLevel(), genTask)
.whenComplete((genTaskResult, ex) ->
{
incompleteSourceGenRequests.remove(pos);
//LOGGER.info("Partial generation completed for pos: ["+pos+"]. Remaining gen requests queued: ["+queuedGenRequests.size()+"].");
this.onWorldGenTaskComplete(genTaskResult, ex, genTask, pos);
});
}
}
}
private void onWorldGenTaskComplete(WorldGenResult genTaskResult, Throwable exception, GenTask genTask, DhSectionPos pos)
{
if (exception != null)
@@ -164,6 +209,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler
{
// generation completed, update the files and listener(s)
// LOGGER.info("gen task completed for pos: ["+pos+"].");
this.files.get(genTask.pos).flushAndSaveAsync();
// fire the event listeners