From 300065712530a8a2fde0094a186296a828622e4c Mon Sep 17 00:00:00 2001 From: JayemCeekay Date: Sun, 16 Apr 2023 13:47:31 -0500 Subject: [PATCH] Introduce DataArray --- .../kotlin/buildlogic.common-java.gradle.kts | 2 +- .../main/kotlin/buildlogic.common.gradle.kts | 2 +- .../ext/fawe/v1_20_R2/PaperweightAdapter.java | 3 +- .../v1_20_R2/PaperweightDataConverters.java | 2 +- .../PaperweightWorldNativeAccess.java | 2 +- .../fawe/v1_20_R2/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_20_R2/PaperweightGetBlocks.java | 53 ++++----- .../v1_20_R2/PaperweightGetBlocks_Copy.java | 19 ++-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_20_R2/PaperweightPlatformAdapter.java | 7 +- .../v1_20_R2/PaperweightPostProcessor.java | 64 ++--------- .../ext/fawe/v1_20_R3/PaperweightAdapter.java | 2 +- .../v1_20_R3/PaperweightDataConverters.java | 2 +- .../PaperweightWorldNativeAccess.java | 2 +- .../fawe/v1_20_R3/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_20_R3/PaperweightGetBlocks.java | 53 ++++----- .../v1_20_R3/PaperweightGetBlocks_Copy.java | 19 ++-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_20_R3/PaperweightPlatformAdapter.java | 7 +- .../v1_20_R3/PaperweightPostProcessor.java | 79 ++----------- .../ext.fawe/v1_20_R4/PaperweightAdapter.java | 3 +- .../v1_20_R4/PaperweightDataConverters.java | 2 +- .../PaperweightWorldNativeAccess.java | 4 +- .../fawe/v1_20_R4/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_20_R4/PaperweightGetBlocks.java | 53 ++++----- .../v1_20_R4/PaperweightGetBlocks_Copy.java | 19 ++-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_20_R4/PaperweightPlatformAdapter.java | 7 +- .../v1_20_R4/PaperweightPostProcessor.java | 79 ++----------- .../ext/fawe/v1_21_R1/PaperweightAdapter.java | 1 + .../fawe/v1_21_R1/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_R1/PaperweightGetBlocks.java | 53 ++++----- .../v1_21_R1/PaperweightGetBlocks_Copy.java | 19 ++-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_R1/PaperweightPlatformAdapter.java | 7 +- .../v1_21_R1/PaperweightPostProcessor.java | 79 ++----------- .../fawe/v1_21_11/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_11/PaperweightGetBlocks.java | 46 +++----- .../v1_21_11/PaperweightGetBlocks_Copy.java | 22 ++-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_11/PaperweightPlatformAdapter.java | 7 +- .../v1_21_11/PaperweightPostProcessor.java | 79 ++----------- .../fawe/v1_21_4/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_4/PaperweightGetBlocks.java | 46 +++----- .../v1_21_4/PaperweightGetBlocks_Copy.java | 18 +-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_4/PaperweightPlatformAdapter.java | 7 +- .../v1_21_4/PaperweightPostProcessor.java | 75 ++----------- .../fawe/v1_21_5/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_5/PaperweightGetBlocks.java | 46 +++----- .../v1_21_5/PaperweightGetBlocks_Copy.java | 18 +-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_5/PaperweightPlatformAdapter.java | 7 +- .../v1_21_5/PaperweightPostProcessor.java | 79 ++----------- .../fawe/v1_21_6/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_6/PaperweightGetBlocks.java | 44 +++----- .../v1_21_6/PaperweightGetBlocks_Copy.java | 18 +-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_6/PaperweightPlatformAdapter.java | 7 +- .../v1_21_6/PaperweightPostProcessor.java | 74 ++---------- .../fawe/v1_21_9/PaperweightFaweAdapter.java | 18 +-- .../fawe/v1_21_9/PaperweightGetBlocks.java | 45 ++++---- .../v1_21_9/PaperweightGetBlocks_Copy.java | 18 +-- .../PaperweightPlacementStateProcessor.java | 4 +- .../v1_21_9/PaperweightPlatformAdapter.java | 7 +- .../v1_21_9/PaperweightPostProcessor.java | 79 ++----------- worldedit-bukkit/build.gradle.kts | 4 +- .../adapter/AbstractBukkitGetBlocks.java | 4 +- .../bukkit/adapter/FaweAdapter.java | 20 ++-- .../bukkit/adapter/NMSAdapter.java | 21 ++-- .../bukkit/adapter/PostProcessor.java | 78 +++++++++++++ .../fastasyncworldedit/core/FaweCache.java | 105 ++++++------------ .../core/extent/DisallowedBlocksExtent.java | 17 +-- .../clipboard/io/FastSchematicReaderV2.java | 12 +- .../clipboard/io/FastSchematicReaderV3.java | 7 +- .../core/extent/filter/CountFilter.java | 2 +- .../core/extent/filter/LinkedFilter.java | 4 +- .../core/extent/filter/MaskFilter.java | 19 ++-- ...erBlock.java => DataArrayFilterBlock.java} | 47 ++++---- .../processor/PlacementStateProcessor.java | 57 +++++----- .../heightmap/HeightmapProcessor.java | 58 +++++++--- .../core/history/change/ChangePopulator.java | 3 +- .../history/changeset/AbstractChangeSet.java | 18 +-- .../core/internal/simd/SimdSupport.java | 16 +-- .../core/internal/simd/VectorFacade.java | 23 ++-- .../simd/VectorizedCharFilterBlock.java | 20 ++-- .../core/internal/simd/VectorizedFilter.java | 2 +- .../core/internal/simd/VectorizedMask.java | 26 +++-- .../core/math/BitArrayUnstretched.java | 7 +- .../core/queue/IBatchProcessor.java | 21 ++-- .../core/queue/IBlocks.java | 13 ++- .../core/queue/IChunkSet.java | 3 +- .../SingleThreadQueueExtent.java | 9 +- .../implementation/blocks/BitSetBlocks.java | 18 +-- .../implementation/blocks/DataArray.java | 99 +++++++++++++++++ .../{CharBlocks.java => DataArrayBlocks.java} | 77 ++++++++----- ...GetBlocks.java => DataArrayGetBlocks.java} | 13 +-- ...SetBlocks.java => DataArraySetBlocks.java} | 43 +++---- .../blocks/MemorySegmentBasedDataArray.java | 86 ++++++++++++++ .../implementation/blocks/NullChunkGet.java | 6 +- ....java => ThreadUnsafeDataArrayBlocks.java} | 58 +++++----- .../implementation/chunk/ChunkHolder.java | 7 +- .../queue/implementation/chunk/NullChunk.java | 8 +- .../implementation/chunk/WrapperChunk.java | 7 +- .../sk89q/worldedit/extent/MaskingExtent.java | 4 +- .../sk89q/worldedit/math/BlockVector3.java | 4 - .../sk89q/worldedit/regions/CuboidRegion.java | 35 ++---- .../com/sk89q/worldedit/regions/Region.java | 61 +++++----- .../worldedit/world/block/BaseBlock.java | 5 - .../worldedit/world/block/BlockState.java | 8 -- .../world/block/BlockStateHolder.java | 3 - .../core/queue/IBatchProcessorTest.java | 62 ++++++----- 112 files changed, 1232 insertions(+), 1572 deletions(-) create mode 100644 worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/PostProcessor.java rename worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/{CharFilterBlock.java => DataArrayFilterBlock.java} (91%) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArray.java rename worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/{CharBlocks.java => DataArrayBlocks.java} (69%) rename worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/{CharGetBlocks.java => DataArrayGetBlocks.java} (80%) rename worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/{CharSetBlocks.java => DataArraySetBlocks.java} (91%) create mode 100644 worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/MemorySegmentBasedDataArray.java rename worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/{ThreadUnsafeCharBlocks.java => ThreadUnsafeDataArrayBlocks.java} (89%) diff --git a/build-logic/src/main/kotlin/buildlogic.common-java.gradle.kts b/build-logic/src/main/kotlin/buildlogic.common-java.gradle.kts index 1d92782248..c53a5e4af7 100644 --- a/build-logic/src/main/kotlin/buildlogic.common-java.gradle.kts +++ b/build-logic/src/main/kotlin/buildlogic.common-java.gradle.kts @@ -15,7 +15,7 @@ tasks val disabledLint = listOf( "processing", "path", "fallthrough", "serial", "overloads", "this-escape", ) - options.release.set(21) + options.release.set(25) options.compilerArgs.addAll(listOf("-Xlint:all") + disabledLint.map { "-Xlint:-$it" }) options.isDeprecation = true options.encoding = "UTF-8" diff --git a/build-logic/src/main/kotlin/buildlogic.common.gradle.kts b/build-logic/src/main/kotlin/buildlogic.common.gradle.kts index 227ec60d08..c47abfe3f1 100644 --- a/build-logic/src/main/kotlin/buildlogic.common.gradle.kts +++ b/build-logic/src/main/kotlin/buildlogic.common.gradle.kts @@ -13,7 +13,7 @@ configurations.all { plugins.withId("java") { the().toolchain { - languageVersion.set(JavaLanguageVersion.of(21)) + languageVersion.set(JavaLanguageVersion.of(25)) } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java index 28391ee583..cf35786143 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightAdapter.java @@ -28,6 +28,7 @@ import com.google.common.util.concurrent.Futures; import com.mojang.datafixers.util.Either; import com.mojang.serialization.Lifecycle; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTConstants; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.WorldEditException; @@ -154,7 +155,6 @@ import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -177,6 +177,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java index be25d079a9..80bc50a06f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightDataConverters.java @@ -49,7 +49,6 @@ import org.apache.logging.log4j.Logger; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -63,6 +62,7 @@ import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; +import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java index a27f01b704..2386e69690 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R2/PaperweightWorldNativeAccess.java @@ -37,9 +37,9 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; +import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java index dadd3f1139..61e0e3ee17 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightFaweAdapter.java @@ -405,21 +405,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -429,16 +429,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java index 3a63187b76..6db1c2e80b 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -405,7 +406,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -418,7 +419,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -451,9 +452,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -469,15 +468,12 @@ protected > T internalCall( } } - if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + if (createCopy) { + copy.storeSection(getSectionIndex, DataArray.createCopy(load(layerNo))); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } } - } if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( @@ -535,10 +531,9 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), load(layerNo))) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true) + .equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -768,7 +763,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -812,16 +807,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -834,7 +827,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -854,14 +847,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -879,11 +872,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java index 61056dfc58..cc884740f1 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -30,7 +31,6 @@ import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -59,7 +59,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinBuildHeight(); this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -182,7 +182,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -230,17 +230,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -280,10 +279,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlacementStateProcessor.java index 24b0fe129d..8fbe2f0383 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlacementStateProcessor.java @@ -52,7 +52,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ThreadLocal threadProcessors, Region region, AtomicBoolean finished @@ -74,7 +74,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java index bbbffad673..71352c464f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPlatformAdapter.java @@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.mojang.datafixers.util.Either; @@ -405,7 +406,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -415,8 +416,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPostProcessor.java index aff4f8fe79..47e1098d3f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_2/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R2/PaperweightPostProcessor.java @@ -1,11 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R2; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; @@ -18,12 +19,7 @@ import javax.annotation.Nullable; -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +32,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +52,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +60,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -115,48 +111,6 @@ public ProcessorScope getScope() { return ProcessorScope.READING_BLOCKS; } - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java index f524676068..e6c6aff9a4 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightAdapter.java @@ -154,7 +154,6 @@ import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -177,6 +176,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java index 3a80b6a3a1..177d3158ae 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightDataConverters.java @@ -49,7 +49,6 @@ import org.apache.logging.log4j.Logger; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -63,6 +62,7 @@ import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; +import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java index 1f51c66ca9..1caf8d7843 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_20_R3/PaperweightWorldNativeAccess.java @@ -38,9 +38,9 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; +import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java index c622b25cb9..d821f9bf3e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightFaweAdapter.java @@ -404,21 +404,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -428,16 +428,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java index 374dc3879d..937beb5fff 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -405,7 +406,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -418,7 +419,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -451,9 +452,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -469,15 +468,12 @@ protected > T internalCall( } } - if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + if (createCopy) { + copy.storeSection(getSectionIndex, DataArray.createCopy(load(layerNo))); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } } - } if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( @@ -535,7 +531,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), load(layerNo))) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true) + .equals(load(layerNo))) { this.reset(layerNo); /*} else if (lock.isModified()) { this.reset(layerNo);*/ @@ -769,7 +766,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -813,16 +810,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -835,7 +830,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -855,20 +850,20 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); } } finally { - Arrays.fill(paletteToOrdinal, 0, num_palette, Character.MAX_VALUE); + Arrays.fill(paletteToOrdinal, 0, num_palette, -1); } return data; } catch (IllegalAccessException | InterruptedException e) { @@ -880,11 +875,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java index 7312290d35..b50177fd1e 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -30,7 +31,6 @@ import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -45,7 +45,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -59,7 +59,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinBuildHeight(); this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -182,7 +182,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -230,17 +230,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -280,10 +279,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlacementStateProcessor.java index fd12e5f380..5c2a81097b 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlacementStateProcessor.java @@ -52,7 +52,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ThreadLocal threadProcessors, Region region, AtomicBoolean finished @@ -74,7 +74,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java index 8c25ef1000..6c625cb74a 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPlatformAdapter.java @@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.mojang.datafixers.util.Either; @@ -405,7 +406,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -415,8 +416,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPostProcessor.java index 6ed321a8d7..205b0544ac 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R3/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R3; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java index cb6da03c34..7c063df27f 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightAdapter.java @@ -24,6 +24,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import com.mojang.serialization.Codec; @@ -158,7 +159,6 @@ import org.spigotmc.SpigotConfig; import org.spigotmc.WatchdogThread; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; @@ -181,6 +181,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; +import javax.annotation.Nullable; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java index c566f0ae88..4403391bf2 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightDataConverters.java @@ -51,7 +51,6 @@ import org.apache.logging.log4j.Logger; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.EnumMap; @@ -65,6 +64,7 @@ import java.util.UUID; import java.util.concurrent.Executor; import java.util.stream.Collectors; +import javax.annotation.Nullable; /** * Handles converting all Pre 1.13.2 data using the Legacy DataFix System (ported to 1.13.2) diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java index c83733bf28..dd2061ebe1 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext.fawe/v1_20_R4/PaperweightWorldNativeAccess.java @@ -37,9 +37,9 @@ import org.bukkit.event.block.BlockPhysicsEvent; import org.enginehub.linbus.tree.LinCompoundTag; -import javax.annotation.Nullable; import java.lang.ref.WeakReference; import java.util.Objects; +import javax.annotation.Nullable; public class PaperweightWorldNativeAccess implements WorldNativeAccess { private static final int UPDATE = 1; @@ -186,6 +186,6 @@ public void onBlockStateChange(BlockPos pos, net.minecraft.world.level.block.sta @Override public void flush() { - + } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java index 44bb4c6ec5..bae1061a15 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightFaweAdapter.java @@ -412,21 +412,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -436,16 +436,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java index 48653c9e85..ba57984c16 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -406,7 +407,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -419,7 +420,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -452,9 +453,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -470,15 +469,12 @@ protected > T internalCall( } } - if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + if (createCopy) { + copy.storeSection(getSectionIndex, DataArray.createCopy(load(layerNo))); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } } - } if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( @@ -536,10 +532,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), load(layerNo))) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -770,7 +764,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -814,16 +808,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -836,7 +828,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -856,14 +848,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -881,11 +873,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } @@ -1064,5 +1056,4 @@ public boolean trim(boolean aggressive) { return true; } } - } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java index 19eb6629b0..290eb903cd 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -31,7 +32,6 @@ import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -46,7 +46,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -60,7 +60,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinBuildHeight(); this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -185,7 +185,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -233,17 +233,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -283,10 +282,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlacementStateProcessor.java index cf52c30cf8..8e87c572b7 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java index be033a455f..28b5f6f458 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPlatformAdapter.java @@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -399,7 +400,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -409,8 +410,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java index 301ed8912b..50afc464cc 100644 --- a/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_20_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_20_R4/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_20_R4; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java index 5e8ed03d7e..0ca39b51e0 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/ext/fawe/v1_21_R1/PaperweightAdapter.java @@ -24,6 +24,7 @@ import com.google.common.cache.LoadingCache; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.google.common.util.concurrent.Futures; import com.mojang.serialization.Codec; diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java index 033d2983c0..c856c9a5b6 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightFaweAdapter.java @@ -412,21 +412,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -436,16 +436,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java index a434387799..e633dacf52 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.implementation.QueueHandler; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -409,7 +410,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -422,7 +423,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -455,9 +456,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -470,15 +469,12 @@ protected > T internalCall( PaperweightPlatformAdapter.clearCounts(existingSection); } - if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); - copy.storeSection(getSectionIndex, copyArr); - if (biomes != null && existingSection != null) { - copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + if (createCopy) { + copy.storeSection(getSectionIndex, DataArray.createCopy(load(layerNo))); + if (biomes != null && existingSection != null) { + copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); + } } - } if (existingSection == null) { PalettedContainer> biomeData = biomes == null ? new PalettedContainer<>( @@ -534,10 +530,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals(update(getSectionIndex, new char[4096], true), load(layerNo))) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -817,7 +811,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -861,16 +855,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -883,7 +875,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -903,14 +895,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -928,11 +920,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } @@ -1111,5 +1103,4 @@ public boolean trim(boolean aggressive) { return true; } } - } diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java index 87c7fbab7e..139533a939 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -31,7 +32,6 @@ import org.enginehub.linbus.tree.LinCompoundTag; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -46,7 +46,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -60,7 +60,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinBuildHeight(); this.maxHeight = serverLevel.getMaxBuildHeight() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -185,7 +185,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -233,17 +233,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -283,10 +282,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlacementStateProcessor.java index 14ae451a6c..3392ec4973 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java index 4976bf0649..0aeb0e6722 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -389,7 +390,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -399,8 +400,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java index 9b1e4f3b6d..f1682cebda 100644 --- a/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_R1/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_R1; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightFaweAdapter.java index 77c772a452..702fc7d554 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightFaweAdapter.java @@ -388,21 +388,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -412,16 +412,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks.java index 038135ca8d..f721522be1 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -406,7 +407,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, serverLevel.registryAccess(), biomeData @@ -419,7 +420,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -449,9 +450,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -465,9 +464,7 @@ protected > T internalCall( } if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + DataArray copyArr = DataArray.createCopy(load(layerNo)); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); @@ -524,13 +521,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - load(layerNo) - )) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -765,7 +757,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -809,16 +801,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createEmpty(); // will be populated below } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -831,7 +821,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -851,14 +841,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -876,11 +866,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks_Copy.java index 9d053ed559..d957d4803d 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightGetBlocks_Copy.java @@ -7,9 +7,8 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; -import com.sk89q.worldedit.bukkit.WorldEditPlugin; -import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.biome.BiomeType; @@ -18,7 +17,6 @@ import com.sk89q.worldedit.world.block.BlockTypesCache; import io.papermc.lib.PaperLib; import net.minecraft.core.Holder; -import net.minecraft.nbt.Tag; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.biome.Biome; @@ -29,7 +27,6 @@ import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -46,7 +43,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -60,7 +57,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinY(); this.maxHeight = serverLevel.getMaxY() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -181,7 +178,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -229,17 +226,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -279,10 +275,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlacementStateProcessor.java index 6a77322a67..822cf4cbf0 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java index 52be60c424..1b0172ff1c 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.mojang.serialization.DataResult; @@ -399,7 +400,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, RegistryAccess registryAccess, @Nullable PalettedContainer> biomes @@ -409,8 +410,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, RegistryAccess registryAccess, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPostProcessor.java index 14b50916bd..4eadc29e80 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_11/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_11/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_11; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightFaweAdapter.java index f1282259a1..b263614c13 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightFaweAdapter.java @@ -393,21 +393,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -417,16 +417,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java index b72ee7c41d..4253ab73fd 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -407,7 +408,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -420,7 +421,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -450,9 +451,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -466,9 +465,7 @@ protected > T internalCall( } if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + DataArray copyArr = DataArray.createCopy(load(layerNo)); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); @@ -526,13 +523,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - load(layerNo) - )) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -763,7 +755,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -807,16 +799,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createEmpty(); // will be populated below } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -829,7 +819,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -849,14 +839,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -874,11 +864,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks_Copy.java index 95898157fa..a8e7703af0 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -46,7 +47,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -60,7 +61,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinY(); this.maxHeight = serverLevel.getMaxY() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -185,7 +186,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -233,17 +234,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -283,10 +283,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlacementStateProcessor.java index 1cee9692bf..38f04cd7b8 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java index fb08d684cb..d7aa0aab90 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -375,7 +376,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -385,8 +386,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPostProcessor.java index 75dd15076e..7d34edce27 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_4/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_4/PaperweightPostProcessor.java @@ -1,29 +1,27 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_4; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; import net.minecraft.core.BlockPos; +import net.minecraft.data.PackOutput; import net.minecraft.server.level.ServerLevel; import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; import javax.annotation.Nullable; -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +34,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +54,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +62,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +102,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightFaweAdapter.java index d9be2690fc..fc2c6d1fc6 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightFaweAdapter.java @@ -393,21 +393,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -417,16 +417,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks.java index 71081abc14..43bef9dd7c 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -407,7 +408,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -420,7 +421,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -450,9 +451,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -466,9 +465,7 @@ protected > T internalCall( } if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + DataArray copyArr = DataArray.createCopy(load(layerNo)); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); @@ -526,13 +523,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - load(layerNo) - )) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -762,7 +754,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -806,16 +798,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createEmpty(); // will be populated below } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -828,7 +818,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -848,14 +838,14 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); @@ -873,11 +863,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks_Copy.java index a8d4ec820d..ce7e77ced7 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -46,7 +47,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -60,7 +61,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinY(); this.maxHeight = serverLevel.getMaxY() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -185,7 +186,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -233,17 +234,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -283,10 +283,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlacementStateProcessor.java index 23d649a456..d1296e7c2d 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlatformAdapter.java index 6c4ca83aae..7b9a5ede42 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -374,7 +375,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -384,8 +385,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPostProcessor.java index fdf48ac6f8..4dd00cdbc5 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_5/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_5/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_5; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightFaweAdapter.java index 7c663390c0..1875cec5d1 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightFaweAdapter.java @@ -404,21 +404,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -428,16 +428,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks.java index ae95fd8dec..b7e1420d58 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -411,7 +412,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, biomeRegistry, biomeData @@ -424,7 +425,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -454,9 +455,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -470,9 +469,7 @@ protected > T internalCall( } if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + DataArray copyArr = DataArray.createCopy(load(layerNo)); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); @@ -530,13 +527,8 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - load(layerNo) - )) { + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo))) { this.reset(layerNo); - /*} else if (lock.isModified()) { - this.reset(layerNo);*/ } } finally { sectionLock.writeLock().unlock(); @@ -770,7 +762,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -814,16 +806,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createEmpty(); // will be populated below } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -836,7 +826,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -856,11 +846,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { char ordinal = ordinal(palette.valueFor(i), adapter); @@ -881,11 +871,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks_Copy.java index db4fe55939..945add7d19 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -48,7 +49,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -62,7 +63,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinY(); this.maxHeight = serverLevel.getMaxY() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -189,7 +190,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -237,17 +238,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -287,10 +287,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlacementStateProcessor.java index 6d83af0ba0..486f16f7bc 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlatformAdapter.java index d994091088..3cca0a86d3 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.bukkit.WorldEditPlugin; @@ -403,7 +404,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes @@ -413,8 +414,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, Registry biomeRegistry, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPostProcessor.java index 8ba0fd1d35..7a2af27dc8 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_6/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_6/PaperweightPostProcessor.java @@ -1,11 +1,13 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_6; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; @@ -18,12 +20,7 @@ import javax.annotation.Nullable; -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +33,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +53,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +61,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +101,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightFaweAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightFaweAdapter.java index 2bde85f600..975b1c8ce3 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightFaweAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightFaweAdapter.java @@ -404,21 +404,21 @@ public BlockState adapt(BlockData blockData) { } public BlockState adapt(net.minecraft.world.level.block.state.BlockState blockState) { - return BlockTypesCache.states[adaptToChar(blockState)]; + return BlockTypesCache.states[adaptToOrdinal(blockState)]; } - public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockState) { + public int adaptToOrdinal(net.minecraft.world.level.block.state.BlockState blockState) { int id = Block.BLOCK_STATE_REGISTRY.getId(blockState); if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } try { init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } catch (ArrayIndexOutOfBoundsException e1) { LOGGER.error("Attempted to convert {} with ID {} to char. ibdToOrdinal length: {}. Defaulting to air!", blockState.getBlock(), Block.BLOCK_STATE_REGISTRY.getId(blockState), ibdToOrdinal.length, e1 @@ -428,16 +428,16 @@ public char adaptToChar(net.minecraft.world.level.block.state.BlockState blockSt } } - public char ibdIDToOrdinal(int id) { + public int ibdIDToOrdinal(int id) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } synchronized (this) { if (initialised) { - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } init(); - return (char) ibdToOrdinal[id]; + return ibdToOrdinal[id]; } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks.java index 5aea2c0363..9ee1fc20ad 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks.java @@ -11,6 +11,7 @@ import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.collection.AdaptedMap; @@ -410,7 +411,7 @@ protected > T internalCall( ); LevelChunkSection newSection = PaperweightPlatformAdapter.newChunkSection( layerNo, - new char[4096], + DataArray.createEmpty(), adapter, serverLevel.registryAccess(), biomeData @@ -423,7 +424,7 @@ protected > T internalCall( newSection, getSectionIndex )) { - updateGet(nmsChunk, levelChunkSections, newSection, new char[4096], getSectionIndex); + updateGet(nmsChunk, levelChunkSections, newSection, DataArray.createEmpty(), getSectionIndex); continue; } else { existingSection = levelChunkSections[getSectionIndex]; @@ -453,9 +454,7 @@ protected > T internalCall( // setArr is modified by PaperweightPlatformAdapter#newChunkSection. This is in order to write changes to // this chunk GET when #updateGet is called. Future dords, please listen this time. - char[] tmp = set.load(layerNo); - char[] setArr = new char[tmp.length]; - System.arraycopy(tmp, 0, setArr, 0, tmp.length); + DataArray setArr = DataArray.createCopy(set.load(layerNo)); // synchronise on internal section to avoid circular locking with a continuing edit if the chunk was // submitted to keep loaded internal chunks to queue target size. @@ -469,9 +468,7 @@ protected > T internalCall( } if (createCopy) { - char[] tmpLoad = load(layerNo); - char[] copyArr = new char[4096]; - System.arraycopy(tmpLoad, 0, copyArr, 0, 4096); + DataArray copyArr = DataArray.createCopy(load(layerNo)); copy.storeSection(getSectionIndex, copyArr); if (biomes != null && existingSection != null) { copy.storeBiomes(getSectionIndex, existingSection.getBiomes()); @@ -528,9 +525,7 @@ protected > T internalCall( } else if (existingSection != getSections(false)[getSectionIndex]) { this.sections[getSectionIndex] = existingSection; this.reset(); - } else if (!Arrays.equals( - update(getSectionIndex, new char[4096], true), - load(layerNo) + } else if (!update(getSectionIndex, DataArray.createEmpty(), true).equals(load(layerNo) )) { this.reset(layerNo); /*} else if (lock.isModified()) { @@ -772,7 +767,7 @@ private void updateGet( LevelChunk nmsChunk, LevelChunkSection[] chunkSections, LevelChunkSection section, - char[] arr, + DataArray arr, int layer ) { try { @@ -816,16 +811,14 @@ public void send() { */ @Override @SuppressWarnings("unchecked") - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { LevelChunkSection section = getSections(aggressive)[layer]; // Section is null, return empty array if (section == null) { - data = new char[4096]; - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); - return data; + return DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } - if (data == null || data == FaweCache.INSTANCE.EMPTY_CHAR_4096 || data.length != 4096) { - data = new char[4096]; // new array, will be populated below + if (data == null || data == FaweCache.INSTANCE.EMPTY_DATA) { + data = DataArray.createEmpty(); // will be populated below } Semaphore lock = PaperweightPlatformAdapter.applyLock(section); synchronized (lock) { @@ -838,7 +831,7 @@ public char[] update(int layer, char[] data, boolean aggressive) { final BitStorage bits = (BitStorage) PaperweightPlatformAdapter.fieldStorage.get(dataObject); if (bits instanceof ZeroBitStorage) { - Arrays.fill(data, adapter.adaptToChar(blocks.get(0, 0, 0))); // get(int) is only public on paper + data.setAll(adapter.adaptToOrdinal(blocks.get(0, 0, 0))); // get(int) is only public on paper return data; } @@ -858,20 +851,20 @@ public char[] update(int layer, char[] data, boolean aggressive) { return data; } - char[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK_CHAR.get(); + int[] paletteToOrdinal = FaweCache.INSTANCE.PALETTE_TO_BLOCK.get(); try { if (num_palette == 1) { - char ordinal = ordinal(palette.valueFor(0), adapter); - Arrays.fill(data, ordinal); + int ordinal = ordinal(palette.valueFor(0), adapter); + data.setAll(ordinal); } else { for (int i = 0; i < num_palette; i++) { - char ordinal = ordinal(palette.valueFor(i), adapter); + int ordinal = ordinal(palette.valueFor(i), adapter); paletteToOrdinal[i] = ordinal; } adapter.mapWithPalette(data, paletteToOrdinal); } } finally { - Arrays.fill(paletteToOrdinal, 0, num_palette, Character.MAX_VALUE); + Arrays.fill(paletteToOrdinal, 0, num_palette, -1); } return data; } catch (IllegalAccessException | InterruptedException e) { @@ -883,11 +876,11 @@ public char[] update(int layer, char[] data, boolean aggressive) { } } - private char ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { + private int ordinal(BlockState ibd, PaperweightFaweAdapter adapter) { if (ibd == null) { return BlockTypesCache.ReservedIDs.AIR; } else { - return adapter.adaptToChar(ibd); + return adapter.adaptToOrdinal(ibd); } } diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks_Copy.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks_Copy.java index 881cbb0eff..985a2a3c7b 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks_Copy.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightGetBlocks_Copy.java @@ -7,6 +7,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter; @@ -48,7 +49,7 @@ public class PaperweightGetBlocks_Copy implements IChunkGet { private final Map tiles = new HashMap<>(); private final Set entities = new HashSet<>(); - private final char[][] blocks; + private final DataArray[] blocks; private final int minHeight; private final int maxHeight; private final int chunkX; @@ -62,7 +63,7 @@ protected PaperweightGetBlocks_Copy(LevelChunk levelChunk) { this.serverLevel = levelChunk.level; this.minHeight = serverLevel.getMinY(); this.maxHeight = serverLevel.getMaxY() - 1; // Minecraft max limit is exclusive. - this.blocks = new char[getSectionCount()][]; + this.blocks = new DataArray[getSectionCount()]; this.chunkX = levelChunk.getPos().x; this.chunkZ = levelChunk.getPos().z; } @@ -189,7 +190,7 @@ public int getSectionCount() { return serverLevel.getSectionsCount(); } - protected void storeSection(int layer, char[] data) { + protected void storeSection(int layer, DataArray data) { blocks[layer] = data; } @@ -237,17 +238,16 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= getMinSectionPosition(); if (blocks[layer] == null) { - blocks[layer] = new char[4096]; - Arrays.fill(blocks[layer], (char) BlockTypesCache.ReservedIDs.AIR); + blocks[layer] = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); } return blocks[layer]; } @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { layer -= getMinSectionPosition(); return blocks[layer]; } @@ -287,10 +287,10 @@ public > T call(IQueueExtent owner, IChunk return null; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { final int layer = (y >> 4) - getMinSectionPosition(); final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer][index]; + return blocks[layer].getAt(index); } diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlacementStateProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlacementStateProcessor.java index ff656a5f2a..af559b4f8c 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlacementStateProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlacementStateProcessor.java @@ -53,7 +53,7 @@ public PaperweightPlacementStateProcessor(Extent extent, BlockTypeMask mask, Reg private PaperweightPlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ServerLevel serverLevel, ThreadLocal threadProcessors, Region region, @@ -65,7 +65,7 @@ private PaperweightPlacementStateProcessor( } @Override - protected char getStateAtFor( + protected int getStateAtFor( int x, int y, int z, diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java index 5da8b3cec5..1e96553283 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPlatformAdapter.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.math.BitArrayUnstretched; import com.fastasyncworldedit.core.math.IntPair; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.TaskManager; import com.mojang.serialization.DataResult; @@ -410,7 +411,7 @@ private static List nearbyPlayers(ServerLevel serverLevel, ChunkPo */ public static LevelChunkSection newChunkSection( final int layer, - final char[] blocks, + final DataArray blocks, CachedBukkitAdapter adapter, RegistryAccess registryAccess, @Nullable PalettedContainer> biomes @@ -420,8 +421,8 @@ public static LevelChunkSection newChunkSection( public static LevelChunkSection newChunkSection( final int layer, - final IntFunction get, - char[] set, + final IntFunction get, + DataArray set, CachedBukkitAdapter adapter, RegistryAccess registryAccess, @Nullable PalettedContainer> biomes diff --git a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPostProcessor.java b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPostProcessor.java index 33569f4a70..15a9ab1fc8 100644 --- a/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPostProcessor.java +++ b/worldedit-bukkit/adapters/adapter-1_21_9/src/main/java/com/sk89q/worldedit/bukkit/adapter/impl/fawe/v1_21_9/PaperweightPostProcessor.java @@ -1,13 +1,12 @@ package com.sk89q.worldedit.bukkit.adapter.impl.fawe.v1_21_9; +import com.fastasyncworldedit.bukkit.adapter.PostProcessor; import com.fastasyncworldedit.core.configuration.Settings; -import com.fastasyncworldedit.core.extent.processor.ProcessorScope; -import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -16,14 +15,7 @@ import net.minecraft.world.level.material.Fluid; import net.minecraft.world.level.material.Fluids; -import javax.annotation.Nullable; - -public class PaperweightPostProcessor implements IBatchProcessor { - - @Override - public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { - return set; - } +public class PaperweightPostProcessor extends PostProcessor { @SuppressWarnings("deprecation") @Override @@ -36,15 +28,15 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh PaperweightGetBlocks_Copy getBlocks = (PaperweightGetBlocks_Copy) iChunkGet; layer: for (int layer = iChunkSet.getMinSectionPosition(); layer <= iChunkSet.getMaxSectionPosition(); layer++) { - char[] set = iChunkSet.loadIfPresent(layer); + DataArray set = iChunkSet.loadIfPresent(layer); if (set == null) { // No edit means no need to process continue; } - char[] get = null; + DataArray get = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; - char replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = set.getAt(i); + int replacedOrdinal = BlockTypesCache.ReservedIDs.__RESERVED__; boolean fromGet = false; // Used for liquids if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (get == null) { @@ -56,7 +48,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh continue layer; } fromGet = true; - ordinal = replacedOrdinal = get[i]; + ordinal = replacedOrdinal = get.getAt(i); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; @@ -64,7 +56,7 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh if (get == null) { get = getBlocks.load(layer); } - replacedOrdinal = get[i]; + replacedOrdinal = get.getAt(i); } boolean ticking = BlockTypesCache.ticking[ordinal]; boolean replacedWasTicking = BlockTypesCache.ticking[replacedOrdinal]; @@ -104,59 +96,6 @@ public void postProcess(final IChunk chunk, final IChunkGet iChunkGet, final ICh } } - @Nullable - @Override - public Extent construct(final Extent child) { - throw new UnsupportedOperationException("Processing only"); - } - - @Override - public ProcessorScope getScope() { - return ProcessorScope.READING_BLOCKS; - } - - private boolean wasAdjacentToWater(char[] get, char[] set, int i, int x, int y, int z) { - if (set == null || get == null) { - return false; - } - char ordinal; - char reserved = BlockTypesCache.ReservedIDs.__RESERVED__; - if (x > 0 && set[i - 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 1])] && isFluid(ordinal)) { - return true; - } - } - if (x < 15 && set[i + 1] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 1])] && isFluid(ordinal)) { - return true; - } - } - if (z > 0 && set[i - 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 16])] && isFluid(ordinal)) { - return true; - } - } - if (z < 15 && set[i + 16] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i + 16])] && isFluid(ordinal)) { - return true; - } - } - if (y > 0 && set[i - 256] != reserved) { - if (BlockTypesCache.ticking[(ordinal = get[i - 256])] && isFluid(ordinal)) { - return true; - } - } - if (y < 15 && set[i + 256] != reserved) { - return BlockTypesCache.ticking[(ordinal = get[i + 256])] && isFluid(ordinal); - } - return false; - } - - @SuppressWarnings("deprecation") - private boolean isFluid(char ordinal) { - return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); - } - @SuppressWarnings("deprecation") private void addFluid(final ServerLevel serverLevel, final BlockState replacedState, final BlockPos position) { Fluid type; diff --git a/worldedit-bukkit/build.gradle.kts b/worldedit-bukkit/build.gradle.kts index b22c6f15b4..615cd21c04 100644 --- a/worldedit-bukkit/build.gradle.kts +++ b/worldedit-bukkit/build.gradle.kts @@ -129,7 +129,7 @@ dependencies { compileOnly(libs.residence) { isTransitive = false } compileOnly(libs.towny) { isTransitive = false } compileOnly(libs.plotsquared.bukkit) { isTransitive = false } - compileOnly(libs.plotsquared.core) { isTransitive = false } + compileOnly(libs.plotsquared.core) // Third party implementation(libs.serverlib) @@ -138,7 +138,7 @@ dependencies { api(libs.sparsebitset) { isTransitive = false } api(libs.parallelgzip) { isTransitive = false } compileOnly(libs.adventureApi) - compileOnlyApi(libs.checkerqual) + compileOnly(libs.checkerqual) // Tests testImplementation(libs.mockito.core) diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/AbstractBukkitGetBlocks.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/AbstractBukkitGetBlocks.java index bba60917e8..51d0305a4c 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/AbstractBukkitGetBlocks.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/AbstractBukkitGetBlocks.java @@ -9,7 +9,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; import com.fastasyncworldedit.core.queue.implementation.QueueHandler; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArrayGetBlocks; import com.fastasyncworldedit.core.util.MemUtil; import com.fastasyncworldedit.core.util.task.FaweThreadUtil; import com.sk89q.worldedit.extent.Extent; @@ -25,7 +25,7 @@ import java.util.concurrent.Future; import java.util.concurrent.locks.ReentrantLock; -public abstract class AbstractBukkitGetBlocks extends CharGetBlocks { +public abstract class AbstractBukkitGetBlocks extends DataArrayGetBlocks { private static final Logger LOGGER = LogManagerCompat.getLogger(); diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/FaweAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/FaweAdapter.java index b902696d2f..5e01ef82b4 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/FaweAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/FaweAdapter.java @@ -1,5 +1,6 @@ package com.fastasyncworldedit.bukkit.adapter; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.TaskManager; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.bukkit.BukkitAdapter; @@ -75,20 +76,19 @@ public boolean generateTree( return true; } - public void mapFromGlobalPalette(char[] data) { - assert data.length == 4096; + public void mapFromGlobalPalette(DataArray data) { ensureInit(); - for (int i = 0; i < 4096; i++) { - data[i] = (char) this.ibdToOrdinal[data[i]]; + for (int i = 0; i < DataArray.CHUNK_SECTION_SIZE; i++) { + data.setAt(i, this.ibdToOrdinal[data.getAt(i)]); } } - public void mapWithPalette(char[] data, char[] paletteToOrdinal) { - for (int i = 0; i < 4096; i++) { - char paletteVal = data[i]; - char val = paletteToOrdinal[paletteVal]; - assert val != Character.MAX_VALUE; // paletteToOrdinal should prevent that - data[i] = val; + public void mapWithPalette(DataArray data, int[] paletteToOrdinal) { + for (int i = 0; i < DataArray.CHUNK_SECTION_SIZE; i++) { + int paletteVal = data.getAt(i); + int val = paletteToOrdinal[paletteVal]; + assert val != -1; // paletteToOrdinal should prevent that + data.setAt(i, val); } } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java index 13ff89349f..194966d17c 100644 --- a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/NMSAdapter.java @@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.math.IntPair; import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.ReflectionUtils; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -19,12 +20,12 @@ public static int createPalette( int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, - char[] set, + DataArray set, CachedBukkitAdapter adapter ) { int numPaletteEntries = 0; for (int i = 0; i < 4096; i++) { - int ordinal = set[i]; + int ordinal = set.getAt(i); ordinal = Math.max(ordinal, BlockTypesCache.ReservedIDs.AIR); int palette = blockToPalette[ordinal]; if (palette == Integer.MAX_VALUE) { @@ -43,22 +44,22 @@ public static int createPalette( int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, - IntFunction get, - char[] set, + IntFunction get, + DataArray set, CachedBukkitAdapter adapter ) { int numPaletteEntries = 0; - char[] getArr = null; + DataArray getArr = null; for (int i = 0; i < 4096; i++) { - char ordinal = set[i]; + int ordinal = set.getAt(i); if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (getArr == null) { getArr = get.apply(layer); } - ordinal = getArr[i]; + ordinal = getArr.getAt(i); // write to set array as this should be a copied array, and will be important when the changes are written // to the GET chunk cached by FAWE. Future dords, actually read this comment please. - set[i] = (char) Math.max(ordinal, BlockTypesCache.ReservedIDs.AIR); + set.setAt(i, Math.max(ordinal, BlockTypesCache.ReservedIDs.AIR)); } int palette = blockToPalette[ordinal]; if (palette == Integer.MAX_VALUE) { @@ -76,7 +77,7 @@ private static void mapPalette( int[] blockToPalette, int[] paletteToBlock, int[] blocksCopy, - char[] set, + DataArray set, CachedBukkitAdapter adapter, int numPaletteEntries ) { @@ -89,7 +90,7 @@ private static void mapPalette( int oldVal = blockToPalette[BlockTypesCache.ReservedIDs.__RESERVED__]; blockToPalette[BlockTypesCache.ReservedIDs.__RESERVED__] = blockToPalette[BlockTypesCache.ReservedIDs.AIR]; for (int i = 0; i < 4096; i++) { - int ordinal = set[i]; + int ordinal = set.getAt(i); int palette = blockToPalette[ordinal]; blocksCopy[i] = palette; } diff --git a/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/PostProcessor.java b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/PostProcessor.java new file mode 100644 index 0000000000..74f411afc6 --- /dev/null +++ b/worldedit-bukkit/src/main/java/com/fastasyncworldedit/bukkit/adapter/PostProcessor.java @@ -0,0 +1,78 @@ +package com.fastasyncworldedit.bukkit.adapter; + +import com.fastasyncworldedit.core.extent.processor.ProcessorScope; +import com.fastasyncworldedit.core.queue.IBatchProcessor; +import com.fastasyncworldedit.core.queue.IChunk; +import com.fastasyncworldedit.core.queue.IChunkGet; +import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockTypesCache; + +import javax.annotation.Nullable; + +/** + * Common code for post-processing on different versions + */ +public abstract class PostProcessor implements IBatchProcessor { + + @Nullable + @Override + public Extent construct(final Extent child) { + throw new UnsupportedOperationException("Processing only"); + } + + protected boolean wasAdjacentToWater(DataArray get, DataArray set, int i, int x, int y, int z) { + if (set == null || get == null) { + return false; + } + int ordinal; + int reserved = BlockTypesCache.ReservedIDs.__RESERVED__; + if (x > 0 && set.getAt(i - 1) != reserved) { + if (BlockTypesCache.ticking[(ordinal = get.getAt(i - 1))] && isFluid(ordinal)) { + return true; + } + } + if (x < 15 && set.getAt(i + 1) != reserved) { + if (BlockTypesCache.ticking[(ordinal = get.getAt(i + 1))] && isFluid(ordinal)) { + return true; + } + } + if (z > 0 && set.getAt(i - 16) != reserved) { + if (BlockTypesCache.ticking[(ordinal = get.getAt(i - 16))] && isFluid(ordinal)) { + return true; + } + } + if (z < 15 && set.getAt(i + 16) != reserved) { + if (BlockTypesCache.ticking[(ordinal = get.getAt(i + 16))] && isFluid(ordinal)) { + return true; + } + } + if (y > 0 && set.getAt(i - 256) != reserved) { + if (BlockTypesCache.ticking[(ordinal = get.getAt(i - 256))] && isFluid(ordinal)) { + return true; + } + } + if (y < 15 && set.getAt(i + 256) != reserved) { + return BlockTypesCache.ticking[(ordinal = get.getAt(i + 256))] && isFluid(ordinal); + } + return false; + } + + @SuppressWarnings("deprecation") + private boolean isFluid(int ordinal) { + return BlockState.getFromOrdinal(ordinal).getMaterial().isLiquid(); + } + + @Override + public ProcessorScope getScope() { + return ProcessorScope.READING_BLOCKS; + } + + @Override + public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChunkSet set) { + return set; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java index 1721b6169b..8337dc7d33 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/FaweCache.java @@ -2,6 +2,7 @@ import com.fastasyncworldedit.core.configuration.Caption; import com.fastasyncworldedit.core.configuration.Settings; +import com.fastasyncworldedit.core.extent.filter.block.DataArrayFilterBlock; import com.fastasyncworldedit.core.internal.exception.FaweBlockBagException; import com.fastasyncworldedit.core.internal.exception.FaweException; import com.fastasyncworldedit.core.internal.exception.FaweException.Type; @@ -13,6 +14,7 @@ import com.fastasyncworldedit.core.queue.Pool; import com.fastasyncworldedit.core.queue.Trimable; import com.fastasyncworldedit.core.queue.implementation.QueuePool; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; import com.fastasyncworldedit.core.util.collection.CleanableThreadLocal; import com.fastasyncworldedit.core.util.task.FaweBasicThreadFactory; @@ -75,7 +77,10 @@ public enum FaweCache implements Trimable { public final int BLOCKS_PER_LAYER = 4096; - public final char[] EMPTY_CHAR_4096 = new char[4096]; + /** + * @since TODO + */ + public final DataArray EMPTY_DATA = DataArray.EMPTY; private final IdentityHashMap, Pool> REGISTERED_POOLS = new IdentityHashMap<>(); @@ -93,6 +98,7 @@ public synchronized boolean trim(boolean aggressive) { SECTION_BLOCKS.clean(); PALETTE_CACHE.clean(); PALETTE_TO_BLOCK_CHAR.clean(); + PALETTE_TO_BLOCK_INT.clean(); INDEX_STORE.clean(); MUTABLE_VECTOR3.clean(); @@ -144,9 +150,9 @@ public V load(@Nonnull T key) { * from the main thread, it will return a {@link Function} referencing the {@link LoadingCache} returned by * {@link FaweCache#createCache(Supplier)}. If it is called from the main thread, it will return a {@link Function} that * will always return the result of the given {@link Supplier}. It is designed to prevent issues caused by - * internally-mutable and resettable classes such as {@link com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock} + * internally-mutable and resettable classes such as {@link DataArrayFilterBlock} * from causing issues when used in edits on the main thread. - * + *

* This method is designed for specific internal use. * * @param withInitial The supplier used to determine the initial value if a thread cache is created, else to provide a new @@ -262,8 +268,12 @@ public V apply(final long input) { public final CleanableThreadLocal PALETTE_TO_BLOCK_CHAR = new CleanableThreadLocal<>( () -> new char[Character.MAX_VALUE + 1], a -> { Arrays.fill(a, Character.MAX_VALUE); - } - ); + }); + + public final CleanableThreadLocal PALETTE_TO_BLOCK_INT = new CleanableThreadLocal<>( + () -> new int[Character.MAX_VALUE + 1], a -> { + Arrays.fill(a, Integer.MAX_VALUE); + }); public final CleanableThreadLocal BLOCK_STATES = new CleanableThreadLocal<>(() -> new long[2048]); @@ -296,21 +306,10 @@ public static final class Palette { /** * Convert raw char array to palette + * * @return palette */ - public Palette toPalette(int layerOffset, char[] blocks) { - return toPalette(layerOffset, null, blocks); - } - - /** - * Convert raw int array to palette - * @return palette - */ - public Palette toPalette(int layerOffset, int[] blocks) { - return toPalette(layerOffset, blocks, null); - } - - private Palette toPalette(int layerOffset, int[] blocksInts, char[] blocksChars) { + public Palette toPalette(int layerOffset, DataArray blocks) { int[] blockToPalette = BLOCK_TO_PALETTE.get(); int[] paletteToBlock = PALETTE_TO_BLOCK.get(); long[] blockStates = BLOCK_STATES.get(); @@ -320,31 +319,15 @@ private Palette toPalette(int layerOffset, int[] blocksInts, char[] blocksChars) int num_palette = 0; int blockIndexStart = layerOffset << 12; int blockIndexEnd = blockIndexStart + 4096; - if (blocksChars != null) { - for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { - int ordinal = blocksChars[i]; - int palette = blockToPalette[ordinal]; - if (palette == Integer.MAX_VALUE) { - blockToPalette[ordinal] = palette = num_palette; - paletteToBlock[num_palette] = ordinal; - num_palette++; - } - blocksCopy[j] = palette; + for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { + int ordinal = blocks.getAt(i); + int palette = blockToPalette[ordinal]; + if (palette == Integer.MAX_VALUE) { + blockToPalette[ordinal] = palette = num_palette; + paletteToBlock[num_palette] = ordinal; + num_palette++; } - } else if (blocksInts != null) { - for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { - int ordinal = blocksInts[i]; - int palette = blockToPalette[ordinal]; - if (palette == Integer.MAX_VALUE) { -// BlockState state = BlockTypesCache.states[ordinal]; - blockToPalette[ordinal] = palette = num_palette; - paletteToBlock[num_palette] = ordinal; - num_palette++; - } - blocksCopy[j] = palette; - } - } else { - throw new IllegalArgumentException(); + blocksCopy[j] = palette; } for (int i = 0; i < num_palette; i++) { @@ -390,11 +373,7 @@ private Palette toPalette(int layerOffset, int[] blocksInts, char[] blocksChars) * * @return palette */ - public Palette toPaletteUnstretched(int layerOffset, char[] blocks) { - return toPaletteUnstretched(layerOffset, null, blocks); - } - - private Palette toPaletteUnstretched(int layerOffset, int[] blocksInts, char[] blocksChars) { + public Palette toPaletteUnstretched(int layerOffset, DataArray blocks) { int[] blockToPalette = BLOCK_TO_PALETTE.get(); int[] paletteToBlock = PALETTE_TO_BLOCK.get(); long[] blockStates = BLOCK_STATES.get(); @@ -404,31 +383,15 @@ private Palette toPaletteUnstretched(int layerOffset, int[] blocksInts, char[] b int num_palette = 0; int blockIndexStart = layerOffset << 12; int blockIndexEnd = blockIndexStart + 4096; - if (blocksChars != null) { - for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { - int ordinal = blocksChars[i]; - int palette = blockToPalette[ordinal]; - if (palette == Integer.MAX_VALUE) { - blockToPalette[ordinal] = palette = num_palette; - paletteToBlock[num_palette] = ordinal; - num_palette++; - } - blocksCopy[j] = palette; + for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { + int ordinal = blocks.getAt(i); + int palette = blockToPalette[ordinal]; + if (palette == Integer.MAX_VALUE) { + blockToPalette[ordinal] = palette = num_palette; + paletteToBlock[num_palette] = ordinal; + num_palette++; } - } else if (blocksInts != null) { - for (int i = blockIndexStart, j = 0; i < blockIndexEnd; i++, j++) { - int ordinal = blocksInts[i]; - int palette = blockToPalette[ordinal]; - if (palette == Integer.MAX_VALUE) { - // BlockState state = BlockTypesCache.states[ordinal]; - blockToPalette[ordinal] = palette = num_palette; - paletteToBlock[num_palette] = ordinal; - num_palette++; - } - blocksCopy[j] = palette; - } - } else { - throw new IllegalArgumentException(); + blocksCopy[j] = palette; } for (int i = 0; i < num_palette; i++) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java index 2773f0b98a..f6a2844187 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/DisallowedBlocksExtent.java @@ -6,6 +6,7 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.ExtentTraverser; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extension.factory.parser.DefaultBlockParser; @@ -29,6 +30,8 @@ import java.util.Set; import java.util.stream.Collectors; +import static com.sk89q.worldedit.world.block.BlockTypesCache.states; + public final class DisallowedBlocksExtent extends AbstractDelegateExtent implements IBatchProcessor { private static final BlockState RESERVED = BlockTypes.__RESERVED__.getDefaultState(); @@ -131,17 +134,17 @@ public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChun if (!set.hasSection(layer)) { continue; } - char[] blocks = Objects.requireNonNull(set.loadIfPresent(layer)); + DataArray blocks = Objects.requireNonNull(set.loadIfPresent(layer)); it: - for (int i = 0; i < blocks.length; i++) { - char block = blocks[i]; + for (int i = 0; i < DataArray.CHUNK_SECTION_SIZE; i++) { + int block = blocks.getAt(i); if (block == BlockTypesCache.ReservedIDs.__RESERVED__) { continue; } BlockState state = BlockTypesCache.states[block]; if (blockedBlocks != null) { if (blockedBlocks.contains(state.getBlockType().id())) { - blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; + blocks.setAt(i, BlockTypesCache.ReservedIDs.__RESERVED__); continue; } } @@ -150,18 +153,18 @@ public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChun } for (FuzzyBlockState fuzzy : blockedStates) { if (fuzzy.equalsFuzzy(state)) { - blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; + blocks.setAt(i, BlockTypesCache.ReservedIDs.__RESERVED__); continue it; } } if (remaps == null || remaps.isEmpty()) { - blocks[i] = block; + blocks.setAt(i, block); continue; } for (PropertyRemap remap : remaps) { state = remap.apply(state); } - blocks[i] = state.getOrdinalChar(); + blocks.setAt(i, state.getOrdinal()); } } return set; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java index 4c71a9f66e..4c4b5e4ffd 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV2.java @@ -76,8 +76,8 @@ public class FastSchematicReaderV2 extends NBTSchematicReader { private int offsetX; private int offsetY; private int offsetZ; - private char[] palette; - private char[] biomePalette; + private int[] palette; + private int[] biomePalette; private BlockVector3 min = BlockVector3.ZERO; private boolean brokenEntities = false; private boolean isWorldEdit = false; @@ -167,7 +167,7 @@ public StreamDelegate createDelegate() { StreamDelegate paletteDelegate = schematic.add("Palette"); paletteDelegate.withValue((ValueReader>) (ignore, v) -> { - palette = new char[v.size()]; + palette = new int[v.size()]; for (Entry entry : v.entrySet()) { BlockState state; String palettePart = fix(entry.getKey()); @@ -178,7 +178,7 @@ public StreamDelegate createDelegate() { state = BlockTypes.AIR.getDefaultState(); } int index = (int) entry.getValue(); - palette[index] = (char) state.getOrdinal(); + palette[index] = state.getOrdinal(); } }); StreamDelegate blockData = schematic.add("BlockData"); @@ -203,7 +203,7 @@ public StreamDelegate createDelegate() { StreamDelegate biomePaletteDelegate = schematic.add("BiomePalette"); biomePaletteDelegate.withValue((ValueReader>) (ignore, v) -> { - biomePalette = new char[v.size()]; + biomePalette = new int[v.size()]; for (Entry entry : v.entrySet()) { BiomeType biome = null; try { @@ -230,7 +230,7 @@ private BlockState getBlockState(int id) { } private BiomeType getBiomeType(FaweInputStream fis) throws IOException { - char biomeId = biomePalette[fis.readVarInt()]; + int biomeId = biomePalette[fis.readVarInt()]; return BiomeTypes.get(biomeId); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java index 28afb9a326..b5dec4e8c4 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/clipboard/io/FastSchematicReaderV3.java @@ -8,7 +8,6 @@ import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.util.IOUtil; import com.fastasyncworldedit.core.util.MathMan; -import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.NBTConstants; import com.sk89q.jnbt.NBTInputStream; import com.sk89q.jnbt.NBTOutputStream; @@ -553,12 +552,12 @@ private void readPaletteData(DataInputStream stream, PaletteDataApplier applier) int i = 0; if (needsVarIntReading(length)) { for (var iter = new VarIntStreamIterator(stream, length); iter.hasNext(); i++) { - applier.apply(i, (char) iter.nextInt()); + applier.apply(i, iter.nextInt()); } return; } while (i < length) { - applier.apply(i++, (char) stream.readUnsignedByte()); + applier.apply(i++, stream.readUnsignedByte()); } } @@ -819,7 +818,7 @@ private interface PaletteDataApplier { * @param index The index of this data entry (due to var-int behaviour not necessarily the index in the data byte array). * @param ordinal The ordinal of this entry as defined in the palette mapping. */ - void apply(int index, char ordinal); + void apply(int index, int ordinal); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java index e07bd276ba..b360ae933d 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/CountFilter.java @@ -37,7 +37,7 @@ public int getTotal() { } @Override - public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { + public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { total += mask.trueCount(); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java index 17571e3af2..08379a5aeb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/LinkedFilter.java @@ -70,7 +70,7 @@ public void join() { getRight().join(); } - private final static class VectorizedLinkedFilter + private final static class VectorizedLinkedFilter extends LinkedFilter implements VectorizedFilter { public VectorizedLinkedFilter(final L left, final R right) { @@ -78,7 +78,7 @@ public VectorizedLinkedFilter(final L left, final R right) { } @Override - public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { + public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { getLeft().applyVector(get, set, mask); getRight().applyVector(get, set, mask); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java index 9ff02e3c4b..6a6d85242c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/MaskFilter.java @@ -9,10 +9,9 @@ import com.fastasyncworldedit.core.queue.Filter; import com.sk89q.worldedit.function.mask.AbstractExtentMask; import com.sk89q.worldedit.function.mask.Mask; -import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.IntVector; import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorOperators; -import jdk.incubator.vector.VectorSpecies; import java.util.Objects; import java.util.concurrent.atomic.AtomicInteger; @@ -69,7 +68,7 @@ public Filter fork() { return new MaskFilter<>(getParent().fork(), mask.copy(), changes); } - public static class VectorizedMaskFilter extends MaskFilter implements VectorizedFilter { + public static class VectorizedMaskFilter extends MaskFilter implements VectorizedFilter { private final VectorizedMask vectorizedMask; @@ -84,14 +83,14 @@ public VectorizedMaskFilter(final T other, final Mask root, AtomicInteger change } @Override - public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { - final T parent = getParent(); - final VectorSpecies species = mask.vectorSpecies(); - VectorMask masked = this.vectorizedMask.compareVector(set, get, species); - ShortVector before = set.getOrZero(masked.vectorSpecies()); + public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { + T parent = getParent(); + var species = mask.vectorSpecies(); + var masked = this.vectorizedMask.compareVector(set, get, species); + IntVector before = set.getOrZero(masked.vectorSpecies()); parent.applyVector(get, set, mask.and(masked)); - ShortVector after = set.getOrZero(masked.vectorSpecies()); - VectorMask changed = after.compare(VectorOperators.NE, before); + IntVector after = set.getOrZero(masked.vectorSpecies()); + var changed = after.compare(VectorOperators.NE, before); this.changes.getAndAdd(changed.trueCount()); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/DataArrayFilterBlock.java similarity index 91% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/DataArrayFilterBlock.java index 5e95261682..acca4d45a6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/CharFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/filter/block/DataArrayFilterBlock.java @@ -8,7 +8,8 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.implementation.Flood; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharGetBlocks; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArrayGetBlocks; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.math.BlockVector3; @@ -30,18 +31,18 @@ import static com.sk89q.worldedit.world.block.BlockTypesCache.states; @ApiStatus.NonExtendable -public class CharFilterBlock extends ChunkFilterBlock { +public class DataArrayFilterBlock extends ChunkFilterBlock { - private static final SetDelegate FULL = (block, value) -> block.setArr[block.index] = value; + private static final SetDelegate FULL = (block, value) -> block.setArr.setAt(block.index, value); private static final SetDelegate NULL = (block, value) -> block.initSet().set(block, value); private int maxLayer; private int minLayer; - protected CharGetBlocks get; + protected DataArrayGetBlocks get; protected IChunkSet set; - protected char[] getArr; + protected DataArray getArr; @Nullable - protected char[] setArr; + protected DataArray setArr; protected SetDelegate delegate; // local protected int layer; @@ -55,7 +56,7 @@ public class CharFilterBlock extends ChunkFilterBlock { private int chunkX; private int chunkZ; - public CharFilterBlock(Extent extent) { + public DataArrayFilterBlock(Extent extent) { super(extent); } @@ -70,12 +71,12 @@ public synchronized final ChunkFilterBlock initChunk(int chunkX, int chunkZ) { @Override public synchronized final ChunkFilterBlock initLayer(IBlocks iget, IChunkSet iset, int layer) { - this.get = (CharGetBlocks) iget; + this.get = (DataArrayGetBlocks) iget; minLayer = this.get.getMinSectionPosition(); maxLayer = this.get.getMaxSectionPosition(); this.layer = layer; if (!iget.hasSection(layer)) { - getArr = FaweCache.INSTANCE.EMPTY_CHAR_4096; + getArr = FaweCache.INSTANCE.EMPTY_DATA; } else { getArr = iget.load(layer); } @@ -233,29 +234,25 @@ public final int getChunkZ() { return chunkZ; } - public final char getOrdinalChar() { - return getArr[index]; - } - @Override public final int getOrdinal() { - return getArr[index]; + return getArr.getAt(index); } @Override public void setOrdinal(int ordinal) { - delegate.set(this, (char) ordinal); + delegate.set(this, ordinal); } @Override public final BlockState getBlock() { - final int ordinal = getArr[index]; + final int ordinal = getArr.getAt(index); return BlockTypesCache.states[ordinal]; } @Override public void setBlock(BlockState state) { - delegate.set(this, state.getOrdinalChar()); + delegate.set(this, state.getOrdinal()); } @Override @@ -318,7 +315,7 @@ public boolean hasNbtData() { @Override public final BlockState getBlockNorth() { if (z > 0) { - return states[getArr[index - 16]]; + return states[getArr.getAt(index - 16)]; } return getExtent().getBlock(x(), y(), z() - 1); } @@ -326,7 +323,7 @@ public final BlockState getBlockNorth() { @Override public final BlockState getBlockEast() { if (x < 15) { - return states[getArr[index + 1]]; + return states[getArr.getAt(index + 1)]; } return getExtent().getBlock(x() + 1, y(), z()); } @@ -334,7 +331,7 @@ public final BlockState getBlockEast() { @Override public final BlockState getBlockSouth() { if (z < 15) { - return states[getArr[index + 16]]; + return states[getArr.getAt(index + 16)]; } return getExtent().getBlock(x(), y(), z() + 1); } @@ -342,7 +339,7 @@ public final BlockState getBlockSouth() { @Override public final BlockState getBlockWest() { if (x > 0) { - return states[getArr[index - 1]]; + return states[getArr.getAt(index - 1)]; } return getExtent().getBlock(x() - 1, y(), z()); } @@ -350,7 +347,7 @@ public final BlockState getBlockWest() { @Override public final BlockState getBlockBelow() { if (y > 0) { - return states[getArr[index - 256]]; + return states[getArr.getAt(index - 256)]; } if (layer > minLayer) { final int newLayer = layer - 1; @@ -362,7 +359,7 @@ public final BlockState getBlockBelow() { @Override public final BlockState getBlockAbove() { if (y < 16) { - return states[getArr[index + 256]]; + return states[getArr.getAt(index + 256)]; } if (layer < maxLayer) { final int newLayer = layer + 1; @@ -376,7 +373,7 @@ public final BlockState getBlockRelativeY(int y) { final int newY = this.y + y; final int layerAdd = newY >> 4; if (layerAdd == 0) { - return states[getArr[this.index + (y << 8)]]; + return states[getArr.getAt(this.index + (y << 8))]; } else if ((layerAdd > 0 && layerAdd < (maxLayer - layer)) || (layerAdd < 0 && layerAdd < (minLayer - layer))) { final int newLayer = layer + layerAdd; final int index = (this.index + ((y & 15) << 8)) & 4095; @@ -434,7 +431,7 @@ public boolean setBiome(int x, int y, int z, BiomeType biome) { @ApiStatus.Internal protected interface SetDelegate { - void set(@Nonnull CharFilterBlock block, char value); + void set(@Nonnull DataArrayFilterBlock block, int value); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/PlacementStateProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/PlacementStateProcessor.java index 165a1b3159..01b0c2a18e 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/PlacementStateProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/PlacementStateProcessor.java @@ -12,6 +12,7 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.registry.state.PropertyKey; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.AbstractDelegateExtent; @@ -59,7 +60,7 @@ public abstract class PlacementStateProcessor extends AbstractDelegateExtent imp protected final Extent extent; protected final BlockTypeMask mask; protected final Region region; - protected final Map postCompleteSecondPasses; + protected final Map postCompleteSecondPasses; protected final ThreadLocal threadProcessors; protected final AtomicBoolean finished; private final MutableVector3 clickPos = new MutableVector3(); @@ -100,7 +101,7 @@ public PlacementStateProcessor(Extent extent, BlockTypeMask mask, Region region) protected PlacementStateProcessor( Extent extent, BlockTypeMask mask, - Map crossChunkSecondPasses, + Map crossChunkSecondPasses, ThreadLocal threadProcessors, Region region, AtomicBoolean finished @@ -220,7 +221,7 @@ private IChunkSet process() { Map setTiles = processChunkSet.tiles(); for (int layer = processChunkGet.getMinSectionPosition(); layer <= processChunkGet.getMaxSectionPosition(); layer++) { int layerY = layer << 4; - char[] set = processChunkSet.loadIfPresent(layer); + DataArray set = processChunkSet.loadIfPresent(layer); if (set == null) { continue; } @@ -235,7 +236,7 @@ private IChunkSet process() { private void checkAndPerformUpdate( Map setTiles, - char[] set, + DataArray set, int index, int blockY, boolean firstPass @@ -244,7 +245,7 @@ private void checkAndPerformUpdate( int blockZ = processChunkZ + z; for (int x = 0; x < 16; x++, index++) { int blockX = processChunkX + x; - char ordinal = set[index]; + int ordinal = set.getAt(index); BlockState state = BlockTypesCache.states[ordinal]; if (firstPass) { if (!IN_FIRST_PASS.test(state)) { @@ -264,7 +265,7 @@ private void checkAndPerformUpdate( blockZ, setTiles.isEmpty() ? null : ((BlockVector3ChunkMap) setTiles).remove(x, blockY, z) ), ordinal); - set[index] = BlockTypesCache.ReservedIDs.__RESERVED__; + set.setAt(index, BlockTypesCache.ReservedIDs.__RESERVED__); continue; } if (state.getBlockType().equals(BlockTypes.CHEST) || state.getBlockType().equals(BlockTypes.TRAPPED_CHEST)) { @@ -272,11 +273,11 @@ private void checkAndPerformUpdate( } else { placedBlock.setComponents(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); } - char newOrdinal = getBlockOrdinal(blockX, blockY, blockZ, state); + int newOrdinal = getBlockOrdinal(blockX, blockY, blockZ, state); if (newOrdinal == ordinal) { continue; } - set[index] = newOrdinal; + set.setAt(index, newOrdinal); } } } @@ -294,17 +295,17 @@ public void finish() { @Override public void flush() { finished.set(true); - for (Map.Entry entry : postCompleteSecondPasses.entrySet()) { + for (Map.Entry entry : postCompleteSecondPasses.entrySet()) { BlockState state; - char ordinal = entry.getValue(); + int ordinal = entry.getValue(); SecondPass secondPass = entry.getKey(); if (ordinal != 0) { state = BlockTypesCache.states[ordinal]; } else { state = extent.getBlock(secondPass.x, secondPass.y, secondPass.z); } - char newOrdinal = getBlockOrdinal(secondPass.x, secondPass.y, secondPass.z, state); - if (newOrdinal == state.getOrdinalChar() && ordinal == 0) { + int newOrdinal = getBlockOrdinal(secondPass.x, secondPass.y, secondPass.z, state); + if (newOrdinal == state.getOrdinal() && ordinal == 0) { continue; } if (secondPass.tile != null) { @@ -318,7 +319,7 @@ public void flush() { @Override public abstract PlacementStateProcessor fork(); - protected abstract char getStateAtFor( + protected abstract int getStateAtFor( int x, int y, int z, @@ -329,18 +330,18 @@ protected abstract char getStateAtFor( ); public BlockState getBlockStateAt(int x, int y, int z) { - Character ord = postCompleteSecondPasses.get(new SecondPass(x, y, z, null)); + Integer ord = postCompleteSecondPasses.get(new SecondPass(x, y, z, null)); if (ord != null && ord != 0) { return BlockTypesCache.states[ord]; } if (processChunkSet == null || (x & CHUNK_BLOCK_POS_MASK) != processChunkX || (z & CHUNK_BLOCK_POS_MASK) != processChunkZ) { return extent.getBlock(x, y, z); } - char[] set = processChunkSet.loadIfPresent(y >> 4); + DataArray set = processChunkSet.loadIfPresent(y >> 4); if (set == null) { return processChunkGet.getBlock(x & 15, y, z & 15); } - char ordinal = set[(y & 15) << 8 | (z & 15) << 4 | (x & 15)]; + int ordinal = set.getAt((y & 15) << 8 | (z & 15) << 4 | (x & 15)); if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { return processChunkGet.getBlock(x & 15, y, z & 15); } @@ -371,7 +372,7 @@ public BlockState getBlockStateAt(int x, int y, int z) { public LinCompoundTag getTileAt(int x, int y, int z) { SecondPass secondPass = new SecondPass(x, y, z, null); - Character ord = postCompleteSecondPasses.get(secondPass); + Integer ord = postCompleteSecondPasses.get(secondPass); if (ord != null && ord != 0) { // This should be rare enough... for (SecondPass pass : postCompleteSecondPasses.keySet()) { @@ -388,19 +389,19 @@ public LinCompoundTag getTileAt(int x, int y, int z) { if (tile != null) { return tile.linTag(); } - char[] set = processChunkSet.loadIfPresent(y >> 4); + DataArray set = processChunkSet.loadIfPresent(y >> 4); if (set == null) { return processChunkGet.getFullBlock(x & 15, y, z & 15).getNbt(); } - char ordinal = set[(y & 15) << 8 | (z & 15) << 4 | (x & 15)]; + int ordinal = set.getAt((y & 15) << 8 | (z & 15) << 4 | (x & 15)); if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { return processChunkGet.getFullBlock(x & 15, y, z & 15).getNbt(); } return BlockTypesCache.states[ordinal].getNbt(); } - private char getBlockOrdinal(int blockX, int blockY, int blockZ, BlockState state) { - char override = getOverrideBlockOrdinal(blockX, blockY, blockZ, state); + private int getBlockOrdinal(int blockX, int blockY, int blockZ, BlockState state) { + int override = getOverrideBlockOrdinal(blockX, blockY, blockZ, state); if (override != BlockTypesCache.ReservedIDs.__RESERVED__) { return override; } @@ -469,10 +470,10 @@ public void applyBlock(FilterBlock block) { return; } if (REQUIRES_SECOND_PASS.test(block.getBlock()) && ADJACENT_STAIR_MASK.test(extent, block)) { - postCompleteSecondPasses.put(new SecondPass(block), (char) 0); + postCompleteSecondPasses.put(new SecondPass(block), 0); } - char ordinal = (char) block.getOrdinal(); - char newOrdinal = getBlockOrdinal(block.x(), block.y(), block.z(), block.getBlock()); + int ordinal = block.getOrdinal(); + int newOrdinal = getBlockOrdinal(block.x(), block.y(), block.z(), block.getBlock()); if (ordinal != newOrdinal) { block.setBlock(BlockTypesCache.states[newOrdinal]); } @@ -488,10 +489,10 @@ public boolean apply(Extent orDefault, BlockVector3 get, BlockVector3 set) throw return false; } if (REQUIRES_SECOND_PASS.test(block) && ADJACENT_STAIR_MASK.test(extent, set)) { - postCompleteSecondPasses.put(new SecondPass(set), (char) 0); + postCompleteSecondPasses.put(new SecondPass(set), 0); return false; } - char newOrdinal = getBlockOrdinal(set.x(), set.y(), set.z(), block.toBlockState()); + int newOrdinal = getBlockOrdinal(set.x(), set.y(), set.z(), block.toBlockState()); if (block.getOrdinalChar() != newOrdinal) { BlockState newState = BlockTypesCache.states[newOrdinal]; orDefault.setBlock(set.x(), set.y(), set.z(), newState); @@ -511,10 +512,10 @@ public BaseBlock applyBlock(BlockVector3 position) { return block; } if (REQUIRES_SECOND_PASS.test(block) && ADJACENT_STAIR_MASK.test(extent, position)) { - postCompleteSecondPasses.put(new SecondPass(position), (char) 0); + postCompleteSecondPasses.put(new SecondPass(position), 0); return block; } - char newOrdinal = getBlockOrdinal(position.x(), position.y(), position.z(), block.toBlockState()); + int newOrdinal = getBlockOrdinal(position.x(), position.y(), position.z(), block.toBlockState()); if (block.getOrdinalChar() != newOrdinal) { BlockState state = BlockTypesCache.states[newOrdinal]; LinCompoundTag nbt = block.getNbt(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java index c677875c60..35bb35a4b6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/extent/processor/heightmap/HeightmapProcessor.java @@ -1,11 +1,11 @@ package com.fastasyncworldedit.core.extent.processor.heightmap; -import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; import com.fastasyncworldedit.core.queue.IBatchProcessor; import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; @@ -18,13 +18,9 @@ public class HeightmapProcessor implements IBatchProcessor { private static final HeightMapType[] TYPES = HeightMapType.values(); private static final int BLOCKS_PER_Y_SHIFT = 8; // log2(256) private static final int BLOCKS_PER_Y = 256; // 16 x 16 - private static final char[] AIR_LAYER = new char[4096]; + private static final DataArray AIR_LAYER = DataArray.createFilled(BlockTypesCache.ReservedIDs.AIR); private static final int NEEDED_UPDATES = TYPES.length * BLOCKS_PER_Y; - static { - Arrays.fill(AIR_LAYER, (char) BlockTypesCache.ReservedIDs.AIR); - } - private final int minY; private final int maxY; @@ -57,21 +53,21 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { if (!(hasSectionSet || hasSectionGet)) { continue; } - char[] setSection = hasSectionSet ? set.loadIfPresent(layer) : null; - if (setSection == null || Arrays.equals(setSection, FaweCache.INSTANCE.EMPTY_CHAR_4096) || - Arrays.equals(setSection, AIR_LAYER)) { + DataArray setSection = hasSectionSet ? set.loadIfPresent(layer) : null; + if (setSection == null || setSection.isEmpty() || + setSection.equals(AIR_LAYER)) { hasSectionSet = false; } if (!hasSectionSet && !hasSectionGet) { continue; } - char[] getSection = null; + DataArray getSection = null; for (int y = 15; y >= 0; y--) { // We don't need to actually iterate over x and z as we're both reading and writing an index for (int j = 0; j < BLOCKS_PER_Y; j++) { - char ordinal = BlockTypesCache.ReservedIDs.__RESERVED__; + int ordinal = BlockTypesCache.ReservedIDs.__RESERVED__; if (hasSectionSet) { - ordinal = setSection[index(y, j)]; + ordinal = setSection.getAt(index(y, j)); } if (ordinal == BlockTypesCache.ReservedIDs.__RESERVED__) { if (!hasSectionGet) { @@ -82,8 +78,8 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { } else if (getSection == null) { getSection = get.load(layer); // skip empty layer - if (Arrays.equals(getSection, FaweCache.INSTANCE.EMPTY_CHAR_4096) - || Arrays.equals(getSection, AIR_LAYER)) { + if (getSection.isEmpty() + || getSection.equals(AIR_LAYER)) { hasSectionGet = false; if (!hasSectionSet) { continue layerIter; @@ -91,7 +87,7 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { continue; } } - ordinal = getSection[index(y, j)]; + ordinal = getSection.getAt(index(y, j)); } // fast skip if block isn't relevant for any height map (air or empty) if (ordinal < 4) { @@ -128,6 +124,38 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { return set; } + private void skipOrUpdateHeightmap( + final IChunkGet get, + final int[][] heightmaps, + final boolean[][] updated, + final int skip, + final int layer, + final int y, + final int j, + final BlockState state, + final int ordinal + ) { + // fast skip if block isn't relevant for any height map (air or empty) + if (ordinal < 4) { + return; + } + if (state == null) { + return; + } + for (int i = 0; i < TYPES.length; i++) { + if ((skip & (1 << i)) != 0) { + continue; // skip finished height map + } + HeightMapType type = TYPES[i]; + // ignore if that position was already set + if (!updated[i][j] && type.includes(state)) { + // mc requires + 1, heightmaps are normalized internally, thus we need to "zero" them. + heightmaps[i][j] = ((layer - get.getMinSectionPosition()) << 4) + y + 1; + updated[i][j] = true; // mark as updated + } + } + } + @Override @Nullable public Extent construct(Extent child) { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/ChangePopulator.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/ChangePopulator.java index 84424d9488..a75d0e6e21 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/ChangePopulator.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/change/ChangePopulator.java @@ -14,7 +14,6 @@ public interface ChangePopulator { static ChangePopulator empty() { class Empty implements ChangePopulator { - private static final Empty EMPTY = new Empty(); @Override public @NotNull C create() { @@ -36,7 +35,7 @@ public boolean accepts(final Change change) { return false; } } - return Empty.EMPTY; + return new Empty(); } @SuppressWarnings("unchecked") diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java index 5fc68b6b4b..ddfef44902 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/history/changeset/AbstractChangeSet.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.NbtUtils; import com.fastasyncworldedit.core.util.TaskManager; import com.google.common.util.concurrent.Futures; @@ -166,15 +167,18 @@ public final synchronized IChunkSet processSet(IChunk chunk, IChunkGet get, IChu if (!set.hasSection(layer)) { continue; } + // add each block and tile - // assume "get" is a copy and doesn't get modified further - char[] blocksGet = get.load(layer); - if (blocksGet == null) { - blocksGet = FaweCache.INSTANCE.EMPTY_CHAR_4096; + DataArray blocksGet; + DataArray tmpGet = get.load(layer); + if (tmpGet == null) { + blocksGet = FaweCache.INSTANCE.EMPTY_DATA; + } else { + blocksGet = DataArray.createCopy(tmpGet); } // assume "set" is a copy and doesn't get modified further // loadIfPresent shouldn't be null if set.hasSection(layer) is true - char[] blocksSet = Objects.requireNonNull(set.loadIfPresent(layer)); + DataArray blocksSet = Objects.requireNonNull(set.loadIfPresent(layer)); // Account for negative layers int by = layer << 4; @@ -183,10 +187,10 @@ public final synchronized IChunkSet processSet(IChunk chunk, IChunkGet get, IChu for (int z = 0; z < 16; z++) { int zz = z + bz; for (int x = 0; x < 16; x++, index++) { - final int combinedTo = blocksSet[index]; + final int combinedTo = blocksSet.getAt(index); if (combinedTo != BlockTypesCache.ReservedIDs.__RESERVED__) { int xx = bx + x; - int from = blocksGet[index]; + int from = blocksGet.getAt(index); if (from == BlockTypesCache.ReservedIDs.__RESERVED__) { from = BlockTypesCache.ReservedIDs.AIR; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java index 8adca710a2..ea8636f5cb 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/SimdSupport.java @@ -13,7 +13,7 @@ import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockTypesCache; -import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.IntVector; import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorOperators; import org.apache.logging.log4j.Logger; @@ -70,16 +70,16 @@ public static boolean useVectorApi() { }; } - private static VectorizedMask vectorizedTargetMaskNonAir() { + private static VectorizedMask vectorizedTargetMaskNonAir() { // everything > VOID_AIR is not air - return (set, get, species) -> get.get(species).compare(VectorOperators.UNSIGNED_GT, BlockTypesCache.ReservedIDs.VOID_AIR); + return (set, get, species) -> get.get(species).compare(VectorOperators.UGE, BlockTypesCache.ReservedIDs.VOID_AIR); } - private static VectorizedMask vectorizedTargetMask(char ordinal) { + private static VectorizedMask vectorizedTargetMask(char ordinal) { return (set, get, species) -> get.get(species).compare(VectorOperators.EQ, (short) ordinal); } - private static VectorizedMask vectorizedTargetMaskInverse(char ordinal) { + private static VectorizedMask vectorizedTargetMaskInverse(char ordinal) { return (set, get, species) -> get.get(species).compare(VectorOperators.NE, (short) ordinal); } @@ -117,10 +117,10 @@ public Filter newInstance(final Filter other) { } @Override - public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { - ShortVector s = set.getOrZero(mask.vectorSpecies()); + public void applyVector(final VectorFacade get, final VectorFacade set, final VectorMask mask) { + IntVector s = set.getOrZero(mask.vectorSpecies()); // only change the lanes the mask dictates us to change, keep the rest - s = s.blend(ShortVector.broadcast(ShortVector.SPECIES_PREFERRED, ordinal), mask); + s = s.blend(IntVector.broadcast(s.species(), ordinal), mask); set.setOrIgnore(s); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorFacade.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorFacade.java index 18eeb1f6f6..098c182a73 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorFacade.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorFacade.java @@ -1,8 +1,9 @@ package com.fastasyncworldedit.core.internal.simd; import com.fastasyncworldedit.core.queue.IBlocks; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.world.block.BlockTypesCache; -import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.IntVector; import jdk.incubator.vector.VectorSpecies; import org.jetbrains.annotations.ApiStatus; @@ -11,34 +12,34 @@ public class VectorFacade { private final IBlocks blocks; private int layer; private int index; - private char[] data; + private DataArray data; VectorFacade(final IBlocks blocks) { this.blocks = blocks; } - public ShortVector get(VectorSpecies species) { + public IntVector get(VectorSpecies species) { if (this.data == null) { load(); } - return ShortVector.fromCharArray(species, this.data, this.index); + return this.data.loadAt(species, this.index); } - public ShortVector getOrZero(VectorSpecies species) { + public IntVector getOrZero(VectorSpecies species) { if (this.data == null) { - return ShortVector.zero(species); + return IntVector.zero(species); } - return ShortVector.fromCharArray(species, this.data, this.index); + return this.data.loadAt(species, this.index); } - public void setOrIgnore(ShortVector vector) { + public void setOrIgnore(IntVector vector) { if (this.data == null) { - if (vector.eq((short) BlockTypesCache.ReservedIDs.__RESERVED__).allTrue()) { + if (vector.eq(BlockTypesCache.ReservedIDs.__RESERVED__).allTrue()) { return; } load(); } - vector.intoCharArray(this.data, this.index); + this.data.storeAt(this.index, vector); } private void load() { @@ -54,7 +55,7 @@ public void setIndex(int index) { this.index = index; } - public void setData(char[] data) { + public void setData(DataArray data) { this.data = data; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java index 581430f0f8..226ec33422 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedCharFilterBlock.java @@ -1,13 +1,16 @@ package com.fastasyncworldedit.core.internal.simd; -import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock; +import com.fastasyncworldedit.core.extent.filter.block.DataArrayFilterBlock; import com.fastasyncworldedit.core.queue.Filter; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.extent.Extent; +import jdk.incubator.vector.IntVector; import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.Vector; import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorSpecies; -public class VectorizedCharFilterBlock extends CharFilterBlock { +public class VectorizedCharFilterBlock extends DataArrayFilterBlock { public VectorizedCharFilterBlock(final Extent extent) { super(extent); @@ -23,17 +26,18 @@ public synchronized void filter(final Filter filter, final int startY, final int if (!(filter instanceof VectorizedFilter vecFilter)) { throw new IllegalStateException("Unexpected VectorizedCharFilterBlock " + filter); } - final VectorSpecies species = ShortVector.SPECIES_PREFERRED; - VectorFacade setFassade = new VectorFacade(this.set); - setFassade.setLayer(this.layer); + final VectorSpecies species = IntVector.SPECIES_PREFERRED; + VectorFacade setFacade = new VectorFacade(this.set); + setFacade.setLayer(this.layer); VectorFacade getFassade = new VectorFacade(this.get); getFassade.setLayer(this.layer); getFassade.setData(this.getArr); - VectorMask affectAll = species.maskAll(true); + VectorMask affectAll = species.maskAll(true); for (int i = startY << 8; i < ((endY + 1) << 8) - 1; i += species.length()) { - setFassade.setIndex(i); + setFacade.setIndex(i); getFassade.setIndex(i); - vecFilter.applyVector(getFassade, setFassade, affectAll); + vecFilter.applyVector(getFassade, setFacade, affectAll); } } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java index 1a7ad40048..6c741a0aaa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedFilter.java @@ -12,6 +12,6 @@ public interface VectorizedFilter extends Filter { * @param set the set vector * @param mask the mask with the lanes set to true which should be affected by the filter */ - void applyVector(VectorFacade get, VectorFacade set, VectorMask mask); + void applyVector(VectorFacade get, VectorFacade set, VectorMask mask); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java index 9f44f2fb72..5985d3cb86 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/internal/simd/VectorizedMask.java @@ -3,35 +3,37 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.world.block.BlockTypesCache; -import jdk.incubator.vector.ShortVector; +import jdk.incubator.vector.IntVector; import jdk.incubator.vector.VectorMask; import jdk.incubator.vector.VectorSpecies; public interface VectorizedMask { default void processChunks(IChunk chunk, IChunkGet get, IChunkSet set) { - VectorFacade setFassade = new VectorFacade(set); - VectorFacade getFassade = new VectorFacade(get); + VectorFacade setFacade = new VectorFacade(set); + VectorFacade getFacade = new VectorFacade(get); for (int layer = get.getMinSectionPosition(); layer <= get.getMaxSectionPosition(); layer++) { - setFassade.setLayer(layer); - getFassade.setLayer(layer); - final char[] sectionSet = set.loadIfPresent(layer); + setFacade.setLayer(layer); + getFacade.setLayer(layer); + final DataArray sectionSet = set.loadIfPresent(layer); if (sectionSet == null) { continue; } - setFassade.setData(sectionSet); - processSection(layer, setFassade, getFassade); + setFacade.setData(sectionSet); + processSection(layer, setFacade, getFacade); } } default void processSection(int layer, VectorFacade set, VectorFacade get) { - final VectorSpecies species = ShortVector.SPECIES_PREFERRED; + final VectorSpecies species = IntVector.SPECIES_PREFERRED; // assume that chunk sections have length 16 * 16 * 16 == 4096 for (int i = 0; i < 4096; i += species.length()) { set.setIndex(i); get.setIndex(i); processVector(set, get, species); + } } @@ -42,8 +44,8 @@ default void processSection(int layer, VectorFacade set, VectorFacade get) { * @param get the get vector * @param species the species to use */ - default void processVector(VectorFacade set, VectorFacade get, VectorSpecies species) { - ShortVector s = set.getOrZero(species); + default void processVector(VectorFacade set, VectorFacade get, VectorSpecies species) { + IntVector s = set.getOrZero(species); s = s.blend(BlockTypesCache.ReservedIDs.__RESERVED__, compareVector(set, get, species).not()); set.setOrIgnore(s); } @@ -55,6 +57,6 @@ default void processVector(VectorFacade set, VectorFacade get, VectorSpecies compareVector(VectorFacade set, VectorFacade get, VectorSpecies species); + VectorMask compareVector(VectorFacade set, VectorFacade get, VectorSpecies species); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BitArrayUnstretched.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BitArrayUnstretched.java index 94f1249254..523b1bf3a8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BitArrayUnstretched.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/math/BitArrayUnstretched.java @@ -1,5 +1,6 @@ package com.fastasyncworldedit.core.math; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.util.MathMan; public final class BitArrayUnstretched { @@ -108,7 +109,7 @@ public int[] toRaw(int[] buffer) { return buffer; } - public char[] toRaw(char[] buffer) { + public DataArray toRaw(DataArray buffer) { final long[] data = this.data; final int bitsPerEntry = this.bitsPerEntry; final int maxSeqLocIndex = this.maxSeqLocIndex; @@ -118,9 +119,9 @@ public char[] toRaw(char[] buffer) { for (int i = 0; i < longLen; i++) { long l = data[i]; char lastVal; - for (; localStart <= maxSeqLocIndex && arrI < buffer.length; localStart += bitsPerEntry) { + for (; localStart <= maxSeqLocIndex && arrI < DataArray.CHUNK_SECTION_SIZE; localStart += bitsPerEntry) { lastVal = (char) (l >>> localStart & this.mask); - buffer[arrI++] = lastVal; + buffer.setAt(arrI++, lastVal); } localStart = 0; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java index b2c62f9233..2be3818b1f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBatchProcessor.java @@ -3,6 +3,7 @@ import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor; import com.fastasyncworldedit.core.extent.processor.MultiBatchProcessor; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.util.NbtUtils; import com.sk89q.worldedit.WorldEdit; @@ -91,23 +92,19 @@ default boolean trimY(IChunkSet set, int minY, int maxY, final boolean keepInsid if (layer > minLayer && layer < maxLayer) { continue; } - char[] blocks = set.loadIfPresent(layer); + DataArray blocks = set.loadIfPresent(layer); if (blocks == null) { continue; } // When on the minimum layer (as defined by minY), remove blocks up to minY (exclusive) if (layer == minLayer) { int index = (minY & 15) << 8; - for (int i = 0; i < index; i++) { - blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + blocks.setRange(0, index, BlockTypesCache.ReservedIDs.__RESERVED__); } // When on the maximum layer (as defined by maxY), remove blocks above maxY (exclusive) if (layer == maxLayer) { int index = ((maxY & 15) + 1) << 8; - for (int i = index; i < blocks.length; i++) { - blocks[i] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + blocks.setRange(index, DataArray.CHUNK_SECTION_SIZE, BlockTypesCache.ReservedIDs.__RESERVED__); } set.setBlocks(layer, blocks); } @@ -137,19 +134,17 @@ default boolean trimY(IChunkSet set, int minY, int maxY, final boolean keepInsid continue; } if (layer == minLayer) { - char[] arr = set.loadIfPresent(layer); + DataArray arr = set.loadIfPresent(layer); if (arr != null) { int index = (minY & 15) << 8; - Arrays.fill(arr, index, 4096, (char) BlockTypesCache.ReservedIDs.__RESERVED__); + arr.setRange(index, DataArray.CHUNK_SECTION_SIZE, BlockTypesCache.ReservedIDs.__RESERVED__); } set.setBlocks(layer, arr); } else if (layer == maxLayer) { - char[] arr = set.loadIfPresent(layer); + DataArray arr = set.loadIfPresent(layer); if (arr != null) { int index = ((maxY + 1) & 15) << 8; - for (int i = 0; i < index; i++) { - arr[i] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + arr.setRange(0, index, BlockTypesCache.ReservedIDs.__RESERVED__); } set.setBlocks(layer, arr); } else { diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java index 0ccf68eb72..c2c0f6a27c 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IBlocks.java @@ -5,6 +5,7 @@ import com.fastasyncworldedit.core.internal.io.FaweOutputStream; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; import com.fastasyncworldedit.core.util.collection.AdaptedMap; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Capability; @@ -56,7 +57,7 @@ default boolean hasNonEmptySection(int layer) { * @param layer chunk section layer (may be negative) * @return char array of ordinals of the chunk section */ - char[] load(int layer); + DataArray load(int layer); /** * Obtain the specified chunk section stored as an array of ordinals if present or null. Uses normal minecraft chunk-section @@ -66,7 +67,7 @@ default boolean hasNonEmptySection(int layer) { * @return char array of ordinals of the chunk section if present */ @Nullable - char[] loadIfPresent(int layer); + DataArray loadIfPresent(int layer); BlockState getBlock(int x, int y, int z); @@ -163,14 +164,14 @@ default byte[] toByteArray(byte[] buffer, int bitMask, boolean full, boolean str continue; } - char[] ids = this.load(layer); + DataArray ids = this.load(layer); int nonEmpty = 0; // TODO optimize into same loop as toPalette - for (int i = 0; i < ids.length; i++) { - char ordinal = ids[i]; + for (int i = 0; i < DataArray.CHUNK_SECTION_SIZE; i++) { + int ordinal = ids.getAt(i); switch (ordinal) { case BlockTypesCache.ReservedIDs.__RESERVED__, BlockTypesCache.ReservedIDs.CAVE_AIR, BlockTypesCache.ReservedIDs.VOID_AIR: - ids[i] = BlockTypesCache.ReservedIDs.AIR; + ids.setAt(i, BlockTypesCache.ReservedIDs.AIR); case BlockTypesCache.ReservedIDs.AIR: continue; default: diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java index 7d24186fc4..516b10ba5f 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/IChunkSet.java @@ -2,6 +2,7 @@ import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.extent.OutputExtent; @@ -34,7 +35,7 @@ default boolean setBiome(BlockVector3 position, BiomeType biome) { @Override > boolean setBlock(int x, int y, int z, T holder); - void setBlocks(int layer, char[] data); + void setBlocks(int layer, DataArray data); boolean isEmpty(); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java index ef9eab52bc..ebaf505a8a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/SingleThreadQueueExtent.java @@ -3,7 +3,7 @@ import com.fastasyncworldedit.core.Fawe; import com.fastasyncworldedit.core.configuration.Settings; import com.fastasyncworldedit.core.extent.PassthroughExtent; -import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock; +import com.fastasyncworldedit.core.extent.filter.block.DataArrayFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.processor.EmptyBatchProcessor; import com.fastasyncworldedit.core.extent.processor.ExtentBatchProcessorHolder; @@ -14,7 +14,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueExtent; -import com.fastasyncworldedit.core.queue.implementation.blocks.CharSetBlocks; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArraySetBlocks; import com.fastasyncworldedit.core.queue.implementation.chunk.ChunkHolder; import com.fastasyncworldedit.core.queue.implementation.chunk.NullChunk; import com.fastasyncworldedit.core.util.MathMan; @@ -193,7 +193,7 @@ public synchronized void init(Extent extent, IChunkCache get, IChunkC }; } if (set == null) { - set = CharSetBlocks::newInstance; + set = DataArraySetBlocks::newInstance; } this.cacheGet = get; this.cacheSet = set; @@ -210,6 +210,7 @@ public synchronized void init(Extent extent, IChunkCache get, IChunkC } } + @Override public int size() { return chunks.size() + submissions.size(); @@ -508,7 +509,7 @@ public synchronized void flush() { @Override public ChunkFilterBlock createFilterBlock() { - return new CharFilterBlock(this); + return new DataArrayFilterBlock(this); } @Override diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java index f77cc32868..782c61fb98 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/BitSetBlocks.java @@ -67,14 +67,14 @@ public > boolean setBlock(int x, int y, int z, T h } @Override - public void setBlocks(int layer, char[] data) { + public void setBlocks(int layer, final DataArray data) { layer -= minSectionPosition; row.reset(layer); int by = layer << 4; for (int y = 0, index = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { for (int x = 0; x < 16; x++, index++) { - if (data[index] != BlockTypesCache.ReservedIDs.__RESERVED__) { + if (data.getAt(index) != BlockTypesCache.ReservedIDs.__RESERVED__) { row.set(null, x, by + y, z, minSectionPosition, maxSectionPosition); } } @@ -137,9 +137,9 @@ public BlockState getBlock(int x, int y, int z) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= minSectionPosition; - char[] arr = FaweCache.INSTANCE.SECTION_BITS_TO_CHAR.get(); + DataArray array = DataArray.createEmpty(); MemBlockSet.IRow nullRowY = row.getRow(layer); if (nullRowY instanceof MemBlockSet.RowY rowY) { char value = blockState.getOrdinalChar(); @@ -149,14 +149,14 @@ public char[] load(int layer) { long bitBuffer = bits[longIndex]; if (bitBuffer != 0) { if (bitBuffer == -1L) { - Arrays.fill(arr, blockIndex, blockIndex + 64, value); + array.setRange(blockIndex, blockIndex + 64, value); continue; } - Arrays.fill(arr, Character.MIN_VALUE); + array.setAll(Character.MIN_VALUE); do { final long lowBit = Long.lowestOneBit(bitBuffer); final int bitIndex = Long.bitCount(lowBit - 1); - arr[blockIndex + bitIndex] = value; + array.setAt(blockIndex + bitIndex, value); bitBuffer = bitBuffer ^ lowBit; } while (bitBuffer != 0); } @@ -164,13 +164,13 @@ public char[] load(int layer) { } } } - return arr; + return array; } // No need to do anything different @Nullable @Override - public char[] loadIfPresent(final int layer) { + public DataArray loadIfPresent(final int layer) { return load(layer); } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArray.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArray.java new file mode 100644 index 0000000000..4ec5e31a99 --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArray.java @@ -0,0 +1,99 @@ +package com.fastasyncworldedit.core.queue.implementation.blocks; + +import jdk.incubator.vector.IntVector; +import jdk.incubator.vector.VectorSpecies; + +/** + * This interface represents the block states stored in a chunk section. + * It provides methods for efficient bulk operations. + */ +public sealed interface DataArray permits MemorySegmentBasedDataArray { + DataArray EMPTY = new MemorySegmentBasedDataArray(true); + + /** + * The amount of entries in a {@link DataArray}. + */ + int CHUNK_SECTION_SIZE = 16 * 16 * 16; + + /** + * Creates a new {@link DataArray} with all entries set to {@code 0}. + * + * @return an empty {@link DataArray}. + */ + static DataArray createEmpty() { + return new MemorySegmentBasedDataArray(false); + } + + /** + * @param value the value to set all entries to. + * {@return a {@link DataArray} with all entries set to the given value} + */ + static DataArray createFilled(int value) { + final DataArray array = createEmpty(); + array.setAll(value); + return array; + } + + /** + * @param other the {@link DataArray} to copy. + * @return a copy of the given {@link DataArray}. + */ + static DataArray createCopy(DataArray other) { + final DataArray array = createEmpty(); + other.copyInto(array); + return array; + } + + /** + * @param index the index to look up. + * @return the value at the given index. + */ + int getAt(int index); + + /** + * Sets the value at the given index to the given value. + * + * @param index the index to set. + * @param value the value to set at the index. + * @throws IndexOutOfBoundsException if {@code index > } {@value CHUNK_SECTION_SIZE} + * or {@code index < 0}. + */ + void setAt(int index, int value); + + /** + * Sets all values in the given range to the given value. + * + * @param start the start of the range to set, inclusive. + * @param end the end of the range to set, exclusive + * @param value the value to set all entries in the given range to. + * @throws IndexOutOfBoundsException if {@code start > } {@value CHUNK_SECTION_SIZE} + * or {@code start < 0} + * or {@code end + 1 > } {@value CHUNK_SECTION_SIZE} + * or {@code end < 0}. + */ + void setRange(int start, int end, int value); + + /** + * Sets all entries to the given value. + * This is equivalent to calling {@link #setRange(int, int, int) setRange(0, CHUNK_SECTION_SIZE, value) } + * + * @param value the value to set all entries to. + */ + void setAll(int value); + + /** + * Copies the data from this array into {@code other}. + * + * @param other the {@link DataArray} to copy the values from this array into. + */ + void copyInto(DataArray other); + + /** + * {@return {@code true} if all values are {@code 0}} + */ + boolean isEmpty(); + + IntVector loadAt(VectorSpecies species, int index); + void storeAt(int index, IntVector vector); + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayBlocks.java similarity index 69% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayBlocks.java index 3bbee7978b..d626a525b6 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayBlocks.java @@ -4,44 +4,44 @@ import com.fastasyncworldedit.core.queue.IBlocks; import com.fastasyncworldedit.core.queue.IChunkSet; import com.sk89q.worldedit.internal.util.LogManagerCompat; +import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; import org.apache.logging.log4j.Logger; import javax.annotation.Nullable; -import java.util.Arrays; -public abstract class CharBlocks implements IBlocks { +public abstract class DataArrayBlocks implements IBlocks { private static final Logger LOGGER = LogManagerCompat.getLogger(); protected static final Section FULL = new Section() { @Override - public char[] get(CharBlocks blocks, int layer, char[] arr) { + public DataArray get(DataArrayBlocks blocks, int layer, DataArray arr) { return arr; } // Ignore aggressive switch here. @Override - public char[] get(CharBlocks blocks, int layer, char[] arr, boolean aggressive) { + public DataArray get(DataArrayBlocks blocks, int layer, DataArray arr, boolean aggressive) { return arr; } }; protected static final Section EMPTY = new Section() { @Override - public char[] get(CharBlocks blocks, int layer, char[] arr) { + public DataArray get(DataArrayBlocks blocks, int layer, DataArray arr) { // Defaults to aggressive as it should only be avoided where we know we've reset a chunk during an edit return get(blocks, layer, arr, true); } @Override - public char[] get(CharBlocks blocks, int layer, char[] arr, boolean aggressive) { + public DataArray get(DataArrayBlocks blocks, int layer, DataArray arr, boolean aggressive) { synchronized (blocks.sectionLocks[layer]) { return update(blocks, layer, aggressive); } } }; - public char[][] blocks; + public DataArray[] blocks; public Object[] sectionLocks; protected int minSectionPosition; protected int maxSectionPosition; @@ -52,11 +52,11 @@ public char[] get(CharBlocks blocks, int layer, char[] arr, boolean aggressive) /** * New instance given initial min/max section indices. Can be negative. */ - public CharBlocks(int minSectionPosition, int maxSectionPosition) { + public DataArrayBlocks(int minSectionPosition, int maxSectionPosition) { this.minSectionPosition = minSectionPosition; this.maxSectionPosition = maxSectionPosition; this.sectionCount = maxSectionPosition - minSectionPosition + 1; - blocks = new char[sectionCount][]; + blocks = new DataArray[sectionCount]; sectionLocks = new Object[sectionCount]; for (int i = 0; i < sectionCount; i++) { sectionLocks[i] = new Object(); @@ -104,11 +104,11 @@ public void reset(int layer) { } } - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { if (data == null) { - return new char[4096]; + return DataArray.createEmpty(); } - Arrays.fill(data, defaultOrdinal()); + data.setAll(defaultOrdinal()); return data; } @@ -119,15 +119,15 @@ public boolean hasSection(int layer) { } @Override - public char[] load(int layer) { + public DataArray load(int layer) { layer -= minSectionPosition; - char[] data = blocks[layer]; + DataArray data = blocks[layer]; return (data == null ? EMPTY : FULL).get(this, layer, data); } @Nullable @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { if (layer < minSectionPosition || layer > maxSectionPosition) { return null; } @@ -155,7 +155,7 @@ public BlockState getBlock(int x, int y, int z) { return BlockTypesCache.states[get(x, y, z)]; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; if (layer > maxSectionPosition || layer < minSectionPosition) { @@ -180,7 +180,7 @@ public int getZ() { protected abstract char defaultOrdinal(); // Not synchronized as it refers to a synchronized method and includes nothing that requires synchronization - public void set(int x, int y, int z, char value) { + public void set(int x, int y, int z, int value) { final int layer = y >> 4; final int index = (y & 15) << 8 | z << 4 | x; try { @@ -196,20 +196,20 @@ public void set(int x, int y, int z, char value) { Section */ - public final char get(int layer, int index) { - char[] data = blocks[layer - minSectionPosition]; + public final int get(int layer, int index) { + DataArray data = blocks[layer - minSectionPosition]; return (data == null ? EMPTY : FULL).get(this, layer, index, data); } - public final void set(int layer, int index, char value) throws ArrayIndexOutOfBoundsException { - char[] data = blocks[layer - minSectionPosition]; + public final void set(int layer, int index, int value) throws ArrayIndexOutOfBoundsException { + DataArray data = blocks[layer - minSectionPosition]; (data == null ? EMPTY : FULL).set(this, layer, index, value, data); } public abstract static class Section { - static char[] update(CharBlocks blocks, int layer, boolean aggressive) { - char[] arr = blocks.blocks[layer]; + static DataArray update(DataArrayBlocks blocks, int layer, boolean aggressive) { + DataArray arr = blocks.blocks[layer]; if (arr == null) { arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive); if (arr == null) { @@ -224,21 +224,38 @@ static char[] update(CharBlocks blocks, int layer, boolean aggressive) { return arr; } - abstract char[] get(CharBlocks blocks, int layer, char[] data); + abstract DataArray get(DataArrayBlocks blocks, int layer, DataArray data); - abstract char[] get(CharBlocks blocks, int layer, char[] data, boolean aggressive); + abstract DataArray get(DataArrayBlocks blocks, int layer, DataArray data, boolean aggressive); - public final char get(CharBlocks blocks, int layer, int index, char[] data) { + public final int get(DataArrayBlocks blocks, int layer, int index, DataArray data) { int normalized = layer - blocks.minSectionPosition; - char[] section = get(blocks, normalized, data); - return section[index]; + DataArray section = get(blocks, normalized, data); + return section.getAt(index); } - public final void set(CharBlocks blocks, int layer, int index, char value, char[] data) { + public final void set(DataArrayBlocks blocks, int layer, int index, int value, DataArray data) { layer -= blocks.minSectionPosition; - get(blocks, layer, data)[index] = value; + get(blocks, layer, data).setAt(index, value); } } + static BiomeType getBiomeType( + final int x, + final int y, + final int z, + final BiomeType[][] biomes, + final int minSectionPosition, + final int maxSectionPosition + ) { + int layer; + if (biomes == null || (y >> 4) < minSectionPosition || (y >> 4) > maxSectionPosition) { + return null; + } else if (biomes[(layer = (y >> 4) - minSectionPosition)] == null) { + return null; + } + return biomes[layer][(y & 15) >> 2 | (z >> 2) << 2 | x >> 2]; + } + } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharGetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayGetBlocks.java similarity index 80% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharGetBlocks.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayGetBlocks.java index f39268cfe5..2d6f2225df 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharGetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArrayGetBlocks.java @@ -7,14 +7,12 @@ import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypesCache; -import java.util.Arrays; - -public abstract class CharGetBlocks extends CharBlocks implements IChunkGet { +public abstract class DataArrayGetBlocks extends DataArrayBlocks implements IChunkGet { /** * New instance given the min/max section indices */ - public CharGetBlocks(final int minSectionPosition, final int maxSectionPosition) { + public DataArrayGetBlocks(final int minSectionPosition, final int maxSectionPosition) { super(minSectionPosition, maxSectionPosition); } @@ -35,11 +33,11 @@ public boolean trim(boolean aggressive) { } @Override - public char[] update(int layer, char[] data, boolean aggressive) { + public DataArray update(int layer, DataArray data, boolean aggressive) { if (data == null) { - data = new char[4096]; + data = DataArray.createEmpty(); } - Arrays.fill(data, (char) BlockTypesCache.ReservedIDs.AIR); + data.setAll(BlockTypesCache.ReservedIDs.AIR); return data; } @@ -62,5 +60,4 @@ public IChunkSet reset() { super.reset(); return null; } - } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArraySetBlocks.java similarity index 91% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArraySetBlocks.java index c9c453127a..b2e391df2b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/CharSetBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/DataArraySetBlocks.java @@ -24,30 +24,30 @@ import java.util.Set; import java.util.UUID; -public class CharSetBlocks extends CharBlocks implements IChunkSet { +public class DataArraySetBlocks extends DataArrayBlocks implements IChunkSet { - private static final Pool POOL = FaweCache.INSTANCE.registerPool( - CharSetBlocks.class, - CharSetBlocks::new, Settings.settings().QUEUE.POOL + private static final Pool POOL = FaweCache.INSTANCE.registerPool( + DataArraySetBlocks.class, + DataArraySetBlocks::new, Settings.settings().QUEUE.POOL ); /** - * @deprecated Use {@link CharSetBlocks#newInstance(int, int)} + * @deprecated Use {@link DataArraySetBlocks#newInstance(int, int)} */ @Deprecated(forRemoval = true, since = "2.13.0") - public static CharSetBlocks newInstance() { + public static DataArraySetBlocks newInstance() { return POOL.poll(); } /** - * Create a new {@link CharSetBlocks} instance + * Create a new {@link DataArraySetBlocks} instance * * @param x chunk x * @param z chunk z * @return New pooled CharSetBlocks instance. */ - public static CharSetBlocks newInstance(int x, int z) { - CharSetBlocks set = POOL.poll(); + public static DataArraySetBlocks newInstance(int x, int z) { + DataArraySetBlocks set = POOL.poll(); set.init(x, z); return set; } @@ -63,7 +63,7 @@ public static CharSetBlocks newInstance(int x, int z) { private int bitMask = -1; private SideEffectSet sideEffectSet = SideEffectSet.defaults(); - private CharSetBlocks() { + private DataArraySetBlocks() { // Expand as we go super(0, 15); } @@ -81,13 +81,7 @@ public BiomeType[][] getBiomes() { @Override public BiomeType getBiomeType(int x, int y, int z) { - int layer; - if (biomes == null || (y >> 4) < minSectionPosition || (y >> 4) > maxSectionPosition) { - return null; - } else if (biomes[(layer = (y >> 4) - minSectionPosition)] == null) { - return null; - } - return biomes[layer][(y & 15) >> 2 | (z >> 2) << 2 | x >> 2]; + return getBiomeType(x, y, z, biomes, minSectionPosition, maxSectionPosition); } @Override @@ -138,7 +132,7 @@ public > boolean setBlock(int x, int y, int z, T h } @Override - public void setBlocks(int layer, char[] data) { + public void setBlocks(int layer, final DataArray data) { updateSectionIndexRange(layer); layer -= minSectionPosition; this.blocks[layer] = data; @@ -355,12 +349,11 @@ public boolean hasBiomes(int layer) { } @Override - public ThreadUnsafeCharBlocks createCopy() { - char[][] blocksCopy = new char[sectionCount][]; + public ThreadUnsafeDataArrayBlocks createCopy() { + DataArray[] blocksCopy = new DataArray[sectionCount]; for (int i = 0; i < sectionCount; i++) { if (blocks[i] != null) { - blocksCopy[i] = new char[FaweCache.INSTANCE.BLOCKS_PER_LAYER]; - System.arraycopy(blocks[i], 0, blocksCopy[i], 0, FaweCache.INSTANCE.BLOCKS_PER_LAYER); + blocksCopy[i] = DataArray.createCopy(blocks[i]); } } BiomeType[][] biomesCopy; @@ -377,7 +370,7 @@ public ThreadUnsafeCharBlocks createCopy() { } char[][] lightCopy = createLightCopy(light, sectionCount); char[][] skyLightCopy = createLightCopy(skyLight, sectionCount); - return new ThreadUnsafeCharBlocks( + return new ThreadUnsafeDataArrayBlocks( blocksCopy, minSectionPosition, maxSectionPosition, @@ -424,7 +417,7 @@ static char[][] createLightCopy(char[][] lightArr, int sectionCount) { } @Override - public char[] load(final int layer) { + public DataArray load(final int layer) { updateSectionIndexRange(layer); return super.load(layer); } @@ -453,7 +446,7 @@ private void updateSectionIndexRange(int layer) { } private void resizeSectionsArrays(int diff, boolean appendNew) { - char[][] tmpBlocks = new char[sectionCount][]; + DataArray[] tmpBlocks = new DataArray[sectionCount]; Object[] tmpSectionLocks = new Object[sectionCount]; int destPos = appendNew ? 0 : diff; System.arraycopy(blocks, 0, tmpBlocks, destPos, blocks.length); diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/MemorySegmentBasedDataArray.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/MemorySegmentBasedDataArray.java new file mode 100644 index 0000000000..8d47f93fcb --- /dev/null +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/MemorySegmentBasedDataArray.java @@ -0,0 +1,86 @@ +package com.fastasyncworldedit.core.queue.implementation.blocks; + +import com.sk89q.worldedit.world.block.BlockTypesCache; +import jdk.incubator.vector.IntVector; +import jdk.incubator.vector.VectorSpecies; + +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import java.nio.ByteOrder; + +final class MemorySegmentBasedDataArray implements DataArray { + private static final VarHandle ACCESSOR = createAccessor(); + + private static VarHandle createAccessor() { + VarHandle arrayElement = ValueLayout.JAVA_INT.arrayElementVarHandle(); + // we don't need the base offset, it's always zero in our case + arrayElement = MethodHandles.insertCoordinates(arrayElement, 1, 0L); + return arrayElement.withInvokeExactBehavior(); + } + + private final MemorySegment data; + + MemorySegmentBasedDataArray(boolean readOnly) { + MemorySegment segment = MemorySegment.ofArray(new long[CHUNK_SECTION_SIZE >> 1]); + this.data = readOnly ? segment.asReadOnly() : segment; + } + + @Override + public int getAt(final int index) { + return (int) ACCESSOR.get(this.data, (long) index); + } + + @Override + public void setAt(final int index, final int value) { + ACCESSOR.set(this.data, (long) index, value); + } + + @Override + public void setRange(final int start, final int end, final int value) { + for (int i = start; i < end; i++) { + setAt(i, value); + } + } + + @Override + public void setAll(final int value) { + if (value == 0) { + this.data.fill((byte) 0); + } else { + setRange(0, 4096, value); + } + } + + @Override + public void copyInto(final DataArray other) { + ((MemorySegmentBasedDataArray) other).data.copyFrom(this.data); + } + + @Override + public boolean isEmpty() { + for (long i = 0; i < this.data.byteSize() >> 3; i++) { + if (this.data.getAtIndex(ValueLayout.JAVA_LONG, i) != 0) { + return false; + } + } + return true; + } + + @Override + public IntVector loadAt(final VectorSpecies species, final int index) { + return IntVector.fromMemorySegment(species, this.data, index * 4L, ByteOrder.nativeOrder()); + } + + @Override + public void storeAt(final int index, final IntVector vector) { + vector.intoMemorySegment(this.data, index * 4L, ByteOrder.nativeOrder()); + } + + @Override + public boolean equals(final Object obj) { + return obj instanceof MemorySegmentBasedDataArray other && data.mismatch(other.data) < 0; + } + +} diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/NullChunkGet.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/NullChunkGet.java index eff8a42059..cc49d761d8 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/NullChunkGet.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/NullChunkGet.java @@ -143,13 +143,13 @@ public > T call(IQueueExtent owner, @Nonnu } @Nonnull - public char[] load(int layer) { - return FaweCache.INSTANCE.EMPTY_CHAR_4096; + public DataArray load(int layer) { + return FaweCache.INSTANCE.EMPTY_DATA; } @Nullable @Override - public char[] loadIfPresent(final int layer) { + public DataArray loadIfPresent(final int layer) { return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeDataArrayBlocks.java similarity index 89% rename from worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java rename to worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeDataArrayBlocks.java index d54d2b99d1..040f15678a 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeCharBlocks.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/blocks/ThreadUnsafeDataArrayBlocks.java @@ -1,7 +1,6 @@ package com.fastasyncworldedit.core.queue.implementation.blocks; import com.fastasyncworldedit.core.Fawe; -import com.fastasyncworldedit.core.FaweCache; import com.fastasyncworldedit.core.extent.processor.heightmap.HeightMapType; import com.fastasyncworldedit.core.math.BlockVector3ChunkMap; import com.fastasyncworldedit.core.nbt.FaweCompoundTag; @@ -28,20 +27,20 @@ import java.util.UUID; /** - * Equivalent to {@link CharSetBlocks} without any attempt to make thread-safe for improved performance. - * This is currently only used as a "copy" of {@link CharSetBlocks} to provide to + * Equivalent to {@link DataArraySetBlocks} without any attempt to make thread-safe for improved performance. + * This is currently only used as a "copy" of {@link DataArraySetBlocks} to provide to * {@link com.fastasyncworldedit.core.queue.IBatchProcessor} instances for processing without overlapping the continuing edit. * * @since 2.6.2 */ -public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { +public class ThreadUnsafeDataArrayBlocks implements IChunkSet, IBlocks { private static final Logger LOGGER = LogManagerCompat.getLogger(); private final char defaultOrdinal; private final int chunkX; private final int chunkZ; - private char[][] blocks; + private DataArray[] blocks; private int minSectionPosition; private int maxSectionPosition; private int sectionCount; @@ -57,12 +56,12 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { private SideEffectSet sideEffectSet; /** - * New instance given the data stored in a {@link CharSetBlocks} instance. + * New instance given the data stored in a {@link DataArraySetBlocks} instance. * * @since 2.6.2 */ - ThreadUnsafeCharBlocks( - char[][] blocks, + ThreadUnsafeDataArrayBlocks( + DataArray[] blocks, int minSectionPosition, int maxSectionPosition, BiomeType[][] biomes, @@ -102,23 +101,23 @@ public class ThreadUnsafeCharBlocks implements IChunkSet, IBlocks { @Override public boolean hasSection(int layer) { layer -= minSectionPosition; - return layer >= 0 && layer < blocks.length && blocks[layer] != null && blocks[layer].length == FaweCache.INSTANCE.BLOCKS_PER_LAYER; + return layer >= 0 && layer < blocks.length && blocks[layer] != null; } @Override - public char[] load(int layer) { + public DataArray load(int layer) { updateSectionIndexRange(layer); layer -= minSectionPosition; - char[] arr = blocks[layer]; + DataArray arr = blocks[layer]; if (arr == null) { - arr = blocks[layer] = new char[FaweCache.INSTANCE.BLOCKS_PER_LAYER]; + arr = blocks[layer] = DataArray.createEmpty(); } return arr; } @Nullable @Override - public char[] loadIfPresent(int layer) { + public DataArray loadIfPresent(int layer) { if (layer < minSectionPosition || layer > maxSectionPosition) { return null; } @@ -198,24 +197,18 @@ public int getZ() { return chunkZ; } - public char get(int x, int y, int z) { + public int get(int x, int y, int z) { int layer = (y >> 4); if (!hasSection(layer)) { return defaultOrdinal; } final int index = (y & 15) << 8 | z << 4 | x; - return blocks[layer - minSectionPosition][index]; + return blocks[layer - minSectionPosition].getAt(index); } @Override public BiomeType getBiomeType(int x, int y, int z) { - int layer; - if (biomes == null || (y >> 4) < minSectionPosition || (y >> 4) > maxSectionPosition) { - return null; - } else if (biomes[(layer = (y >> 4) - minSectionPosition)] == null) { - return null; - } - return biomes[layer][(y & 15) >> 2 | (z >> 2) << 2 | x >> 2]; + return DataArrayBlocks.getBiomeType(x, y, z, biomes, minSectionPosition, maxSectionPosition); } @Override @@ -246,7 +239,7 @@ public void set(int x, int y, int z, char value) { final int layer = (y >> 4) - minSectionPosition; final int index = (y & 15) << 8 | z << 4 | x; try { - blocks[layer][index] = value; + blocks[layer].setAt(index, value); } catch (ArrayIndexOutOfBoundsException exception) { LOGGER.error("Tried setting block at coordinates (" + x + "," + y + "," + z + ")"); assert Fawe.platform() != null; @@ -263,7 +256,7 @@ public > boolean setBlock(int x, int y, int z, T h } @Override - public void setBlocks(int layer, char[] data) { + public void setBlocks(int layer, DataArray data) { updateSectionIndexRange(layer); layer -= minSectionPosition; this.blocks[layer] = data; @@ -446,7 +439,7 @@ public boolean hasLight() { @Override public IChunkSet reset() { - blocks = new char[sectionCount][]; + blocks = new DataArray[sectionCount]; biomes = new BiomeType[sectionCount][]; light = new char[sectionCount][]; skyLight = new char[sectionCount][]; @@ -465,11 +458,12 @@ public boolean hasBiomes(int layer) { @Override public IChunkSet createCopy() { - char[][] blocksCopy = new char[sectionCount][]; + DataArray[] blocksCopy = new DataArray[sectionCount]; for (int i = 0; i < sectionCount; i++) { - blocksCopy[i] = new char[FaweCache.INSTANCE.BLOCKS_PER_LAYER]; if (blocks[i] != null) { - System.arraycopy(blocks[i], 0, blocksCopy[i], 0, FaweCache.INSTANCE.BLOCKS_PER_LAYER); + blocksCopy[i] = DataArray.createCopy(blocks[i]); + } else { + blocksCopy[i] = DataArray.createEmpty(); } } BiomeType[][] biomesCopy; @@ -484,9 +478,9 @@ public IChunkSet createCopy() { } } } - char[][] lightCopy = CharSetBlocks.createLightCopy(light, sectionCount); - char[][] skyLightCopy = CharSetBlocks.createLightCopy(skyLight, sectionCount); - return new ThreadUnsafeCharBlocks( + char[][] lightCopy = DataArraySetBlocks.createLightCopy(light, sectionCount); + char[][] skyLightCopy = DataArraySetBlocks.createLightCopy(skyLight, sectionCount); + return new ThreadUnsafeDataArrayBlocks( blocksCopy, minSectionPosition, maxSectionPosition, @@ -541,7 +535,7 @@ private void updateSectionIndexRange(int layer) { } private void resizeSectionsArrays(int layer, int diff, boolean appendNew) { - char[][] tmpBlocks = new char[sectionCount][]; + DataArray[] tmpBlocks = new DataArray[sectionCount]; int destPos = appendNew ? 0 : diff; System.arraycopy(blocks, 0, tmpBlocks, destPos, blocks.length); blocks = tmpBlocks; diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java index 2251ca0096..a1569f9eaa 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/ChunkHolder.java @@ -13,6 +13,7 @@ import com.fastasyncworldedit.core.util.MemUtil; import com.fastasyncworldedit.core.util.task.FaweThreadUtil; import com.sk89q.worldedit.entity.Entity; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.internal.util.LogManagerCompat; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; @@ -134,18 +135,18 @@ public char[][] getSkyLight() { } @Override - public void setBlocks(int layer, char[] data) { + public void setBlocks(int layer, DataArray data) { delegate.set(this).setBlocks(layer, data); } @Override - public char[] load(int layer) { + public DataArray load(int layer) { return getOrCreateGet().load(layer); } @Nullable @Override - public char[] loadIfPresent(final int layer) { + public DataArray loadIfPresent(final int layer) { if (chunkExisting == null) { return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java index f0966493c1..16b1abd76b 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/NullChunk.java @@ -8,6 +8,7 @@ import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueChunk; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.regions.Region; @@ -155,7 +156,8 @@ public > boolean setBlock(int x, int y, int z, T h return false; } - public void setBlocks(int layer, @Nonnull char[] data) { + @Override + public void setBlocks(int layer, @Nonnull DataArray data) { } @Nullable @@ -194,13 +196,13 @@ public BaseBlock getFullBlock(int x, int y, int z) { @Nullable - public char[] load(int layer) { + public DataArray load(int layer) { return null; } @Nullable @Override - public char[] loadIfPresent(final int layer) { + public DataArray loadIfPresent(final int layer) { return null; } diff --git a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/WrapperChunk.java b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/WrapperChunk.java index 025bd72d82..3d14411dda 100644 --- a/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/WrapperChunk.java +++ b/worldedit-core/src/main/java/com/fastasyncworldedit/core/queue/implementation/chunk/WrapperChunk.java @@ -9,6 +9,7 @@ import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; import com.fastasyncworldedit.core.queue.IQueueExtent; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.WorldEditException; import com.sk89q.worldedit.entity.Entity; @@ -184,7 +185,7 @@ public > boolean setBlock(final int x, final int y } @Override - public void setBlocks(final int layer, final char[] data) { + public void setBlocks(final int layer, final DataArray data) { getWrapped().setBlocks(layer, data); } @@ -409,12 +410,12 @@ public boolean hasNonEmptySection(final int layer) { } @Override - public char[] load(final int layer) { + public DataArray load(final int layer) { return getWrapped().load(layer); } @Override - public @Nullable char[] loadIfPresent(final int layer) { + public @Nullable DataArray loadIfPresent(final int layer) { return getWrapped().loadIfPresent(layer); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java index 42fc4610ab..efd35b7020 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/MaskingExtent.java @@ -20,7 +20,7 @@ package com.sk89q.worldedit.extent; import com.fastasyncworldedit.core.FaweCache; -import com.fastasyncworldedit.core.extent.filter.block.CharFilterBlock; +import com.fastasyncworldedit.core.extent.filter.block.DataArrayFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.ChunkFilterBlock; import com.fastasyncworldedit.core.extent.filter.block.FilterBlock; import com.fastasyncworldedit.core.extent.processor.ProcessorScope; @@ -65,7 +65,7 @@ public MaskingExtent(Extent extent, Mask mask) { this.mask = mask; this.vectorizedMask = SimdSupport.vectorizedTargetMask(mask); //FAWE start - this.getOrCreateFilterBlock = FaweCache.INSTANCE.createMainThreadSafeCache(() -> new CharFilterBlock(getExtent())); + this.getOrCreateFilterBlock = FaweCache.INSTANCE.createMainThreadSafeCache(() -> new DataArrayFilterBlock(getExtent())); //FAWE end } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java index 1917e68b25..bcd07dbaac 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/math/BlockVector3.java @@ -836,10 +836,6 @@ public int getOrdinal(Extent orDefault) { return getBlock(orDefault).getOrdinal(); } - public char getOrdinalChar(Extent orDefault) { - return (char) getOrdinal(orDefault); - } - public BlockState getBlock(Extent orDefault) { return orDefault.getBlock(this); } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java index 2c029ace72..c3223da11d 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/CuboidRegion.java @@ -27,6 +27,7 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.world.World; @@ -851,7 +852,7 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { if (!set.hasSection(layer)) { continue; } - char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true + DataArray arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true int indexY = 0; for (int y = 0; y < 16; y++, indexY += 256) { // For each y layer within a chunk section int index; @@ -859,34 +860,26 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { index = indexY; for (int z = 0; z < lowerZ; z++) { // null the z values - for (int x = 0; x < 16; x++, index++) { - arr[index] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + arr.setRange(index, index += 16, BlockTypesCache.ReservedIDs.__RESERVED__); } index = indexY + upperZi; for (int z = upperZ + 1; z < 16; z++) { // null the z values - for (int x = 0; x < 16; x++, index++) { - arr[index] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + arr.setRange(index, index += 16, BlockTypesCache.ReservedIDs.__RESERVED__); } } if (trimX) { index = indexY + lowerZi; // Skip blocks already removed by trimZ for (int z = lowerZ; z <= upperZ; z++, index += 16) { - for (int x = 0; x < lowerX; x++) { - // null the x values - arr[index + x] = BlockTypesCache.ReservedIDs.__RESERVED__; - } - for (int x = upperX + 1; x < 16; x++) { - // null the x values - arr[index + x] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + // null the x values + arr.setRange(index, index + lowerX, BlockTypesCache.ReservedIDs.__RESERVED__); + arr.setRange(index + upperX + 1, index + upperX + 16, BlockTypesCache.ReservedIDs.__RESERVED__); } } } set.setBlocks(layer, arr); } + final BlockVector3 chunkPos = BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4); trimNBT(set, this::contains, pos -> this.contains(pos.add(chunkPos))); return set; @@ -935,7 +928,7 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean if (!set.hasSection(layer)) { continue; } - char[] arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true + DataArray arr = Objects.requireNonNull(set.loadIfPresent(layer)); // This shouldn't be null if above is true if (!(trimX || trimZ)) { continue; } @@ -946,18 +939,14 @@ public IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean index = indexY; for (int z = lowerZ; z <= upperZ; z++) { // null the z values - for (int x = 0; x < 16; x++, index++) { - arr[index] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + arr.setRange(index, index += 16, BlockTypesCache.ReservedIDs.__RESERVED__); } } if (trimX) { index = indexY + lowerZi; // Skip blocks already removed by trimZ for (int z = lowerZ; z <= upperZ; z++, index += 16) { - for (int x = lowerX; x <= upperX; x++) { - // null the x values - arr[index + x] = BlockTypesCache.ReservedIDs.__RESERVED__; - } + // null the x values + arr.setRange(index + lowerX, index + upperX + 1, BlockTypesCache.ReservedIDs.__RESERVED__); } } } diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java index 0ba49a2f37..2943cafb8b 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/regions/Region.java @@ -29,6 +29,7 @@ import com.fastasyncworldedit.core.queue.IChunk; import com.fastasyncworldedit.core.queue.IChunkGet; import com.fastasyncworldedit.core.queue.IChunkSet; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.extension.platform.Capability; import com.sk89q.worldedit.extent.Extent; @@ -416,20 +417,11 @@ default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { int ty = by + 15; if (!containsEntireCuboid(bx, tx, by, ty, bz, tz)) { processExtra = true; - char[] arr = set.loadIfPresent(layer); + DataArray arr = set.loadIfPresent(layer); if (arr == null) { continue; } - for (int y = 0, index = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++, index++) { - if (arr[index] != BlockTypesCache.ReservedIDs.__RESERVED__ && !contains(bx + x, by + y, bz + z)) { - arr[index] = BlockTypesCache.ReservedIDs.__RESERVED__; - } - } - } - } - set.setBlocks(layer, arr); + processCuboid(set, layer, arr); } } if (processExtra) { @@ -442,6 +434,19 @@ default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set) { } } + private void processCuboid(IChunkSet set, int layer, DataArray dataArray) { + for (int y = 0, index = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++, index++) { + if (dataArray.getAt(index) != BlockTypesCache.ReservedIDs.__RESERVED__ && !contains(x, y, z)) { + dataArray.setAt(index, BlockTypesCache.ReservedIDs.__RESERVED__); + } + } + } + } + set.setBlocks(layer, dataArray); + } + /** * Process the chunk, with the option to process as if the region is a blacklisted region, and thus any contained blocks * should be removed, rather than uncontained blocks being removed. @@ -468,24 +473,11 @@ default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean int by = layer << 4; int ty = by + 15; if (containsEntireCuboid(bx, tx, by, ty, bz, tz)) { - set.setBlocks(layer, FaweCache.INSTANCE.EMPTY_CHAR_4096); + set.setBlocks(layer, FaweCache.INSTANCE.EMPTY_DATA); processExtra = true; continue; } - char[] arr = set.load(layer); - for (int y = 0, index = 0; y < 16; y++) { - for (int z = 0; z < 16; z++) { - for (int x = 0; x < 16; x++, index++) { - if (arr[index] != BlockTypesCache.ReservedIDs.__RESERVED__ && contains(x, y, z)) { - arr[index] = BlockTypesCache.ReservedIDs.__RESERVED__; - processExtra = true; - } - } - } - } - if (processExtra) { - set.setBlocks(layer, arr); - } + processExtra = processPartial(set, processExtra, layer, set.load(layer)); } if (processExtra) { BlockVector3 chunkPos = chunk.getChunkBlockCoord().withY(0); @@ -497,6 +489,23 @@ default IChunkSet processSet(IChunk chunk, IChunkGet get, IChunkSet set, boolean } } + private boolean processPartial(IChunkSet set, boolean processExtra, int layer, DataArray arr) { + for (int y = 0, index = 0; y < 16; y++) { + for (int z = 0; z < 16; z++) { + for (int x = 0; x < 16; x++, index++) { + if (arr.getAt(index) != BlockTypesCache.ReservedIDs.__RESERVED__ && contains(x, y, z)) { + arr.setAt(index, BlockTypesCache.ReservedIDs.__RESERVED__); + processExtra = true; + } + } + } + } + if (processExtra) { + set.setBlocks(layer, arr); + } + return processExtra; + } + @Override default Extent construct(Extent child) { if (isGlobal()) { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java index 65179fab25..a332802eed 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BaseBlock.java @@ -215,11 +215,6 @@ public BlockMaterial getMaterial() { public int getOrdinal() { return blockState.getOrdinal(); } - - @Override - public final char getOrdinalChar() { - return blockState.getOrdinalChar(); - } //FAWE end /** diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java index 54424c2ee8..da57129e13 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockState.java @@ -66,7 +66,6 @@ public class BlockState implements BlockStateHolder, Pattern { //FAWE start private final int internalId; private final int ordinal; - private final char ordinalChar; private BlockMaterial material; private final BaseBlock emptyBaseBlock; private CompoundInput compoundInput = CompoundInput.NULL; @@ -79,7 +78,6 @@ public BlockState(BlockType blockType, int internalId, int ordinal) { this.blockType = blockType; this.internalId = internalId; this.ordinal = ordinal; - this.ordinalChar = (char) ordinal; this.emptyBaseBlock = new BlanketBaseBlock(this); this.lazyStringRepresentation = LazyReference.from(BlockStateHolder.super::getAsString); } @@ -88,7 +86,6 @@ public BlockState(BlockType blockType, int internalId, int ordinal, @Nonnull Com this.blockType = blockType; this.internalId = internalId; this.ordinal = ordinal; - this.ordinalChar = (char) ordinal; this.emptyBaseBlock = new BlanketBaseBlock(this, tile); this.lazyStringRepresentation = LazyReference.from(BlockStateHolder.super::getAsString); } @@ -477,11 +474,6 @@ public final int getOrdinal() { return this.ordinal; } - @Override - public final char getOrdinalChar() { - return this.ordinalChar; - } - @Override public int hashCode() { return getOrdinal(); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java index 5145fc0d28..55673126d6 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/block/BlockStateHolder.java @@ -66,9 +66,6 @@ public interface BlockStateHolder> extends TileEnt @Deprecated int getOrdinal(); - @Deprecated - char getOrdinalChar(); - BlockMaterial getMaterial(); /** diff --git a/worldedit-core/src/test/java/com/fastasyncworldedit/core/queue/IBatchProcessorTest.java b/worldedit-core/src/test/java/com/fastasyncworldedit/core/queue/IBatchProcessorTest.java index e28d0d236f..1369f4ac3a 100644 --- a/worldedit-core/src/test/java/com/fastasyncworldedit/core/queue/IBatchProcessorTest.java +++ b/worldedit-core/src/test/java/com/fastasyncworldedit/core/queue/IBatchProcessorTest.java @@ -1,17 +1,20 @@ package com.fastasyncworldedit.core.queue; +import com.fastasyncworldedit.core.queue.implementation.blocks.DataArray; import com.sk89q.worldedit.extent.Extent; -import com.sk89q.worldedit.world.block.BlockTypesCache; import org.jetbrains.annotations.Nullable; +import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.parallel.Isolated; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; +import org.opentest4j.AssertionFailedError; -import java.util.Arrays; import java.util.stream.Stream; +import static com.sk89q.worldedit.world.block.BlockTypesCache.ReservedIDs.AIR; +import static com.sk89q.worldedit.world.block.BlockTypesCache.ReservedIDs.__RESERVED__; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.Mockito.*; @@ -21,15 +24,18 @@ class IBatchProcessorTest { @Isolated class trimY { - private static final char[] CHUNK_DATA = new char[16 * 16 * 16]; - private static final char[] SLICE_AIR = new char[16 * 16]; - private static final char[] SLICE_RESERVED = new char[16 * 16]; + static { + // this must happen before DataArray/CharDataArray is initialized + System.setProperty("fawe.test", "true"); + } + + private static final DataArray CHUNK_DATA = DataArray.createFilled(AIR); private final IBatchProcessor processor = new NoopBatchProcessor(); - static { - Arrays.fill(CHUNK_DATA, (char) BlockTypesCache.ReservedIDs.AIR); - Arrays.fill(SLICE_AIR, (char) BlockTypesCache.ReservedIDs.AIR); - Arrays.fill(SLICE_RESERVED, (char) BlockTypesCache.ReservedIDs.__RESERVED__); + @AfterAll + static void tearDown() { + // remove again + System.getProperties().remove("fawe.test"); } @ParameterizedTest @@ -37,9 +43,9 @@ class trimY { void testFullChunkSelectedInBoundedRegion(int minY, int maxY, int minSection, int maxSection) { final IChunkSet set = mock(); - char[][] sections = new char[(320 + 64) >> 4][CHUNK_DATA.length]; - for (final char[] chars : sections) { - System.arraycopy(CHUNK_DATA, 0, chars, 0, CHUNK_DATA.length); + DataArray[] sections = new DataArray[(320 + 64) >> 4]; + for (int i = 0; i < sections.length; i++) { + sections[i] = DataArray.createCopy(CHUNK_DATA); } when(set.getMinSectionPosition()).thenReturn(-64 >> 4); @@ -56,7 +62,7 @@ void testFullChunkSelectedInBoundedRegion(int minY, int maxY, int minSection, in for (int section = -64 >> 4; section < 320 >> 4; section++) { int sectionIndex = section + 4; - char[] palette = sections[sectionIndex]; + DataArray palette = sections[sectionIndex]; if (section < minSection) { assertNull(palette, "expected section below minimum section to be null"); continue; @@ -72,28 +78,26 @@ void testFullChunkSelectedInBoundedRegion(int minY, int maxY, int minSection, in if (section == maxSection) { shouldContainBlocks &= slice <= (maxY % 16); } - assertArrayEquals( - shouldContainBlocks ? SLICE_AIR : SLICE_RESERVED, - Arrays.copyOfRange(palette, slice << 8, (slice + 1) << 8), - ("[lower] slice %d (y=%d) expected to contain " + (shouldContainBlocks ? "air" : "nothing")) - .formatted(slice, ((section << 4) + slice)) - ); + try { + assertSliceMatches(palette, slice << 8, (slice + 1) << 8, shouldContainBlocks ? AIR : __RESERVED__); + } catch (AssertionFailedError error) { + fail("[lower] slice %d (y=%d) expected to contain " + (shouldContainBlocks ? "air" : "nothing"), error); + } } continue; } if (section == maxSection) { for (int slice = 0; slice < 16; slice++) { boolean shouldContainBlocks = slice <= (maxY % 16); - assertArrayEquals( - shouldContainBlocks ? SLICE_AIR : SLICE_RESERVED, - Arrays.copyOfRange(palette, slice << 8, (slice + 1) << 8), - ("[upper] slice %d (y=%d) expected to contain " + (shouldContainBlocks ? "air" : "nothing")) - .formatted(slice, ((section << 4) + slice)) - ); + try { + assertSliceMatches(palette, slice << 8, (slice + 1) << 8, shouldContainBlocks ? AIR : __RESERVED__); + } catch (AssertionFailedError error) { + fail("[upper] slice %d (y=%d) expected to contain " + (shouldContainBlocks ? "air" : "nothing"), error); + } } continue; } - assertArrayEquals(CHUNK_DATA, palette, "full captured chunk @ %d should contain full data".formatted(section)); + assertEquals(CHUNK_DATA, palette, "full captured chunk @ %d should contain full data".formatted(section)); } } @@ -133,4 +137,10 @@ public IChunkSet processSet(final IChunk chunk, final IChunkGet get, final IChun } + private static void assertSliceMatches(DataArray dataArray, int sliceStart, int sliceEnd, int expectedValue) { + for (int i = sliceStart; i < sliceEnd; i++) { + assertEquals(expectedValue, dataArray.getAt(i), "mismatch at index " + i); + } + } + }