175 lines
4.9 KiB
Java
175 lines
4.9 KiB
Java
package com.boydti.fawe.beta;
|
|
|
|
import com.boydti.fawe.FaweCache;
|
|
import com.boydti.fawe.beta.implementation.IChunkExtent;
|
|
import com.boydti.fawe.beta.implementation.filter.block.ChunkFilterBlock;
|
|
import com.boydti.fawe.beta.implementation.processors.IBatchProcessorHolder;
|
|
import com.sk89q.worldedit.extent.Extent;
|
|
import com.sk89q.worldedit.function.operation.Operation;
|
|
import com.sk89q.worldedit.math.BlockVector2;
|
|
import com.sk89q.worldedit.math.BlockVector3;
|
|
import com.sk89q.worldedit.regions.Region;
|
|
import org.jetbrains.annotations.Range;
|
|
|
|
import java.io.Flushable;
|
|
import java.util.Set;
|
|
import java.util.concurrent.Future;
|
|
import javax.annotation.Nullable;
|
|
|
|
/**
|
|
* TODO: implement Extent (need to refactor Extent first) Interface for a queue based extent which
|
|
* uses chunks
|
|
*/
|
|
public interface IQueueExtent<T extends IChunk> extends Flushable, Trimable, IChunkExtent<T>, IBatchProcessorHolder {
|
|
|
|
@Override
|
|
default boolean isQueueEnabled() {
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Must ensure that it is enqueued with QueueHandler
|
|
*/
|
|
@Override
|
|
void enableQueue();
|
|
|
|
/**
|
|
* Must ensure it is not in the queue handler (i.e. does not change blocks in the world)
|
|
*/
|
|
@Override
|
|
void disableQueue();
|
|
|
|
|
|
/**
|
|
* Initialize the queue (for reusability)
|
|
* @param extent
|
|
* @param get
|
|
* @param set
|
|
*/
|
|
void init(Extent extent, IChunkCache<IChunkGet> get, IChunkCache<IChunkSet> set);
|
|
|
|
/**
|
|
* Get the cached get object. This is faster than getting the object using NMS and allows for
|
|
* wrapping.
|
|
* @param chunkX
|
|
* @param chunkZ
|
|
* @return
|
|
*/
|
|
IChunkGet getCachedGet(@Range(from = 0, to = 15) int chunkX, @Range(from = 0, to = 15) int chunkZ);
|
|
|
|
/**
|
|
* Get the cached chunk set object.
|
|
* @param chunkX
|
|
* @param chunkZ
|
|
* @return
|
|
*/
|
|
IChunkSet getCachedSet(@Range(from = 0, to = 15) int chunkX, @Range(from = 0, to = 15) int chunkZ);
|
|
|
|
/**
|
|
* Submit the chunk so that it's changes are applied to the world
|
|
*
|
|
* @param chunk
|
|
* @return result
|
|
*/
|
|
<V extends Future<V>> V submit(T chunk);
|
|
|
|
@Override
|
|
default BlockVector3 getMinimumPoint() {
|
|
return BlockVector3.at(-30000000, 0, -30000000);
|
|
}
|
|
|
|
@Override
|
|
default BlockVector3 getMaximumPoint() {
|
|
return BlockVector3.at(30000000, FaweCache.IMP.WORLD_MAX_Y, 30000000);
|
|
}
|
|
|
|
void setFastMode(boolean fastMode);
|
|
|
|
boolean isFastMode();
|
|
|
|
/**
|
|
* Create a new root IChunk object. Full chunks will be reused, so a more optimized chunk can be
|
|
* returned in that case.
|
|
*
|
|
* @apiNote Don't wrap the chunk, that should be done in {@link IQueueExtent#wrap(IChunk)}
|
|
* @param isFull true if a more optimized chunk should be returned
|
|
* @return a more optimized chunk object
|
|
*/
|
|
T create(boolean isFull);
|
|
|
|
/**
|
|
* Wrap the chunk object (i.e., for region restrictions / limits etc.).
|
|
*
|
|
* @return wrapped chunk
|
|
*/
|
|
default T wrap(T root) {
|
|
return root;
|
|
}
|
|
|
|
@Nullable
|
|
@Override
|
|
default Operation commit() {
|
|
flush();
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Flush all changes to the world.
|
|
* @apiNote Best to call this async, so it doesn't hang the server.
|
|
*/
|
|
@Override
|
|
void flush();
|
|
|
|
/**
|
|
* A filter block is used to iterate over blocks / positions. Essentially combines BlockVector3,
|
|
* Extent and BlockState functions in a way that avoids lookups.
|
|
*/
|
|
ChunkFilterBlock initFilterBlock();
|
|
|
|
/**
|
|
* Returns the number of chunks in this queue.
|
|
*
|
|
* @return the number of chunks in this queue
|
|
*/
|
|
int size();
|
|
|
|
/**
|
|
* Returns <tt>true</tt> if this queue contains no elements.
|
|
*
|
|
* @return <tt>true</tt> if this queue contains no elements
|
|
*/
|
|
boolean isEmpty();
|
|
|
|
default ChunkFilterBlock apply(ChunkFilterBlock block, Filter filter, Region region, int chunkX, int chunkZ, boolean full) {
|
|
if (!filter.appliesChunk(chunkX, chunkZ)) {
|
|
return block;
|
|
}
|
|
T chunk = this.getOrCreateChunk(chunkX, chunkZ);
|
|
// Initialize
|
|
chunk.init(this, chunkX, chunkZ);
|
|
chunk.setFastMode(isFastMode());
|
|
|
|
T newChunk = filter.applyChunk(chunk, region);
|
|
if (newChunk != null) {
|
|
chunk = newChunk;
|
|
if (block == null) {
|
|
block = this.initFilterBlock();
|
|
}
|
|
chunk.filterBlocks(filter, block, region, full);
|
|
}
|
|
this.submit(chunk);
|
|
return block;
|
|
}
|
|
|
|
@Override
|
|
default <T extends Filter> T apply(Region region, T filter, boolean full) {
|
|
final Set<BlockVector2> chunks = region.getChunks();
|
|
ChunkFilterBlock block = null;
|
|
for (BlockVector2 chunk : chunks) {
|
|
block = apply(block, filter, region, chunk.getX(), chunk.getZ(), full);
|
|
}
|
|
flush();
|
|
return filter;
|
|
}
|
|
}
|