Search in sources :

Example 1 with ChunkRelevanceRegion

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());
}
Also used : ChunkRelevanceRegion(org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion) BlockRegion(org.terasology.engine.world.block.BlockRegion) Chunk(org.terasology.engine.world.chunks.Chunk)

Example 2 with ChunkRelevanceRegion

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();
    }
}
Also used : ChunkRelevanceRegion(org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion)

Example 3 with ChunkRelevanceRegion

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();
    }
}
Also used : BeforeChunkUnload(org.terasology.engine.world.chunks.event.BeforeChunkUnload) LightMerger(org.terasology.engine.world.propagation.light.LightMerger) Vector3ic(org.joml.Vector3ic) ChunkRelevanceRegion(org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion) Vector3i(org.joml.Vector3i) PurgeWorldEvent(org.terasology.engine.world.chunks.event.PurgeWorldEvent) ChunkProcessingPipeline(org.terasology.engine.world.chunks.pipeline.ChunkProcessingPipeline) Chunk(org.terasology.engine.world.chunks.Chunk)

Aggregations

ChunkRelevanceRegion (org.terasology.engine.world.chunks.internal.ChunkRelevanceRegion)3 Chunk (org.terasology.engine.world.chunks.Chunk)2 Vector3i (org.joml.Vector3i)1 Vector3ic (org.joml.Vector3ic)1 BlockRegion (org.terasology.engine.world.block.BlockRegion)1 BeforeChunkUnload (org.terasology.engine.world.chunks.event.BeforeChunkUnload)1 PurgeWorldEvent (org.terasology.engine.world.chunks.event.PurgeWorldEvent)1 ChunkProcessingPipeline (org.terasology.engine.world.chunks.pipeline.ChunkProcessingPipeline)1 LightMerger (org.terasology.engine.world.propagation.light.LightMerger)1