geforkt von Mirrors/FastAsyncWorldEdit
Some refactoring
Dieser Commit ist enthalten in:
Ursprung
f5944fbcaf
Commit
4116adcfef
@ -2,16 +2,14 @@ package com.boydti.fawe.bukkit.beta;
|
|||||||
|
|
||||||
import com.boydti.fawe.Fawe;
|
import com.boydti.fawe.Fawe;
|
||||||
import com.boydti.fawe.beta.Filter;
|
import com.boydti.fawe.beta.Filter;
|
||||||
import com.boydti.fawe.beta.IChunk;
|
|
||||||
import com.boydti.fawe.beta.IGetBlocks;
|
import com.boydti.fawe.beta.IGetBlocks;
|
||||||
import com.boydti.fawe.beta.IQueueExtent;
|
import com.boydti.fawe.beta.IQueueExtent;
|
||||||
|
import com.boydti.fawe.beta.ISetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.QueueHandler;
|
import com.boydti.fawe.beta.implementation.QueueHandler;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.holder.ChunkHolder;
|
import com.boydti.fawe.beta.implementation.holder.ChunkHolder;
|
||||||
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
import com.boydti.fawe.bukkit.v0.BukkitQueue_0;
|
||||||
import com.boydti.fawe.bukkit.v1_13.BukkitQueue_1_13;
|
import com.boydti.fawe.bukkit.v1_13.BukkitQueue_1_13;
|
||||||
import com.boydti.fawe.util.ReflectionUtils;
|
import com.boydti.fawe.util.ReflectionUtils;
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.jnbt.ListTag;
|
import com.sk89q.jnbt.ListTag;
|
||||||
import com.sk89q.jnbt.LongTag;
|
import com.sk89q.jnbt.LongTag;
|
||||||
@ -20,8 +18,6 @@ import com.sk89q.jnbt.Tag;
|
|||||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
import com.sk89q.worldedit.bukkit.BukkitAdapter;
|
||||||
import com.sk89q.worldedit.internal.Constants;
|
import com.sk89q.worldedit.internal.Constants;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
|
||||||
import net.jpountz.util.UnsafeUtils;
|
|
||||||
import net.minecraft.server.v1_13_R2.BiomeBase;
|
import net.minecraft.server.v1_13_R2.BiomeBase;
|
||||||
import net.minecraft.server.v1_13_R2.BlockPosition;
|
import net.minecraft.server.v1_13_R2.BlockPosition;
|
||||||
import net.minecraft.server.v1_13_R2.Chunk;
|
import net.minecraft.server.v1_13_R2.Chunk;
|
||||||
@ -37,18 +33,14 @@ import org.bukkit.block.Biome;
|
|||||||
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
|
import org.bukkit.craftbukkit.v1_13_R2.block.CraftBlock;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
|
||||||
|
|
||||||
public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
||||||
@Override
|
@Override
|
||||||
@ -86,7 +78,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
int Z = getZ();
|
int Z = getZ();
|
||||||
BukkitQueue extent = (BukkitQueue) getExtent();
|
BukkitQueue extent = (BukkitQueue) getExtent();
|
||||||
BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet();
|
BukkitGetBlocks get = (BukkitGetBlocks) getOrCreateGet();
|
||||||
CharSetBlocks set = (CharSetBlocks) getOrCreateSet();
|
ISetBlocks set = getOrCreateSet();
|
||||||
|
|
||||||
Chunk nmsChunk = extent.ensureLoaded(X, Z);
|
Chunk nmsChunk = extent.ensureLoaded(X, Z);
|
||||||
|
|
||||||
@ -102,12 +94,10 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
final int ly = pos.getY();
|
final int ly = pos.getY();
|
||||||
final int lz = pos.getZ() & 15;
|
final int lz = pos.getZ() & 15;
|
||||||
final int layer = ly >> 4;
|
final int layer = ly >> 4;
|
||||||
final char[] array = set.blocks[layer];
|
if (!set.hasSection(layer)) {
|
||||||
if (array == null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final int index = (((ly & 0xF) << 8) | (lz << 4) | lx);
|
if (set.getBlock(lx, ly, lz).getOrdinal() != 0) {
|
||||||
if (array[index] != 0) {
|
|
||||||
TileEntity tile = entry.getValue();
|
TileEntity tile = entry.getValue();
|
||||||
tile.z();
|
tile.z();
|
||||||
tile.invalidateBlockCache();
|
tile.invalidateBlockCache();
|
||||||
@ -116,7 +106,6 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bitMask = 0;
|
int bitMask = 0;
|
||||||
synchronized (nmsChunk) {
|
synchronized (nmsChunk) {
|
||||||
ChunkSection[] sections = nmsChunk.getSections();
|
ChunkSection[] sections = nmsChunk.getSections();
|
||||||
@ -128,7 +117,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
|
|
||||||
bitMask |= 1 << layer;
|
bitMask |= 1 << layer;
|
||||||
|
|
||||||
char[] setArr = set.blocks[layer];
|
char[] setArr = set.getArray(layer);
|
||||||
ChunkSection newSection;
|
ChunkSection newSection;
|
||||||
ChunkSection existingSection = sections[layer];
|
ChunkSection existingSection = sections[layer];
|
||||||
if (existingSection == null) {
|
if (existingSection == null) {
|
||||||
@ -182,11 +171,12 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Biomes
|
// Biomes
|
||||||
if (set.biomes != null) {
|
BiomeType[] biomes = set.getBiomes();
|
||||||
|
if (biomes != null) {
|
||||||
// set biomes
|
// set biomes
|
||||||
final BiomeBase[] currentBiomes = nmsChunk.getBiomeIndex();
|
final BiomeBase[] currentBiomes = nmsChunk.getBiomeIndex();
|
||||||
for (int i = 0; i < set.biomes.length; i++) {
|
for (int i = 0; i < biomes.length; i++) {
|
||||||
final BiomeType biome = set.biomes[i];
|
final BiomeType biome = biomes[i];
|
||||||
if (biome != null) {
|
if (biome != null) {
|
||||||
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
final Biome craftBiome = BukkitAdapter.adapt(biome);
|
||||||
currentBiomes[i] = CraftBlock.biomeToBiomeBase(craftBiome);
|
currentBiomes[i] = CraftBlock.biomeToBiomeBase(craftBiome);
|
||||||
@ -200,11 +190,10 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
int bx = X << 4;
|
int bx = X << 4;
|
||||||
int bz = Z << 4;
|
int bz = Z << 4;
|
||||||
|
|
||||||
if (set.entityRemoves != null && !set.entityRemoves.isEmpty()) {
|
Set<UUID> entityRemoves = set.getEntityRemoves();
|
||||||
|
if (entityRemoves != null && !entityRemoves.isEmpty()) {
|
||||||
if (syncTasks == null) syncTasks = new Runnable[3];
|
if (syncTasks == null) syncTasks = new Runnable[3];
|
||||||
|
|
||||||
HashSet<UUID> entsToRemove = set.entityRemoves;
|
|
||||||
|
|
||||||
syncTasks[2] = new Runnable() {
|
syncTasks[2] = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -216,7 +205,7 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
final Iterator<Entity> iter = ents.iterator();
|
final Iterator<Entity> iter = ents.iterator();
|
||||||
while (iter.hasNext()) {
|
while (iter.hasNext()) {
|
||||||
final Entity entity = iter.next();
|
final Entity entity = iter.next();
|
||||||
if (entsToRemove.contains(entity.getUniqueID())) {
|
if (entityRemoves.contains(entity.getUniqueID())) {
|
||||||
iter.remove();
|
iter.remove();
|
||||||
entity.b(false);
|
entity.b(false);
|
||||||
entity.die();
|
entity.die();
|
||||||
@ -229,15 +218,14 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (set.entities != null && !set.entities.isEmpty()) {
|
Set<CompoundTag> entities = set.getEntities();
|
||||||
|
if (entities != null && !entities.isEmpty()) {
|
||||||
if (syncTasks == null) syncTasks = new Runnable[2];
|
if (syncTasks == null) syncTasks = new Runnable[2];
|
||||||
|
|
||||||
HashSet<CompoundTag> entitiesToSpawn = set.entities;
|
|
||||||
|
|
||||||
syncTasks[1] = new Runnable() {
|
syncTasks[1] = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for (final CompoundTag nativeTag : entitiesToSpawn) {
|
for (final CompoundTag nativeTag : entities) {
|
||||||
final Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
|
final Map<String, Tag> entityTagMap = ReflectionUtils.getMap(nativeTag.getValue());
|
||||||
final StringTag idTag = (StringTag) entityTagMap.get("Id");
|
final StringTag idTag = (StringTag) entityTagMap.get("Id");
|
||||||
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
|
final ListTag posTag = (ListTag) entityTagMap.get("Pos");
|
||||||
@ -274,10 +262,10 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set tiles
|
// set tiles
|
||||||
if (set.tiles != null && !set.tiles.isEmpty()) {
|
Map<Short, CompoundTag> tiles = set.getTiles();
|
||||||
|
if (tiles != null && !tiles.isEmpty()) {
|
||||||
if (syncTasks == null) syncTasks = new Runnable[1];
|
if (syncTasks == null) syncTasks = new Runnable[1];
|
||||||
|
|
||||||
HashMap<Short, CompoundTag> tiles = set.tiles;
|
|
||||||
syncTasks[0] = new Runnable() {
|
syncTasks[0] = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@ -307,19 +295,22 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
int finalMask = bitMask;
|
Runnable callback;
|
||||||
Runnable callback = () -> {
|
if (bitMask == 0) {
|
||||||
if (finalMask != 0) {
|
callback = null;
|
||||||
|
} else {
|
||||||
|
int finalMask = bitMask;
|
||||||
|
callback = () -> {
|
||||||
// Set Modified
|
// Set Modified
|
||||||
nmsChunk.f(true);
|
nmsChunk.f(true);
|
||||||
nmsChunk.mustSave = true;
|
nmsChunk.mustSave = true;
|
||||||
nmsChunk.markDirty();
|
nmsChunk.markDirty();
|
||||||
// send to player
|
// send to player
|
||||||
extent.sendChunk(X, Z, finalMask);
|
extent.sendChunk(X, Z, finalMask);
|
||||||
}
|
|
||||||
|
|
||||||
extent.returnToPool(BukkitChunkHolder.this);
|
extent.returnToPool(BukkitChunkHolder.this);
|
||||||
};
|
};
|
||||||
|
}
|
||||||
if (syncTasks != null) {
|
if (syncTasks != null) {
|
||||||
QueueHandler queueHandler = Fawe.get().getQueueHandler();
|
QueueHandler queueHandler = Fawe.get().getQueueHandler();
|
||||||
Runnable[] finalSyncTasks = syncTasks;
|
Runnable[] finalSyncTasks = syncTasks;
|
||||||
@ -335,12 +326,21 @@ public class BukkitChunkHolder<T extends Future<T>> extends ChunkHolder {
|
|||||||
task.run();
|
task.run();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return queueHandler.async(callback, null);
|
if (callback == null) {
|
||||||
|
extent.returnToPool(BukkitChunkHolder.this);
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return queueHandler.async(callback, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (T) (Future) queueHandler.sync(chain);
|
return (T) (Future) queueHandler.sync(chain);
|
||||||
} else {
|
} else {
|
||||||
callback.run();
|
if (callback == null) {
|
||||||
|
extent.returnToPool(BukkitChunkHolder.this);
|
||||||
|
} else {
|
||||||
|
callback.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.boydti.fawe.beta;
|
package com.boydti.fawe.beta;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -14,7 +13,8 @@ import static com.sk89q.worldedit.world.block.BlockTypes.states;
|
|||||||
public class CharFilterBlock implements FilterBlock {
|
public class CharFilterBlock implements FilterBlock {
|
||||||
private IQueueExtent queue;
|
private IQueueExtent queue;
|
||||||
private CharGetBlocks get;
|
private CharGetBlocks get;
|
||||||
private CharSetBlocks set;
|
|
||||||
|
private ISetBlocks set;
|
||||||
|
|
||||||
private char[] getArr;
|
private char[] getArr;
|
||||||
private @Nullable char[] setArr;
|
private @Nullable char[] setArr;
|
||||||
@ -39,28 +39,26 @@ public class CharFilterBlock implements FilterBlock {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final Filter filter) {
|
@Override
|
||||||
final CharSetBlocks set = (CharSetBlocks) iset;
|
public final void filter(final IGetBlocks iget, final ISetBlocks iset, final int layer, final Filter filter) {
|
||||||
|
this.layer = layer;
|
||||||
final CharGetBlocks get = (CharGetBlocks) iget;
|
final CharGetBlocks get = (CharGetBlocks) iget;
|
||||||
for (int layer = 0; layer < 16; layer++) {
|
if (!get.hasSection(layer)) return;
|
||||||
if (!get.hasSection(layer)) continue;
|
this.set = iset;
|
||||||
this.set = set;
|
getArr = get.sections[layer].get(get, layer);
|
||||||
getArr = get.sections[layer].get(get, layer);
|
if (set.hasSection(layer)) {
|
||||||
if (set.hasSection(layer)) {
|
setArr = set.getArray(layer);
|
||||||
setArr = set.blocks[layer];
|
delegate = FULL;
|
||||||
delegate = FULL;
|
} else {
|
||||||
} else {
|
delegate = NULL;
|
||||||
delegate = NULL;
|
setArr = null;
|
||||||
setArr = null;
|
}
|
||||||
}
|
this.yy = layer << 4;
|
||||||
this.layer = layer;
|
|
||||||
this.yy = layer << 4;
|
|
||||||
|
|
||||||
for (y = 0, index = 0; y < 16; y++) {
|
for (y = 0, index = 0; y < 16; y++) {
|
||||||
for (z = 0; z < 16; z++) {
|
for (z = 0; z < 16; z++) {
|
||||||
for (x = 0; x < 16; x++, index++) {
|
for (x = 0; x < 16; x++, index++) {
|
||||||
filter.applyBlock(this);
|
filter.applyBlock(this);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -305,7 +303,7 @@ public class CharFilterBlock implements FilterBlock {
|
|||||||
Set delegate
|
Set delegate
|
||||||
*/
|
*/
|
||||||
private SetDelegate initSet() {
|
private SetDelegate initSet() {
|
||||||
setArr = set.sections[layer].get(set, layer);
|
setArr = set.getArray(layer);
|
||||||
return delegate = FULL;
|
return delegate = FULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public interface Filter {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
default void join(final Filter parent) {
|
default void join() {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
package com.boydti.fawe.beta;
|
package com.boydti.fawe.beta;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharGetBlocks;
|
|
||||||
import com.boydti.fawe.beta.implementation.blocks.CharSetBlocks;
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.block.BaseBlock;
|
import com.sk89q.worldedit.world.block.BaseBlock;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
@ -11,7 +9,7 @@ public interface FilterBlock {
|
|||||||
|
|
||||||
FilterBlock init(int X, int Z, IGetBlocks chunk);
|
FilterBlock init(int X, int Z, IGetBlocks chunk);
|
||||||
|
|
||||||
void filter(IGetBlocks get, ISetBlocks set, Filter filter);
|
void filter(IGetBlocks get, ISetBlocks set, int layer, Filter filter);
|
||||||
|
|
||||||
void setOrdinal(int ordinal);
|
void setOrdinal(int ordinal);
|
||||||
|
|
||||||
|
@ -27,8 +27,6 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T> {
|
|||||||
|
|
||||||
int getZ();
|
int getZ();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If the chunk is a delegate, returns it's paren'ts root
|
* If the chunk is a delegate, returns it's paren'ts root
|
||||||
* @return root IChunk
|
* @return root IChunk
|
||||||
@ -42,14 +40,6 @@ public interface IChunk<T extends Future<T>> extends Trimable, Callable<T> {
|
|||||||
*/
|
*/
|
||||||
boolean isEmpty();
|
boolean isEmpty();
|
||||||
|
|
||||||
/**
|
|
||||||
* Spend time optimizing for apply<br>
|
|
||||||
* default behavior: do nothing
|
|
||||||
*/
|
|
||||||
default void optimize() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the queued changes to the world<br>
|
* Apply the queued changes to the world<br>
|
||||||
* The future returned may return another future<br>
|
* The future returned may return another future<br>
|
||||||
|
@ -2,9 +2,13 @@ package com.boydti.fawe.beta;
|
|||||||
|
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,4 +30,19 @@ public interface ISetBlocks extends IBlocks {
|
|||||||
default void optimize() {
|
default void optimize() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BlockState getBlock(int x, int y, int z);
|
||||||
|
|
||||||
|
char[] getArray(int layer);
|
||||||
|
|
||||||
|
BiomeType[] getBiomes();
|
||||||
|
|
||||||
|
Map<Short, CompoundTag> getTiles();
|
||||||
|
|
||||||
|
Set<CompoundTag> getEntities();
|
||||||
|
|
||||||
|
Set<UUID> getEntityRemoves();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void reset();
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package com.boydti.fawe.beta.filters;
|
package com.boydti.fawe.beta.filters;
|
||||||
|
|
||||||
import com.boydti.fawe.beta.Filter;
|
|
||||||
import com.boydti.fawe.beta.FilterBlock;
|
import com.boydti.fawe.beta.FilterBlock;
|
||||||
import com.boydti.fawe.config.BBC;
|
import com.boydti.fawe.config.BBC;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
@ -12,11 +11,35 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class CountFilter implements Filter {
|
public class CountFilter extends ForkedFilter<CountFilter> {
|
||||||
private final int[] counter = new int[BlockTypes.states.length];
|
private final int[] counter = new int[BlockTypes.states.length];
|
||||||
|
|
||||||
|
public CountFilter() {
|
||||||
|
super(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private CountFilter(CountFilter root) {
|
||||||
|
super(root);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void applyBlock(final FilterBlock block) {
|
public CountFilter init() {
|
||||||
|
return new CountFilter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void join(CountFilter filter) {
|
||||||
|
for (int i = 0; i < filter.counter.length; i++) {
|
||||||
|
this.counter[i] += filter.counter[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void applyBlock(final FilterBlock block) {
|
||||||
counter[block.getOrdinal()]++;
|
counter[block.getOrdinal()]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,17 +65,4 @@ public class CountFilter implements Filter {
|
|||||||
actor.print(BBC.getPrefix() + str);
|
actor.print(BBC.getPrefix() + str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Filter fork() {
|
|
||||||
return new CountFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void join(final Filter parent) {
|
|
||||||
final CountFilter other = (CountFilter) parent;
|
|
||||||
for (int i = 0; i < counter.length; i++) {
|
|
||||||
other.counter[i] += this.counter[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.boydti.fawe.beta.filters;
|
||||||
|
|
||||||
|
import com.boydti.fawe.beta.Filter;
|
||||||
|
import com.boydti.fawe.beta.FilterBlock;
|
||||||
|
import com.boydti.fawe.config.BBC;
|
||||||
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.util.Countable;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public abstract class ForkedFilter<T extends ForkedFilter<T>> implements Filter {
|
||||||
|
protected final Map<Thread, T> children;
|
||||||
|
|
||||||
|
public ForkedFilter(T root) {
|
||||||
|
if (root != null) {
|
||||||
|
children = root.children;
|
||||||
|
} else {
|
||||||
|
children = new ConcurrentHashMap<>();
|
||||||
|
children.put(Thread.currentThread(), (T) this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final Filter fork() {
|
||||||
|
return children.computeIfAbsent(Thread.currentThread(), thread -> init());
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T init();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void join() {
|
||||||
|
for (Map.Entry<Thread, T> entry : children.entrySet()) {
|
||||||
|
T filter = entry.getValue();
|
||||||
|
if (filter != this) {
|
||||||
|
join(filter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
children.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract void join(T filter);
|
||||||
|
}
|
@ -12,7 +12,6 @@ import com.boydti.fawe.object.collection.IterableThreadLocal;
|
|||||||
import com.boydti.fawe.util.MemUtil;
|
import com.boydti.fawe.util.MemUtil;
|
||||||
import com.boydti.fawe.util.TaskManager;
|
import com.boydti.fawe.util.TaskManager;
|
||||||
import com.boydti.fawe.wrappers.WorldWrapper;
|
import com.boydti.fawe.wrappers.WorldWrapper;
|
||||||
import com.google.common.util.concurrent.Futures;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.regions.Region;
|
import com.sk89q.worldedit.regions.Region;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
@ -24,7 +23,6 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.Callable;
|
import java.util.concurrent.Callable;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import java.util.concurrent.ExecutorService;
|
|
||||||
import java.util.concurrent.ForkJoinPool;
|
import java.util.concurrent.ForkJoinPool;
|
||||||
import java.util.concurrent.ForkJoinTask;
|
import java.util.concurrent.ForkJoinTask;
|
||||||
import java.util.concurrent.Future;
|
import java.util.concurrent.Future;
|
||||||
@ -163,40 +161,30 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
synchronized (queue) {
|
synchronized (queue) {
|
||||||
FilterBlock block = null;
|
FilterBlock block = null;
|
||||||
|
|
||||||
try {
|
while (true) {
|
||||||
while (true) {
|
// Get the next chunk pos
|
||||||
// Get the next chunk pos
|
final int X, Z;
|
||||||
final int X, Z;
|
synchronized (chunksIter) {
|
||||||
synchronized (chunksIter) {
|
if (!chunksIter.hasNext()) break;
|
||||||
if (!chunksIter.hasNext()) break;
|
final BlockVector2 pos = chunksIter.next();
|
||||||
final BlockVector2 pos = chunksIter.next();
|
X = pos.getX();
|
||||||
X = pos.getX();
|
Z = pos.getZ();
|
||||||
Z = pos.getZ();
|
|
||||||
}
|
|
||||||
IChunk chunk = queue.getCachedChunk(X, Z);
|
|
||||||
// Initialize
|
|
||||||
chunk.init(queue, X, Z);
|
|
||||||
|
|
||||||
if (!newFilter.appliesChunk(X, Z)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
chunk = newFilter.applyChunk(chunk);
|
|
||||||
|
|
||||||
if (chunk == null) continue;
|
|
||||||
|
|
||||||
if (block == null) block = queue.initFilterBlock();
|
|
||||||
chunk.filter(newFilter, block);
|
|
||||||
|
|
||||||
newFilter.finishChunk(chunk);
|
|
||||||
|
|
||||||
queue.submit(chunk);
|
|
||||||
}
|
}
|
||||||
} finally {
|
IChunk chunk = queue.getCachedChunk(X, Z);
|
||||||
if (filter != newFilter) {
|
// Initialize
|
||||||
synchronized (filter) {
|
chunk.init(queue, X, Z);
|
||||||
newFilter.join(filter);
|
|
||||||
}
|
if (!newFilter.appliesChunk(X, Z)) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
chunk = newFilter.applyChunk(chunk);
|
||||||
|
|
||||||
|
if (chunk == null) continue;
|
||||||
|
|
||||||
|
if (block == null) block = queue.initFilterBlock();
|
||||||
|
chunk.filter(newFilter, block);
|
||||||
|
|
||||||
|
queue.submit(chunk);
|
||||||
}
|
}
|
||||||
queue.flush();
|
queue.flush();
|
||||||
}
|
}
|
||||||
@ -210,5 +198,6 @@ public abstract class QueueHandler implements Trimable, Runnable {
|
|||||||
task.quietlyJoin();
|
task.quietlyJoin();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
filter.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,10 +4,14 @@ import com.boydti.fawe.beta.ISetBlocks;
|
|||||||
import com.boydti.fawe.util.MathMan;
|
import com.boydti.fawe.util.MathMan;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class CharSetBlocks extends CharBlocks implements ISetBlocks {
|
public class CharSetBlocks extends CharBlocks implements ISetBlocks {
|
||||||
@ -16,6 +20,31 @@ public class CharSetBlocks extends CharBlocks implements ISetBlocks {
|
|||||||
public HashSet<CompoundTag> entities;
|
public HashSet<CompoundTag> entities;
|
||||||
public HashSet<UUID> entityRemoves;
|
public HashSet<UUID> entityRemoves;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getArray(int layer) {
|
||||||
|
return sections[layer].get(this, layer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BiomeType[] getBiomes() {
|
||||||
|
return biomes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<Short, CompoundTag> getTiles() {
|
||||||
|
return tiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<CompoundTag> getEntities() {
|
||||||
|
return entities;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<UUID> getEntityRemoves() {
|
||||||
|
return entityRemoves;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
|
public boolean setBiome(final int x, final int y, final int z, final BiomeType biome) {
|
||||||
if (biomes == null) {
|
if (biomes == null) {
|
||||||
@ -25,6 +54,11 @@ public class CharSetBlocks extends CharBlocks implements ISetBlocks {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState getBlock(int x, int y, int z) {
|
||||||
|
return BlockTypes.states[get(x, y, z)];
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder holder) {
|
public boolean setBlock(final int x, final int y, final int z, final BlockStateHolder holder) {
|
||||||
set(x, y, z, holder.getOrdinalChar());
|
set(x, y, z, holder.getOrdinalChar());
|
||||||
|
@ -1,24 +0,0 @@
|
|||||||
package com.boydti.fawe.beta.implementation.blocks;
|
|
||||||
|
|
||||||
import com.boydti.fawe.beta.IBlocks;
|
|
||||||
|
|
||||||
// TODO implement
|
|
||||||
public class FullCharBlocks implements IBlocks {
|
|
||||||
public final boolean[] hasSections = new boolean[16];
|
|
||||||
public final char[] blocks = new char[65536];
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasSection(final int layer) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void reset() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean trim(final boolean aggressive) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -40,7 +40,11 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
|
|||||||
final IGetBlocks get = getOrCreateGet();
|
final IGetBlocks get = getOrCreateGet();
|
||||||
final ISetBlocks set = getOrCreateSet();
|
final ISetBlocks set = getOrCreateSet();
|
||||||
block = block.init(X, Z, get);
|
block = block.init(X, Z, get);
|
||||||
block.filter(get, set, filter);
|
for (int layer = 0; layer < 16; layer++) {
|
||||||
|
if (!get.hasSection(layer)) continue;
|
||||||
|
block.filter(get, set, layer, filter);
|
||||||
|
}
|
||||||
|
filter.finishChunk(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -94,12 +98,12 @@ public abstract class ChunkHolder implements IChunk, Supplier<IGetBlocks> {
|
|||||||
return get();
|
return get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
public void optimize() {
|
// public void optimize() {
|
||||||
if (set != null) {
|
// if (set != null) {
|
||||||
set.optimize();
|
// set.optimize();
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(final IQueueExtent extent, final int X, final int Z) {
|
public void init(final IQueueExtent extent, final int X, final int Z) {
|
||||||
|
@ -11,8 +11,7 @@ import java.util.Iterator;
|
|||||||
import java.util.concurrent.ConcurrentLinkedDeque;
|
import java.util.concurrent.ConcurrentLinkedDeque;
|
||||||
|
|
||||||
public abstract class IterableThreadLocal<T> extends ThreadLocal<T> implements Iterable<T> {
|
public abstract class IterableThreadLocal<T> extends ThreadLocal<T> implements Iterable<T> {
|
||||||
private ThreadLocal<T> flag;
|
private final ConcurrentLinkedDeque<T> allValues = new ConcurrentLinkedDeque<>();
|
||||||
private ConcurrentLinkedDeque<T> allValues = new ConcurrentLinkedDeque<>();
|
|
||||||
|
|
||||||
public IterableThreadLocal() {
|
public IterableThreadLocal() {
|
||||||
}
|
}
|
||||||
@ -21,7 +20,9 @@ public abstract class IterableThreadLocal<T> extends ThreadLocal<T> implements I
|
|||||||
protected final T initialValue() {
|
protected final T initialValue() {
|
||||||
T value = init();
|
T value = init();
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
allValues.add(value);
|
synchronized (this) {
|
||||||
|
allValues.add(value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -36,7 +37,12 @@ public abstract class IterableThreadLocal<T> extends ThreadLocal<T> implements I
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clean() {
|
public void clean() {
|
||||||
IterableThreadLocal.clean(this);
|
if (!allValues.isEmpty()) {
|
||||||
|
synchronized (this) {
|
||||||
|
IterableThreadLocal.clean(this);
|
||||||
|
allValues.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void clean(ThreadLocal instance) {
|
public static void clean(ThreadLocal instance) {
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren