use of org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class RelevanceSystem method addRelevanceEntity.
/**
* Add entity to relevance system. create region for it. Update distance if region exists already. Create/Load
* chunks for region.
*
* @param entity the region will be centered around the LocationComponent of this entity
* @param distance the dimensions of the region, in chunks
* @param listener notified when relevant chunks become available
*
* @return the region of chunks deemed relevant
*/
public BlockRegionc addRelevanceEntity(EntityRef entity, Vector3ic distance, ChunkRegionListener listener) {
if (!entity.exists()) {
// Futures.immediateFailedFuture(new IllegalArgumentException("Entity does not exist."));
return null;
}
regionLock.readLock().lock();
try {
ChunkRelevanceRegion region = regions.get(entity);
if (region != null) {
region.setRelevanceDistance(distance);
// Future of “when region.currentRegion is no longer dirty”?
return new BlockRegion(region.getCurrentRegion());
}
} finally {
regionLock.readLock().unlock();
}
ChunkRelevanceRegion region = new ChunkRelevanceRegion(entity, distance);
if (listener != null) {
region.setListener(listener);
}
regionLock.writeLock().lock();
try {
regions.put(entity, region);
} finally {
regionLock.writeLock().unlock();
}
StreamSupport.stream(region.getCurrentRegion().spliterator(), false).sorted(// <-- this is n^2 cost. not sure why this needs to be sorted like this.
new PositionRelevanceComparator()).forEach(pos -> {
Chunk chunk = chunkProvider.getChunk(pos);
if (chunk != null) {
region.checkIfChunkIsRelevant(chunk);
// return Futures.immediateFuture(chunk);
} else {
// return this
chunkProvider.createOrLoadChunk(pos);
}
});
// whenAllComplete
return new BlockRegion(region.getCurrentRegion());
}
use of org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class RelevanceSystem method regionsDistanceScore.
private int regionsDistanceScore(Vector3ic chunk) {
int score = Integer.MAX_VALUE;
regionLock.readLock().lock();
try {
for (ChunkRelevanceRegion region : regions.values()) {
int dist = (int) chunk.gridDistance(region.getCenter());
if (dist < score) {
score = dist;
}
if (score == 0) {
break;
}
}
return score;
} finally {
regionLock.readLock().unlock();
}
}
use of org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class LocalChunkProvider method purgeWorld.
@Override
public void purgeWorld() {
ChunkMonitor.fireChunkProviderDisposed(this);
loadingPipeline.shutdown();
unloadRequestTaskMaster.shutdown(new ChunkUnloadRequest(), true);
getAllChunks().stream().filter(Chunk::isReady).forEach(chunk -> {
worldEntity.send(new BeforeChunkUnload(chunk.getPosition(new Vector3i())));
storageManager.deactivateChunk(chunk);
chunk.dispose();
});
chunkCache.clear();
storageManager.deleteWorld();
worldEntity.send(new PurgeWorldEvent());
loadingPipeline = new ChunkProcessingPipeline(this::getChunk, relevanceSystem.createChunkTaskComporator());
loadingPipeline.addStage(ChunkTaskProvider.create("Chunk generate internal lightning", (Consumer<Chunk>) InternalLightProcessor::generateInternalLighting)).addStage(ChunkTaskProvider.create("Chunk deflate", Chunk::deflate)).addStage(ChunkTaskProvider.createMulti("Light merging", chunks -> {
Chunk[] localChunks = chunks.toArray(new Chunk[0]);
return LightMerger.merge(localChunks);
}, LightMerger::requiredChunks)).addStage(ChunkTaskProvider.create("Chunk ready", readyChunks::add));
unloadRequestTaskMaster = TaskMaster.createFIFOTaskMaster("Chunk-Unloader", 8);
ChunkMonitor.fireChunkProviderInitialized(this);
for (ChunkRelevanceRegion chunkRelevanceRegion : relevanceSystem.getRegions()) {
for (Vector3ic pos : chunkRelevanceRegion.getCurrentRegion()) {
createOrLoadChunk(pos);
}
chunkRelevanceRegion.setUpToDate();
}
}
Aggregations