diff --git a/src/main/java/net/minestom/server/instance/block/BlockImpl.java b/src/main/java/net/minestom/server/instance/block/BlockImpl.java index b20525b02..3281eeaf9 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockImpl.java +++ b/src/main/java/net/minestom/server/instance/block/BlockImpl.java @@ -3,9 +3,9 @@ package net.minestom.server.instance.block; import com.github.benmanes.caffeine.cache.Cache; import com.github.benmanes.caffeine.cache.Caffeine; import com.google.gson.JsonObject; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minestom.server.registry.Registry; import net.minestom.server.tag.Tag; +import net.minestom.server.utils.ObjectArray; import net.minestom.server.utils.block.BlockUtils; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,7 +17,7 @@ import java.util.function.Function; final class BlockImpl implements Block { // Block state -> block object - private static final ObjectArrayList BLOCK_STATE_MAP = new ObjectArrayList<>(); + private static final ObjectArray BLOCK_STATE_MAP = new ObjectArray<>(); private static final Registry.Container CONTAINER = new Registry.Container<>(Registry.Resource.BLOCKS, (container, namespace, object) -> { final JsonObject stateObject = object.remove("states").getAsJsonObject(); @@ -30,7 +30,7 @@ final class BlockImpl implements Block { final var propertyMap = BlockUtils.parseProperties(query); final Block block = new BlockImpl(Registry.block(namespace, object, stateOverride), unmodifiableEntries, propertyMap, null, null); - BLOCK_STATE_MAP.add(block.stateId(), block); + BLOCK_STATE_MAP.set(block.stateId(), block); propertyEntry.put(propertyMap, block); } // Register default state diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 795d909c6..06676d488 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -4,12 +4,12 @@ import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.stream.JsonReader; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.minestom.server.entity.EntitySpawnType; import net.minestom.server.entity.EquipmentSlot; import net.minestom.server.instance.block.Block; import net.minestom.server.item.Material; import net.minestom.server.utils.NamespaceID; +import net.minestom.server.utils.ObjectArray; import net.minestom.server.utils.validate.Check; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; @@ -76,7 +76,7 @@ public final class Registry { // namespace -> registry data private final Map namespaceMap = new HashMap<>(); // id -> registry data - private final ObjectArrayList idMap = new ObjectArrayList<>(); + private final ObjectArray ids = new ObjectArray<>(); private final Collection objects = Collections.unmodifiableCollection(namespaceMap.values()); private final boolean initialized; @@ -90,7 +90,7 @@ public final class Registry { loader.accept(this, namespace, object); } this.initialized = true; - this.idMap.trim(); + this.ids.trim(); } public T get(@NotNull String namespace) { @@ -102,7 +102,7 @@ public final class Registry { } public T getId(int id) { - return idMap.get(id); + return ids.get(id); } public Collection values() { @@ -111,7 +111,7 @@ public final class Registry { public void register(@NotNull T value) { Check.stateCondition(initialized, "Registering is only available within the loader lambda."); - this.idMap.add(value.id(), value); + this.ids.set(value.id(), value); this.namespaceMap.put(value.name(), value); } diff --git a/src/main/java/net/minestom/server/utils/ObjectArray.java b/src/main/java/net/minestom/server/utils/ObjectArray.java new file mode 100644 index 000000000..50544ca46 --- /dev/null +++ b/src/main/java/net/minestom/server/utils/ObjectArray.java @@ -0,0 +1,47 @@ +package net.minestom.server.utils; + +import org.jetbrains.annotations.ApiStatus; + +/** + * Represents an array which will be resized to the highest required index. + * + * @param the type of the array + */ +@ApiStatus.Internal +public final class ObjectArray { + private T[] array; + private int max; + + public ObjectArray(int size) { + this.array = allocate(size); + } + + public ObjectArray() { + this(0); + } + + public void set(int index, T object) { + if (index >= array.length) { + T[] newArray = allocate(index * 2 + 1); + System.arraycopy(array, 0, newArray, 0, array.length); + this.array = newArray; + } + array[index] = object; + this.max = Math.max(max, index); + } + + public T get(int index) { + return index < array.length ? array[index] : null; + } + + public void trim() { + T[] newArray = allocate(max + 1); + System.arraycopy(array, 0, newArray, 0, max + 1); + this.array = newArray; + } + + private static T[] allocate(int length) { + //noinspection unchecked + return (T[]) new Object[length]; + } +}