Mirror von
https://github.com/IntellectualSites/FastAsyncWorldEdit.git
synchronisiert 2024-11-07 12:00:07 +01:00
document some methods
Dieser Commit ist enthalten in:
Ursprung
57b5be84f4
Commit
6692a2eb92
@ -38,7 +38,7 @@ public class BukkitChunkHolder extends ChunkHolder<Boolean, BukkitQueue> {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(final Filter filter) {
|
||||
public void set(final Filter filter) {
|
||||
// for each block
|
||||
// filter.applyBlock(block)
|
||||
throw new UnsupportedOperationException("Not implemented");
|
||||
|
@ -21,7 +21,7 @@ public class BukkitFullChunk extends ChunkHolder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void filter(Filter filter) {
|
||||
public void set(Filter filter) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,10 @@ package com.boydti.fawe.beta;
|
||||
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
|
||||
public interface Filter {
|
||||
/**
|
||||
* A filter is an interface used for setting blocks
|
||||
*/
|
||||
public interface Filter {
|
||||
/**
|
||||
* Check whether a chunk should be read
|
||||
*
|
||||
@ -47,4 +50,13 @@ public interface Filter {
|
||||
*/
|
||||
default void finishChunk(final IChunk chunk) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fork this for use by another thread
|
||||
* - Typically filters are simple and don't need to create another copy to be thread safe here
|
||||
* @return this
|
||||
*/
|
||||
default Filter fork() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package com.boydti.fawe.beta;
|
||||
|
||||
/**
|
||||
* Shared interface for IGetBlocks and ISetBlocks
|
||||
*/
|
||||
public interface IBlocks {
|
||||
|
||||
}
|
||||
}
|
@ -5,30 +5,59 @@ import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
public interface IChunk<T, V extends IQueueExtent> {
|
||||
/* set */
|
||||
boolean setBiome(int x, int y, int z, BiomeType biome);
|
||||
|
||||
boolean setBlock(int x, int y, int z, BlockStateHolder block);
|
||||
|
||||
/* get */
|
||||
BiomeType getBiome(int x, int z);
|
||||
|
||||
BlockState getBlock(int x, int y, int z);
|
||||
|
||||
BaseBlock getFullBlock(int x, int y, int z);
|
||||
|
||||
/**
|
||||
* Represents a chunk in the queue {@link IQueueExtent}
|
||||
* Used for getting and setting blocks / biomes / entities
|
||||
* @param <T> The result type (typically returns true when the chunk is applied)
|
||||
* @param <V> The IQueue class
|
||||
*/
|
||||
public interface IChunk<T, V extends IQueueExtent> extends Trimable {
|
||||
/**
|
||||
* Initialize at the location
|
||||
* @param extent
|
||||
* @param X
|
||||
* @param Z
|
||||
*/
|
||||
void init(V extent, int X, int Z);
|
||||
|
||||
T apply();
|
||||
|
||||
int getX();
|
||||
|
||||
int getZ();
|
||||
|
||||
/**
|
||||
* If the chunk is a delegate, returns it's paren'ts root
|
||||
* @return root IChunk
|
||||
*/
|
||||
default IChunk getRoot() {
|
||||
return this;
|
||||
}
|
||||
|
||||
void filter(Filter filter);
|
||||
/**
|
||||
* @return true if no changes are queued for this chunk
|
||||
*/
|
||||
boolean isEmpty();
|
||||
|
||||
/**
|
||||
* Apply the queued changes to the world
|
||||
* @return
|
||||
*/
|
||||
T apply();
|
||||
|
||||
/* set - queues a change */
|
||||
boolean setBiome(int x, int y, int z, BiomeType biome);
|
||||
|
||||
boolean setBlock(int x, int y, int z, BlockStateHolder block);
|
||||
|
||||
/**
|
||||
* Set using the filter
|
||||
* @param filter
|
||||
*/
|
||||
void set(Filter filter);
|
||||
|
||||
/* get - from the world */
|
||||
BiomeType getBiome(int x, int z);
|
||||
|
||||
BlockState getBlock(int x, int y, int z);
|
||||
|
||||
BaseBlock getFullBlock(int x, int y, int z);
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
package com.boydti.fawe.beta;
|
||||
|
||||
import com.boydti.fawe.beta.implementation.SingleThreadQueueExtent;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
/**
|
||||
* Delegate for IChunk
|
||||
* @param <T> The result type (typically returns true when the chunk is applied)
|
||||
* @param <V> The IQueue class
|
||||
* @param <U> parent class
|
||||
*/
|
||||
public interface IDelegateChunk<T, V extends IQueueExtent, U extends IChunk<T, V>> extends IChunk<T, V> {
|
||||
U getParent();
|
||||
|
||||
@ -57,11 +62,26 @@ public interface IDelegateChunk<T, V extends IQueueExtent, U extends IChunk<T, V
|
||||
return getParent().getZ();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
default boolean trim(boolean aggressive) {
|
||||
return getParent().trim(aggressive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply this chunk to the world
|
||||
* @return result T (typically a boolean)
|
||||
*/
|
||||
@Override
|
||||
default T apply() {
|
||||
return getParent().apply();
|
||||
}
|
||||
|
||||
@Override
|
||||
default boolean isEmpty() {
|
||||
return getParent().isEmpty();
|
||||
}
|
||||
|
||||
default <T extends IChunk> T findParent(final Class<T> clazz) {
|
||||
IChunk root = getParent();
|
||||
if (clazz.isAssignableFrom(root.getClass())) return (T) root;
|
||||
@ -73,7 +93,7 @@ public interface IDelegateChunk<T, V extends IQueueExtent, U extends IChunk<T, V
|
||||
}
|
||||
|
||||
@Override
|
||||
default void filter(Filter filter) {
|
||||
getParent().filter(filter);
|
||||
default void set(Filter filter) {
|
||||
getParent().set(filter);
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,9 @@ import com.boydti.fawe.beta.implementation.WorldChunkCache;
|
||||
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* Delegate for IQueueExtent
|
||||
*/
|
||||
public interface IDelegateQueueExtent extends IQueueExtent {
|
||||
IQueueExtent getParent();
|
||||
|
||||
|
@ -4,12 +4,16 @@ import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||
import com.sk89q.worldedit.world.block.BlockState;
|
||||
|
||||
public interface IGetBlocks extends IBlocks {
|
||||
/**
|
||||
* Interface for getting blocks
|
||||
*/
|
||||
public interface IGetBlocks extends IBlocks, Trimable {
|
||||
BaseBlock getFullBlock(int x, int y, int z);
|
||||
|
||||
BiomeType getBiome(int x, int z);
|
||||
|
||||
BlockState getBlock(int x, int y, int z);
|
||||
|
||||
void trim();
|
||||
@Override
|
||||
boolean trim(boolean aggressive);
|
||||
}
|
||||
|
@ -8,11 +8,27 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
import java.io.Flushable;
|
||||
import java.util.concurrent.Future;
|
||||
|
||||
/**
|
||||
* TODO: implement Extent (need to refactor Extent first)
|
||||
* Interface for a queue based extent which uses chunks
|
||||
*/
|
||||
public interface IQueueExtent extends Flushable, Trimable {
|
||||
void init(WorldChunkCache world);
|
||||
|
||||
/**
|
||||
* Get the IChunk at a position (and cache it if it's not already)
|
||||
* @param X
|
||||
* @param Z
|
||||
* @return IChunk
|
||||
*/
|
||||
IChunk getCachedChunk(int X, int Z);
|
||||
|
||||
/**
|
||||
* Submit the chunk so that it's changes are applied to the world
|
||||
* @param chunk
|
||||
* @param <T> result type
|
||||
* @return result
|
||||
*/
|
||||
<T> Future<T> submit(IChunk<T, ?> chunk);
|
||||
|
||||
default boolean setBlock(final int x, final int y, final int z, final BlockStateHolder state) {
|
||||
@ -36,14 +52,16 @@ public interface IQueueExtent extends Flushable, Trimable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the IChunk
|
||||
* Create a new root IChunk object<br>
|
||||
* - Full chunks will be reused, so a more optimized chunk can be returned in that case<br>
|
||||
* - Don't wrap the chunk, that should be done in {@link #wrap(IChunk)}
|
||||
* @param full
|
||||
* @return
|
||||
*/
|
||||
IChunk create(boolean full);
|
||||
|
||||
/**
|
||||
* Wrap the chunk object (i.e. for region restrictions etc.)
|
||||
* Wrap the chunk object (i.e. for region restrictions / limits etc.)
|
||||
* @param root
|
||||
* @return wrapped chunk
|
||||
*/
|
||||
@ -51,6 +69,10 @@ public interface IQueueExtent extends Flushable, Trimable {
|
||||
return root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush all changes to the world
|
||||
* - Best to call this async so it doesn't hang the server
|
||||
*/
|
||||
@Override
|
||||
void flush();
|
||||
}
|
@ -3,8 +3,13 @@ package com.boydti.fawe.beta;
|
||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
/**
|
||||
* Interface for setting blocks
|
||||
*/
|
||||
public interface ISetBlocks extends IBlocks {
|
||||
boolean setBiome(int x, int y, int z, BiomeType biome);
|
||||
|
||||
boolean setBlock(int x, int y, int z, BlockStateHolder holder);
|
||||
|
||||
boolean isEmpty();
|
||||
}
|
||||
|
@ -1,5 +1,14 @@
|
||||
package com.boydti.fawe.beta;
|
||||
|
||||
/**
|
||||
* Interface for objects that can be trimmed (memory related)<br>
|
||||
* - Trimming will reduce it's memory footprint
|
||||
*/
|
||||
public interface Trimable {
|
||||
/**
|
||||
* Trim the object, reducing it's memory footprint
|
||||
* @param aggressive if trimming should be aggressive e.g. Not return early when the first element cannot be trimmed
|
||||
* @return if this object is empty at the end of the trim, and can therefore be deleted
|
||||
*/
|
||||
boolean trim(boolean aggressive);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.boydti.fawe.beta.Filter;
|
||||
import com.boydti.fawe.beta.IQueueExtent;
|
||||
import com.boydti.fawe.beta.Trimable;
|
||||
import com.boydti.fawe.object.collection.IterableThreadLocal;
|
||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
|
||||
@ -12,8 +13,12 @@ import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Class which handles all the queues {@link IQueueExtent}
|
||||
*/
|
||||
public abstract class QueueHandler implements Trimable {
|
||||
private Map<World, WeakReference<WorldChunkCache>> chunkCache = new HashMap<>();
|
||||
|
||||
private IterableThreadLocal<IQueueExtent> pool = new IterableThreadLocal<IQueueExtent>() {
|
||||
@Override
|
||||
public IQueueExtent init() {
|
||||
@ -21,7 +26,14 @@ public abstract class QueueHandler implements Trimable {
|
||||
}
|
||||
};
|
||||
|
||||
public WorldChunkCache getOrCreate(final World world) {
|
||||
/**
|
||||
* Get or create the WorldChunkCache for a world
|
||||
* @param world
|
||||
* @return
|
||||
*/
|
||||
public WorldChunkCache getOrCreate(World world) {
|
||||
world = WorldWrapper.unwrap(world);
|
||||
|
||||
synchronized (chunkCache) {
|
||||
final WeakReference<WorldChunkCache> ref = chunkCache.get(world);
|
||||
if (ref != null) {
|
||||
@ -38,6 +50,7 @@ public abstract class QueueHandler implements Trimable {
|
||||
|
||||
public abstract IQueueExtent create();
|
||||
|
||||
@Override
|
||||
public boolean trim(final boolean aggressive) {
|
||||
boolean result = true;
|
||||
synchronized (chunkCache) {
|
||||
|
@ -6,6 +6,7 @@ import com.boydti.fawe.beta.implementation.holder.ReferenceChunk;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.MemUtil;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import it.unimi.dsi.fastutil.longs.Long2ObjectLinkedOpenHashMap;
|
||||
|
||||
@ -16,20 +17,37 @@ import java.util.concurrent.ForkJoinTask;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
/**
|
||||
* Single threaded implementation for IQueueExtent (still abstract)
|
||||
* - Does not implement creation of chunks (that has to implemented by the platform e.g. Bukkit)
|
||||
*
|
||||
* This queue is reusable {@link #init(WorldChunkCache)}
|
||||
*/
|
||||
public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
private WorldChunkCache cache;
|
||||
private Thread currentThread;
|
||||
|
||||
/**
|
||||
* Safety check to ensure that the thread being used matches the one being initialized on
|
||||
* - Can be removed later
|
||||
*/
|
||||
private void checkThread() {
|
||||
if (Thread.currentThread() != currentThread && currentThread != null) {
|
||||
throw new UnsupportedOperationException("This class must be used from a single thread. Use multiple queues for concurrent operations");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the {@link WorldChunkCache}
|
||||
* @return
|
||||
*/
|
||||
public WorldChunkCache getCache() {
|
||||
return cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the queue
|
||||
*/
|
||||
protected synchronized void reset() {
|
||||
checkThread();
|
||||
cache = null;
|
||||
@ -37,7 +55,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
for (IChunk chunk : chunks.values()) {
|
||||
chunk = chunk.getRoot();
|
||||
if (chunk != null) {
|
||||
chunkPool.add(chunk);
|
||||
CHUNK_POOL.add(chunk);
|
||||
}
|
||||
}
|
||||
chunks.clear();
|
||||
@ -47,6 +65,10 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
currentThread = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the queue
|
||||
* @param cache
|
||||
*/
|
||||
@Override
|
||||
public synchronized void init(final WorldChunkCache cache) {
|
||||
if (cache != null) {
|
||||
@ -57,24 +79,32 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
// Last access pointers
|
||||
private IChunk lastChunk;
|
||||
private long lastPair = Long.MAX_VALUE;
|
||||
// Chunks currently being queued / worked on
|
||||
private final Long2ObjectLinkedOpenHashMap<IChunk> chunks = new Long2ObjectLinkedOpenHashMap<>();
|
||||
private final ConcurrentLinkedQueue<IChunk> chunkPool = new ConcurrentLinkedQueue<>();
|
||||
// Pool discarded chunks for reuse (can safely be cleared by another thread)
|
||||
private static final ConcurrentLinkedQueue<IChunk> CHUNK_POOL = new ConcurrentLinkedQueue<>();
|
||||
|
||||
@Override
|
||||
public <T> ForkJoinTask<T> submit(final IChunk<T, ?> tmp) {
|
||||
public <T> ForkJoinTask<T> submit(final IChunk<T, ?> chunk) {
|
||||
if (chunk.isEmpty()) {
|
||||
CHUNK_POOL.add(chunk);
|
||||
return null;
|
||||
}
|
||||
// TODO use SetQueue to run in parallel
|
||||
final ForkJoinPool pool = TaskManager.IMP.getPublicForkJoinPool();
|
||||
return pool.submit(new Callable<T>() {
|
||||
@Override
|
||||
public T call() {
|
||||
IChunk<T, ?> chunk = tmp;
|
||||
IChunk<T, ?> tmp = chunk;
|
||||
|
||||
T result = chunk.apply();
|
||||
T result = tmp.apply();
|
||||
|
||||
chunk = chunk.getRoot();
|
||||
if (chunk != null) {
|
||||
chunkPool.add(chunk);
|
||||
tmp = tmp.getRoot();
|
||||
if (tmp != null) {
|
||||
CHUNK_POOL.add(tmp);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -83,7 +113,8 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
|
||||
@Override
|
||||
public synchronized boolean trim(boolean aggressive) {
|
||||
chunkPool.clear();
|
||||
// TODO trim individial chunk sections
|
||||
CHUNK_POOL.clear();
|
||||
if (Thread.currentThread() == currentThread) {
|
||||
lastChunk = null;
|
||||
lastPair = Long.MAX_VALUE;
|
||||
@ -94,13 +125,21 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
}
|
||||
}
|
||||
|
||||
private IChunk pool(final int X, final int Z) {
|
||||
IChunk next = chunkPool.poll();
|
||||
/**
|
||||
* Get a new IChunk from either the pool, or create a new one<br>
|
||||
* + Initialize it at the coordinates
|
||||
* @param X
|
||||
* @param Z
|
||||
* @return IChunk
|
||||
*/
|
||||
private IChunk poolOrCreate(final int X, final int Z) {
|
||||
IChunk next = CHUNK_POOL.poll();
|
||||
if (next == null) next = create(false);
|
||||
next.init(this, X, Z);
|
||||
return next;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final IChunk getCachedChunk(final int X, final int Z) {
|
||||
final long pair = MathMan.pairInt(X, Z);
|
||||
if (pair == lastPair) {
|
||||
@ -125,7 +164,7 @@ public abstract class SingleThreadQueueExtent implements IQueueExtent {
|
||||
submit(chunk);
|
||||
}
|
||||
}
|
||||
chunk = pool(X, Z);
|
||||
chunk = poolOrCreate(X, Z);
|
||||
chunk = wrap(chunk);
|
||||
|
||||
chunks.put(pair, chunk);
|
||||
|
@ -10,6 +10,10 @@ import it.unimi.dsi.fastutil.objects.ObjectIterator;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* IGetBlocks may be cached by the WorldChunkCache so that it can be used between multiple IQueueExtents
|
||||
* - avoids conversion between palette and raw data on every block get
|
||||
*/
|
||||
public class WorldChunkCache implements Trimable {
|
||||
protected final Long2ObjectLinkedOpenHashMap<WeakReference<IGetBlocks>> getCache;
|
||||
private final World world;
|
||||
@ -27,6 +31,12 @@ public class WorldChunkCache implements Trimable {
|
||||
return getCache.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get or create the IGetBlocks
|
||||
* @param index chunk index {@link com.boydti.fawe.util.MathMan#pairInt(int, int)}
|
||||
* @param provider used to create if it isn't already cached
|
||||
* @return cached IGetBlocks
|
||||
*/
|
||||
public synchronized IGetBlocks get(final long index, final Supplier<IGetBlocks> provider) {
|
||||
final WeakReference<IGetBlocks> ref = getCache.get(index);
|
||||
if (ref != null) {
|
||||
@ -52,7 +62,7 @@ public class WorldChunkCache implements Trimable {
|
||||
result = false;
|
||||
if (!aggressive) return result;
|
||||
synchronized (igb) {
|
||||
igb.trim();
|
||||
igb.trim(aggressive);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,9 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Abstract IChunk class that implements basic get/set blocks
|
||||
*/
|
||||
public abstract class ChunkHolder<T, V extends SingleThreadQueueExtent> implements IChunk<T, V>, Supplier<IGetBlocks> {
|
||||
private IGetBlocks get;
|
||||
private ISetBlocks set;
|
||||
@ -30,6 +33,11 @@ public abstract class ChunkHolder<T, V extends SingleThreadQueueExtent> implemen
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return set == null || set.isEmpty();
|
||||
}
|
||||
|
||||
public final IGetBlocks cachedGet() {
|
||||
if (get == null) get = newGet();
|
||||
return get;
|
||||
|
@ -3,6 +3,10 @@ package com.boydti.fawe.beta.implementation.holder;
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IDelegateChunk;
|
||||
|
||||
/**
|
||||
* Implementation of IDelegateChunk
|
||||
* @param <T>
|
||||
*/
|
||||
public class DelegateChunk<T extends IChunk> implements IDelegateChunk {
|
||||
private T parent;
|
||||
|
||||
|
@ -6,6 +6,11 @@ import com.boydti.fawe.beta.IQueueExtent;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
|
||||
/**
|
||||
* An IChunk may be wrapped by a ReferenceChunk if there is low memory<br>
|
||||
* A reference chunk stores a reference (for garbage collection purposes)<br>
|
||||
* - If it is garbage collected, the {@link FinalizedChunk} logic is run
|
||||
*/
|
||||
public abstract class ReferenceChunk implements IDelegateChunk {
|
||||
private final Reference<FinalizedChunk> ref;
|
||||
|
||||
|
@ -6,9 +6,12 @@ import com.boydti.fawe.beta.IQueueExtent;
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Soft reference implementation of {@link ReferenceChunk}
|
||||
*/
|
||||
public class SoftChunk extends ReferenceChunk {
|
||||
|
||||
public SoftChunk(final IChunk parent, IQueueExtent queueExtent) {
|
||||
public SoftChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
||||
super(parent, queueExtent);
|
||||
}
|
||||
|
||||
|
@ -1,13 +1,17 @@
|
||||
package com.boydti.fawe.beta.implementation.holder;
|
||||
|
||||
import com.boydti.fawe.beta.IChunk;
|
||||
import com.boydti.fawe.beta.IQueueExtent;
|
||||
|
||||
import java.lang.ref.Reference;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
/**
|
||||
* Weak reference implementation of {@link ReferenceChunk}
|
||||
*/
|
||||
public class WeakChunk extends ReferenceChunk {
|
||||
public WeakChunk(final IChunk parent) {
|
||||
super(parent);
|
||||
public WeakChunk(final IChunk parent, final IQueueExtent queueExtent) {
|
||||
super(parent, queueExtent);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren