From 110f782a5cb2083691b599a1f2fd0faba2f504f3 Mon Sep 17 00:00:00 2001 From: Jesse Boyd Date: Sun, 14 Apr 2019 00:00:38 +1000 Subject: [PATCH] Optimize entity get (lazy nbt) --- .../adapter/v1_13_1/Spigot_v1_13_R2.java | 16 ++++-- .../bukkit/v1_13/BukkitChunk_1_13_Copy.java | 52 +++++++++++-------- .../sk89q/worldedit/bukkit/BukkitEntity.java | 10 ++++ .../sk89q/worldedit/bukkit/BukkitWorld.java | 3 ++ .../object/extent/FastWorldEditExtent.java | 2 + .../com/sk89q/worldedit/entity/Entity.java | 6 +++ .../worldedit/entity/LazyBaseEntity.java | 32 ++++++++++++ .../function/operation/ForwardExtentCopy.java | 17 ++++-- 8 files changed, 108 insertions(+), 30 deletions(-) create mode 100644 worldedit-core/src/main/java/com/sk89q/worldedit/entity/LazyBaseEntity.java diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/v1_13_1/Spigot_v1_13_R2.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/v1_13_1/Spigot_v1_13_R2.java index 69ef73ba6..876e79521 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/v1_13_1/Spigot_v1_13_R2.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/adapter/v1_13_1/Spigot_v1_13_R2.java @@ -29,6 +29,7 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.bukkit.adapter.CachedBukkitAdapter; import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.LazyBaseEntity; import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.registry.state.*; @@ -36,6 +37,7 @@ import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.*; +import com.sk89q.worldedit.world.entity.EntityType; import com.sk89q.worldedit.world.registry.BlockMaterial; import net.minecraft.server.v1_13_R2.*; import org.bukkit.Bukkit; @@ -57,6 +59,7 @@ import javax.annotation.Nullable; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.*; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.stream.Collectors; @@ -287,9 +290,16 @@ public final class Spigot_v1_13_R2 extends CachedBukkitAdapter implements Bukkit String id = getEntityId(mcEntity); if (id != null) { - NBTTagCompound tag = new NBTTagCompound(); - readEntityIntoTag(mcEntity, tag); - return new BaseEntity(com.sk89q.worldedit.world.entity.EntityTypes.get(id), (CompoundTag) toNative(tag)); + EntityType type = com.sk89q.worldedit.world.entity.EntityTypes.get(id); + Supplier saveTag = new Supplier() { + @Override + public CompoundTag get() { + NBTTagCompound tag = new NBTTagCompound(); + readEntityIntoTag(mcEntity, tag); + return (CompoundTag) toNative(tag); + } + }; + return new LazyBaseEntity(type, saveTag); } else { return null; } diff --git a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/BukkitChunk_1_13_Copy.java b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/BukkitChunk_1_13_Copy.java index bb6357b8e..acfeb9729 100644 --- a/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/BukkitChunk_1_13_Copy.java +++ b/worldedit-bukkit/src/main/java/com/boydti/fawe/bukkit/v1_13/BukkitChunk_1_13_Copy.java @@ -22,6 +22,9 @@ public class BukkitChunk_1_13_Copy extends BukkitChunk_1_13 { @Override public int[][] getCombinedIdArrays() { + if (this.sectionPalettes == null) { + return this.ids; + } for (int i = 0; i < ids.length; i++) { getIdArray(i); } @@ -30,36 +33,39 @@ public class BukkitChunk_1_13_Copy extends BukkitChunk_1_13 { @Override public int[] getIdArray(int layer) { - ChunkSection section = this.sectionPalettes[layer]; - int[] idsArray = this.ids[layer]; - if (section != null && idsArray == null) { - idsArray = new int[4096]; - if (!section.a()) { - try { - DataPaletteBlock blocks = section.getBlocks(); - DataBits bits = (DataBits) BukkitQueue_1_13.fieldBits.get(blocks); - DataPalette palette = (DataPalette) BukkitQueue_1_13.fieldPalette.get(blocks); + if (this.sectionPalettes != null) { + ChunkSection section = this.sectionPalettes[layer]; + int[] idsArray = this.ids[layer]; + if (section != null && idsArray == null) { + idsArray = new int[4096]; + if (!section.a()) { + try { + DataPaletteBlock blocks = section.getBlocks(); + DataBits bits = (DataBits) BukkitQueue_1_13.fieldBits.get(blocks); + DataPalette palette = (DataPalette) BukkitQueue_1_13.fieldPalette.get(blocks); - long[] raw = bits.a(); - int bitsPerEntry = bits.c(); + long[] raw = bits.a(); + int bitsPerEntry = bits.c(); - new BitArray4096(raw, bitsPerEntry).toRaw(idsArray); - IBlockData defaultBlock = (IBlockData) BukkitQueue_1_13.fieldDefaultBlock.get(blocks); - // TODO optimize away palette.a - for (int i = 0; i < 4096; i++) { - IBlockData ibd = palette.a(idsArray[i]); - if (ibd == null) { - ibd = defaultBlock; + new BitArray4096(raw, bitsPerEntry).toRaw(idsArray); + IBlockData defaultBlock = (IBlockData) BukkitQueue_1_13.fieldDefaultBlock.get(blocks); + // TODO optimize away palette.a + for (int i = 0; i < 4096; i++) { + IBlockData ibd = palette.a(idsArray[i]); + if (ibd == null) { + ibd = defaultBlock; + } + int ordinal = ((Spigot_v1_13_R2) getAdapter()).adaptToInt(ibd); + idsArray[i] = BlockTypes.states[ordinal].getInternalId(); } - int ordinal = ((Spigot_v1_13_R2) getAdapter()).adaptToInt(ibd); - idsArray[i] = BlockTypes.states[ordinal].getInternalId(); + } catch (IllegalAccessException e) { + e.printStackTrace(); } - } catch (IllegalAccessException e) { - e.printStackTrace(); } } + return idsArray; } - return idsArray; + return null; } @Override diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java index a5c7b0a60..5ac3b1893 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitEntity.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.bukkit; import static com.google.common.base.Preconditions.checkNotNull; +import com.boydti.fawe.util.TaskManager; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; @@ -29,6 +30,8 @@ import com.sk89q.worldedit.entity.metadata.EntityProperties; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.NullWorld; +import com.sk89q.worldedit.world.entity.EntityTypes; +import org.bukkit.entity.EntityType; import java.lang.ref.WeakReference; @@ -40,6 +43,7 @@ import javax.annotation.Nullable; public class BukkitEntity implements Entity { private final WeakReference entityRef; + private final EntityType type; /** * Create a new instance. @@ -48,6 +52,7 @@ public class BukkitEntity implements Entity { */ public BukkitEntity(org.bukkit.entity.Entity entity) { checkNotNull(entity); + this.type = entity.getType(); this.entityRef = new WeakReference<>(entity); } @@ -81,6 +86,11 @@ public class BukkitEntity implements Entity { } } + @Override + public com.sk89q.worldedit.world.entity.EntityType getType() { + return EntityTypes.get(type.getName().toUpperCase()); + } + @Override public BaseEntity getState() { org.bukkit.entity.Entity entity = entityRef.get(); diff --git a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index ca94366da..022129fd5 100644 --- a/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -18,6 +18,7 @@ package com.sk89q.worldedit.bukkit; +import com.boydti.fawe.Fawe; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEditException; @@ -82,6 +83,7 @@ public class BukkitWorld extends AbstractWorld { @Override public List getEntities(Region region) { + System.out.println(Fawe.isMainThread()); World world = getWorld(); List ents = world.getEntities(); @@ -96,6 +98,7 @@ public class BukkitWorld extends AbstractWorld { @Override public List getEntities() { + System.out.println(Fawe.isMainThread()); List list = new ArrayList<>(); for (Entity entity : getWorld().getEntities()) { list.add(BukkitAdapter.adapt(entity)); diff --git a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java index e8853dda8..0bcbfe182 100644 --- a/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java +++ b/worldedit-core/src/main/java/com/boydti/fawe/object/extent/FastWorldEditExtent.java @@ -149,11 +149,13 @@ public class FastWorldEditExtent extends AbstractDelegateExtent implements HasFa @Override public List getEntities() { + System.out.println("World cp * " + world + " | " + world.getClass()); return world.getEntities(); } @Override public List getEntities(final Region region) { + System.out.println("World cp rg " + world + " | " + world.getClass()); return world.getEntities(region); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java index 31bff6968..23544ea30 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/Entity.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.entity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.util.Faceted; import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.entity.EntityType; import javax.annotation.Nullable; @@ -62,6 +63,11 @@ public interface Entity extends Faceted { */ boolean setLocation(Location location); + default EntityType getType() { + BaseEntity state = getState(); + return state != null ? state.getType() : null; + } + /** * Get the extent that this entity is on. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/entity/LazyBaseEntity.java b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/LazyBaseEntity.java new file mode 100644 index 000000000..ff34d8627 --- /dev/null +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/entity/LazyBaseEntity.java @@ -0,0 +1,32 @@ +package com.sk89q.worldedit.entity; + +import com.boydti.fawe.Fawe; +import com.boydti.fawe.util.TaskManager; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.world.entity.EntityType; + +import javax.annotation.Nullable; +import java.util.function.Supplier; + +public class LazyBaseEntity extends BaseEntity { + private Supplier saveTag; + public LazyBaseEntity(EntityType type, Supplier saveTag) { + super(type, null); + this.saveTag = saveTag; + } + + @Nullable + @Override + public CompoundTag getNbtData() { + Supplier tmp = saveTag; + if (tmp != null) { + saveTag = null; + if (Fawe.isMainThread()) { + setNbtData(tmp.get()); + } else { + setNbtData(TaskManager.IMP.sync(tmp)); + } + } + return super.getNbtData(); + } +} diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java index d22285d22..e1a276736 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/function/operation/ForwardExtentCopy.java @@ -27,12 +27,14 @@ import com.boydti.fawe.object.function.block.BiomeCopy; import com.boydti.fawe.object.function.block.CombinedBlockCopy; import com.boydti.fawe.object.function.block.SimpleBlockCopy; import com.boydti.fawe.util.MaskTraverser; +import com.google.common.base.Predicate; import com.sk89q.worldedit.EditSession; import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import com.google.common.collect.Lists; import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.extent.clipboard.BlockArrayClipboard; @@ -52,6 +54,9 @@ import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.transform.Identity; import com.sk89q.worldedit.math.transform.Transform; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.world.entity.EntityTypes; + +import javax.annotation.Nullable; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -353,11 +358,15 @@ public class ForwardExtentCopy implements Operation { List entities; if (isCopyingEntities()) { // filter players since they can't be copied - entities = source.getEntities() + entities = source.getEntities(region) .stream() - .filter(entity -> entity.getState() != null && - !entity.getState().getType().getId().equals("minecraft:player") && - region.contains(entity.getLocation().toBlockPoint())) + .filter(new Predicate() { + @Override + public boolean apply(@Nullable Entity input) { + BaseEntity state = input.getState(); + return state != null && state.getType() != EntityTypes.PLAYER; + } + }) .collect(Collectors.toList()); } else { entities = new ArrayList<>();