use of org.terasology.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class LocalChunkProvider method checkForUnload.
private void checkForUnload() {
PerformanceMonitor.startActivity("Unloading irrelevant chunks");
int unloaded = 0;
logger.debug("Compacting cache");
Iterator<Vector3i> iterator = chunkCache.iterateChunkPositions();
while (iterator.hasNext()) {
Vector3i pos = iterator.next();
boolean keep = false;
for (ChunkRelevanceRegion region : regions.values()) {
if (region.getCurrentRegion().expand(UNLOAD_LEEWAY).encompasses(pos)) {
keep = true;
break;
}
}
if (!keep) {
// Note: Above won't matter if all changes are on the main thread
if (unloadChunkInternal(pos)) {
iterator.remove();
if (++unloaded >= UNLOAD_PER_FRAME) {
break;
}
}
}
}
PerformanceMonitor.endActivity();
}
use of org.terasology.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class LocalChunkProvider method addRelevanceEntity.
@Override
public void addRelevanceEntity(EntityRef entity, Vector3i distance, ChunkRegionListener listener) {
if (!entity.exists()) {
return;
}
regionLock.readLock().lock();
try {
ChunkRelevanceRegion region = regions.get(entity);
if (region != null) {
region.setRelevanceDistance(distance);
return;
}
} 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();
}
for (Vector3i pos : region.getCurrentRegion()) {
Chunk chunk = getChunk(pos);
if (chunk != null) {
region.checkIfChunkIsRelevant(chunk);
} else {
createOrLoadChunk(pos);
}
}
}
use of org.terasology.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class LocalChunkProvider method unloadChunkInternal.
private boolean unloadChunkInternal(Vector3i pos) {
Chunk chunk = chunkCache.get(pos);
if (!chunk.isReady()) {
// Chunk hasn't been finished or changed, so just drop it.
Iterator<ReadyChunkInfo> infoIterator = sortedReadyChunks.iterator();
while (infoIterator.hasNext()) {
ReadyChunkInfo next = infoIterator.next();
if (next.getPos().equals(chunk.getPosition())) {
infoIterator.remove();
break;
}
}
return true;
}
worldEntity.send(new BeforeChunkUnload(pos));
for (ChunkRelevanceRegion region : regions.values()) {
region.chunkUnloaded(pos);
}
storageManager.deactivateChunk(chunk);
chunk.dispose();
try {
unloadRequestTaskMaster.put(new ChunkUnloadRequest(chunk, this));
} catch (InterruptedException e) {
logger.error("Failed to enqueue unload request for {}", chunk.getPosition(), e);
}
return true;
}
use of org.terasology.world.chunks.internal.ChunkRelevanceRegion in project Terasology by MovingBlocks.
the class LocalChunkProvider method purgeWorld.
@Override
public void purgeWorld() {
ChunkMonitor.fireChunkProviderDisposed(this);
pipeline.shutdown();
unloadRequestTaskMaster.shutdown(new ChunkUnloadRequest(), true);
chunkFinalizer.shutdown();
chunkCache.getAllChunks().stream().filter(ManagedChunk::isReady).forEach(chunk -> {
worldEntity.send(new BeforeChunkUnload(chunk.getPosition()));
storageManager.deactivateChunk(chunk);
chunk.dispose();
});
chunkCache.clear();
readyChunks.clear();
sortedReadyChunks.clear();
storageManager.deleteWorld();
preparingChunks.clear();
worldEntity.send(new PurgeWorldEvent());
pipeline = new ChunkGenerationPipeline(new ChunkTaskRelevanceComparator());
unloadRequestTaskMaster = TaskMaster.createFIFOTaskMaster("Chunk-Unloader", 8);
chunkFinalizer = chunkFinalizerSupplier.get();
chunkFinalizer.initialize(this);
chunkFinalizer.restart();
ChunkMonitor.fireChunkProviderInitialized(this);
for (ChunkRelevanceRegion chunkRelevanceRegion : regions.values()) {
for (Vector3i pos : chunkRelevanceRegion.getCurrentRegion()) {
createOrLoadChunk(pos);
}
chunkRelevanceRegion.setUpToDate();
}
}
Aggregations