geforkt von Mirrors/FastAsyncWorldEdit
wip chunk based bitset
Dieser Commit ist enthalten in:
Ursprung
d6a8e9738a
Commit
14d5275e05
@ -17,6 +17,7 @@ import com.sk89q.worldedit.function.operation.Operations;
|
||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||
import com.sk89q.worldedit.function.visitor.RegionVisitor;
|
||||
import com.sk89q.worldedit.math.BlockVector2;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.util.Countable;
|
||||
import com.sk89q.worldedit.world.World;
|
||||
@ -103,6 +104,10 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
|
||||
return filter;
|
||||
}
|
||||
|
||||
public int getChanges() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBlocks(final Region region, final Mask searchMask) {
|
||||
return
|
||||
@ -116,19 +121,25 @@ public class MultiThreadedQueue extends AbstractDelegateExtent implements IQueue
|
||||
@Override
|
||||
public <B extends BlockStateHolder<B>> int setBlocks(Region region, B block) throws MaxChangedBlocksException {
|
||||
apply(region, block);
|
||||
return 0;
|
||||
return getChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Region region, Pattern pattern) throws MaxChangedBlocksException {
|
||||
apply(region, pattern);
|
||||
return 0;
|
||||
return getChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int setBlocks(Set<BlockVector3> vset, Pattern pattern) {
|
||||
TODO
|
||||
return getChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int replaceBlocks(Region region, Mask mask, Pattern pattern) throws MaxChangedBlocksException {
|
||||
apply(region, mask.toFilter(pattern));
|
||||
return 0;
|
||||
return getChanges();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -686,39 +686,4 @@ public abstract class FawePlayer<T> extends Metadatable {
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the tracked EditSession(s) for this player<br>
|
||||
* - Queued or autoqueued EditSessions are considered tracked
|
||||
*
|
||||
* @param requiredStage
|
||||
* @return
|
||||
*/
|
||||
public Map<EditSession, SetQueue.QueueStage> getTrackedSessions(SetQueue.QueueStage requiredStage) {
|
||||
Map<EditSession, SetQueue.QueueStage> map = new ConcurrentHashMap<>(8, 0.9f, 1);
|
||||
if (requiredStage == null || requiredStage == SetQueue.QueueStage.ACTIVE) {
|
||||
for (FaweQueue queue : SetQueue.IMP.getActiveQueues()) {
|
||||
Collection<EditSession> sessions = queue.getEditSessions();
|
||||
for (EditSession session : sessions) {
|
||||
FawePlayer currentPlayer = session.getPlayer();
|
||||
if (currentPlayer == this) {
|
||||
map.put(session, SetQueue.QueueStage.ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (requiredStage == null || requiredStage == SetQueue.QueueStage.INACTIVE) {
|
||||
for (FaweQueue queue : SetQueue.IMP.getInactiveQueues()) {
|
||||
Collection<EditSession> sessions = queue.getEditSessions();
|
||||
for (EditSession session : sessions) {
|
||||
FawePlayer currentPlayer = session.getPlayer();
|
||||
if (currentPlayer == this) {
|
||||
map.put(session, SetQueue.QueueStage.INACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,109 @@
|
||||
package com.boydti.fawe.object.collection;
|
||||
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
|
||||
public class ChunkBVecSet implements Set<BlockVector3> {
|
||||
private final int offsetX, offsetZ;
|
||||
private final ChunkBitSet set;
|
||||
private int size = 0;
|
||||
|
||||
public ChunkBVecSet(int size) {
|
||||
this(Integer.MAX_VALUE, Integer.MAX_VALUE, new ChunkBitSet(size));
|
||||
}
|
||||
|
||||
public ChunkBVecSet(ChunkBitSet set, int offsetX, int offsetZ) {
|
||||
this.offsetX = offsetX;
|
||||
this.offsetZ = offsetZ;
|
||||
this.set = set;
|
||||
}
|
||||
|
||||
public ChunkBitSet getBitSet() {
|
||||
return set;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return size() == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
try {
|
||||
return contain((BlockVector3) o);
|
||||
} catch (ClassCastException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contain(BlockVector3 obj) {
|
||||
return contain(obj.getX(), obj.getY(), obj.getZ());
|
||||
}
|
||||
|
||||
public boolean contain(int x, int y, int z) {
|
||||
return set.get(x - offsetX, y, z - offsetZ);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<BlockVector3> iterator() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return new Object[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T> T[] toArray(@NotNull T[] a) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(BlockVector3 blockVector3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(@NotNull Collection<?> c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean addAll(@NotNull Collection<? extends BlockVector3> c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(@NotNull Collection<?> c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(@NotNull Collection<?> c) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
|
||||
}
|
||||
}
|
@ -26,6 +26,10 @@ public class ChunkBitSet {
|
||||
return rows[x >> 4].get(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
public void add(int x, int y, int z) {
|
||||
rows[x >> 4].add(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
public void set(int x, int y, int z) {
|
||||
rows[x >> 4].set(this.rows, x, y, z);
|
||||
}
|
||||
@ -37,6 +41,10 @@ public class ChunkBitSet {
|
||||
private interface IRow {
|
||||
default boolean get(IRow[] rows, int x, int y, int z) { return false; }
|
||||
void set(IRow[] rows, int x, int y, int z);
|
||||
default boolean add(IRow[] rows, int x, int y, int z) {
|
||||
set(rows, x, y, z);
|
||||
return true;
|
||||
}
|
||||
default void clear(IRow[] rows, int x, int y, int z) { return; }
|
||||
}
|
||||
|
||||
@ -85,6 +93,11 @@ public class ChunkBitSet {
|
||||
this.rows[z >> 4].set(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||
return this.rows[z >> 4].add(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(IRow[] parent, int x, int y, int z) {
|
||||
this.rows[z >> 4].clear(this.rows, x, y, z);
|
||||
@ -109,6 +122,11 @@ public class ChunkBitSet {
|
||||
this.rows[y >> 4].set(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||
return this.rows[y >> 4].add(this.rows, x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(IRow[] parent, int x, int y, int z) {
|
||||
this.rows[y >> 4].set(this.rows, x, y, z);
|
||||
@ -134,6 +152,19 @@ public class ChunkBitSet {
|
||||
bits[i >> 6] |= (1L << (i & 0x3F));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(IRow[] parent, int x, int y, int z) {
|
||||
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
|
||||
int offset = i >> 6;
|
||||
long value = bits[offset];
|
||||
long mask = (1L << (i & 0x3F));
|
||||
if ((value & mask) != 0) {
|
||||
bits[offset] = value | mask;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear(IRow[] parent, int x, int y, int z) {
|
||||
int i = ((y & 15) << 8) | ((z & 15) << 4) | (x & 15);
|
||||
|
@ -24,8 +24,6 @@ import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.object.FaweLimit;
|
||||
import com.boydti.fawe.object.FawePlayer;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.object.HistoryExtent;
|
||||
import com.boydti.fawe.object.RegionWrapper;
|
||||
import com.boydti.fawe.object.RunnableVal;
|
||||
@ -45,7 +43,6 @@ import com.boydti.fawe.util.EditSessionBuilder;
|
||||
import com.boydti.fawe.util.ExtentTraverser;
|
||||
import com.boydti.fawe.util.MaskTraverser;
|
||||
import com.boydti.fawe.util.MathMan;
|
||||
import com.boydti.fawe.util.SetQueue;
|
||||
import com.boydti.fawe.util.TaskManager;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.sk89q.jnbt.CompoundTag;
|
||||
@ -944,7 +941,7 @@ public class EditSession extends AbstractDelegateExtent implements HasFaweQueue,
|
||||
}
|
||||
|
||||
public int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
||||
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern), this);
|
||||
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
|
||||
Operations.completeBlindly(visitor);
|
||||
changes += visitor.getAffected();
|
||||
return changes;
|
||||
|
@ -581,4 +581,10 @@ public interface Extent extends InputExtent, OutputExtent {
|
||||
return setBlocks(centerRegion, pattern);
|
||||
}
|
||||
|
||||
default int setBlocks(final Set<BlockVector3> vset, final Pattern pattern) {
|
||||
RegionVisitor visitor = new RegionVisitor(vset, new BlockReplace(getExtent(), pattern));
|
||||
Operations.completeBlindly(visitor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -20,13 +20,6 @@
|
||||
package com.sk89q.worldedit.function.visitor;
|
||||
|
||||
import com.boydti.fawe.config.BBC;
|
||||
import com.boydti.fawe.config.Settings;
|
||||
import com.boydti.fawe.example.MappedFaweQueue;
|
||||
import com.boydti.fawe.object.FaweQueue;
|
||||
import com.boydti.fawe.object.HasFaweQueue;
|
||||
import com.boydti.fawe.object.exception.FaweException;
|
||||
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
import com.sk89q.worldedit.WorldEditException;
|
||||
import com.sk89q.worldedit.function.RegionFunction;
|
||||
import com.sk89q.worldedit.function.operation.Operation;
|
||||
@ -34,7 +27,6 @@ import com.sk89q.worldedit.function.operation.RunContext;
|
||||
import com.sk89q.worldedit.math.BlockVector3;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -46,7 +38,6 @@ public class RegionVisitor implements Operation {
|
||||
public final RegionFunction function;
|
||||
public int affected = 0;
|
||||
public final Iterable<? extends BlockVector3> iterable;
|
||||
private final MappedFaweQueue queue;
|
||||
|
||||
/**
|
||||
* Deprecated in favor of the other constructors which will preload chunks during iteration
|
||||
@ -56,22 +47,14 @@ public class RegionVisitor implements Operation {
|
||||
*/
|
||||
@Deprecated
|
||||
public RegionVisitor(Region region, RegionFunction function) {
|
||||
this(region, function, (FaweQueue) null);
|
||||
this((Iterable<BlockVector3>) region, function);
|
||||
}
|
||||
|
||||
public RegionVisitor(Region region, RegionFunction function, EditSession editSession) {
|
||||
this(region, function, editSession != null ? editSession.getQueue() : null);
|
||||
}
|
||||
|
||||
public RegionVisitor(Region region, RegionFunction function, FaweQueue queue) {
|
||||
this((Iterable<BlockVector3>) region, function, queue);
|
||||
}
|
||||
|
||||
public RegionVisitor(Iterable<? extends BlockVector3> iterable, RegionFunction function, HasFaweQueue hasQueue) {
|
||||
@Deprecated
|
||||
public RegionVisitor(Iterable<BlockVector3> iterable, RegionFunction function) {
|
||||
this.region = iterable instanceof Region ? (Region) iterable : null;
|
||||
this.function = function;
|
||||
this.iterable = iterable;
|
||||
this.queue = hasQueue != null && hasQueue.getQueue() instanceof MappedFaweQueue ? (MappedFaweQueue) hasQueue.getQueue() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,100 +68,8 @@ public class RegionVisitor implements Operation {
|
||||
|
||||
@Override
|
||||
public Operation resume(RunContext run) throws WorldEditException {
|
||||
if (queue != null && Settings.IMP.QUEUE.PRELOAD_CHUNKS > 1) {
|
||||
/*
|
||||
* The following is done to reduce iteration cost
|
||||
* - Preload chunks just in time
|
||||
* - Only check every 16th block for potential chunk loads
|
||||
* - Stop iteration on exception instead of hasNext
|
||||
* - Do not calculate the stacktrace as it is expensive
|
||||
*/
|
||||
Iterator<? extends BlockVector3> trailIter = iterable.iterator();
|
||||
Iterator<? extends BlockVector3> leadIter = iterable.iterator();
|
||||
int lastTrailChunkX = Integer.MIN_VALUE;
|
||||
int lastTrailChunkZ = Integer.MIN_VALUE;
|
||||
int lastLeadChunkX = Integer.MIN_VALUE;
|
||||
int lastLeadChunkZ = Integer.MIN_VALUE;
|
||||
int loadingTarget = Settings.IMP.QUEUE.PRELOAD_CHUNKS;
|
||||
try {
|
||||
for (; ; ) {
|
||||
BlockVector3 pt = trailIter.next();
|
||||
apply(pt);
|
||||
int cx = pt.getBlockX() >> 4;
|
||||
int cz = pt.getBlockZ() >> 4;
|
||||
if (cx != lastTrailChunkX || cz != lastTrailChunkZ) {
|
||||
lastTrailChunkX = cx;
|
||||
lastTrailChunkZ = cz;
|
||||
int amount;
|
||||
if (lastLeadChunkX == Integer.MIN_VALUE) {
|
||||
lastLeadChunkX = cx;
|
||||
lastLeadChunkZ = cz;
|
||||
amount = loadingTarget;
|
||||
} else {
|
||||
amount = 1;
|
||||
}
|
||||
for (int count = 0; count < amount; ) {
|
||||
BlockVector3 v = leadIter.next();
|
||||
int vcx = v.getBlockX() >> 4;
|
||||
int vcz = v.getBlockZ() >> 4;
|
||||
if (vcx != lastLeadChunkX || vcz != lastLeadChunkZ) {
|
||||
lastLeadChunkX = vcx;
|
||||
lastLeadChunkZ = vcz;
|
||||
queue.queueChunkLoad(vcx, vcz);
|
||||
count++;
|
||||
}
|
||||
// Skip the next 15 blocks
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
leadIter.next();
|
||||
}
|
||||
}
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
}
|
||||
} catch (FaweException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Throwable ignore) {
|
||||
ignore.printStackTrace();
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
apply(trailIter.next());
|
||||
apply(trailIter.next());
|
||||
}
|
||||
} catch (FaweException e) {
|
||||
throw new RuntimeException(e);
|
||||
} catch (Throwable ignore) {
|
||||
}
|
||||
} else {
|
||||
for (BlockVector3 pt : iterable) {
|
||||
apply(pt);
|
||||
}
|
||||
for (BlockVector3 pt : iterable) {
|
||||
apply(pt);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren