diff --git a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java index c52b204f799..a9608f9edb2 100644 --- a/src/main/java/net/minestom/server/command/builder/arguments/Argument.java +++ b/src/main/java/net/minestom/server/command/builder/arguments/Argument.java @@ -30,8 +30,11 @@ */ public abstract class Argument { @ApiStatus.Internal - public static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS, - (namespace, properties) -> new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id"))); + public static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.COMMAND_ARGUMENTS, Argument::createImpl); + + private static ArgumentImpl createImpl(String namespace, Registry.Properties properties) { + return new ArgumentImpl(NamespaceID.from(namespace), properties.getInt("id")); + } record ArgumentImpl(NamespaceID namespace, int id) implements StaticProtocolObject { @Override diff --git a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java index d919c6fee19..9a2d0ee48da 100644 --- a/src/main/java/net/minestom/server/entity/EntityTypeImpl.java +++ b/src/main/java/net/minestom/server/entity/EntityTypeImpl.java @@ -42,8 +42,11 @@ import static java.util.Map.entry; record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ENTITIES, - (namespace, properties) -> new EntityTypeImpl(Registry.entity(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ENTITIES, EntityTypeImpl::createImpl); + + private static EntityType createImpl(String namespace, Registry.Properties properties) { + return new EntityTypeImpl(Registry.entity(namespace, properties)); + } static final Map> ENTITY_META_SUPPLIER = createMetaMap(); static EntityType get(@NotNull String namespace) { diff --git a/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java b/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java index 70f97ff4c5b..03c8e132e01 100644 --- a/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java +++ b/src/main/java/net/minestom/server/entity/damage/DamageTypeImpl.java @@ -12,12 +12,15 @@ import java.util.concurrent.atomic.AtomicInteger; record DamageTypeImpl(Registry.DamageTypeEntry registry, int id) implements DamageType { - private static final Registry.Container CONTAINER; + private static final AtomicInteger INDEX = new AtomicInteger(); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.DAMAGE_TYPES, DamageTypeImpl::createImpl); - static { - AtomicInteger i = new AtomicInteger(); - CONTAINER = Registry.createStaticContainer(Registry.Resource.DAMAGE_TYPES, - (namespace, properties) -> new DamageTypeImpl(Registry.damageType(namespace, properties), i.getAndIncrement())); + private DamageTypeImpl(Registry.DamageTypeEntry registry) { + this(registry, INDEX.getAndIncrement()); + } + + private static DamageType createImpl(String namespace, Registry.Properties properties) { + return new DamageTypeImpl(Registry.damageType(namespace, properties)); } static DamageType get(@NotNull String namespace) { 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 6140b7fbe89..2aa868f8b50 100644 --- a/src/main/java/net/minestom/server/instance/block/BlockImpl.java +++ b/src/main/java/net/minestom/server/instance/block/BlockImpl.java @@ -31,61 +31,7 @@ record BlockImpl(@NotNull Registry.BlockEntry registry, private static final ObjectArray PROPERTIES_TYPE = ObjectArray.singleThread(); // Block id -> Map private static final ObjectArray> POSSIBLE_STATES = ObjectArray.singleThread(); - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BLOCKS, - (namespace, properties) -> { - final int blockId = properties.getInt("id"); - final Registry.Properties stateObject = properties.section("states"); - - // Retrieve properties - PropertyType[] propertyTypes; - { - Registry.Properties stateProperties = properties.section("properties"); - if (stateProperties != null) { - final int stateCount = stateProperties.size(); - propertyTypes = new PropertyType[stateCount]; - int i = 0; - for (var entry : stateProperties) { - final var k = entry.getKey(); - final var v = (List) entry.getValue(); - propertyTypes[i++] = new PropertyType(k, v); - } - } else { - propertyTypes = new PropertyType[0]; - } - } - PROPERTIES_TYPE.set(blockId, propertyTypes); - - // Retrieve block states - { - final int propertiesCount = stateObject.size(); - PropertiesHolder[] propertiesKeys = new PropertiesHolder[propertiesCount]; - BlockImpl[] blocksValues = new BlockImpl[propertiesCount]; - int propertiesOffset = 0; - for (var stateEntry : stateObject) { - final String query = stateEntry.getKey(); - final var stateOverride = (Map) stateEntry.getValue(); - final var propertyMap = BlockUtils.parseProperties(query); - assert propertyTypes.length == propertyMap.size(); - byte[] propertiesArray = new byte[propertyTypes.length]; - for (var entry : propertyMap.entrySet()) { - final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), null); - final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), null); - propertiesArray[keyIndex] = valueIndex; - } - - var mainProperties = Registry.Properties.fromMap(new MergedMap<>(stateOverride, properties.asMap())); - final BlockImpl block = new BlockImpl(Registry.block(namespace, mainProperties), - propertiesArray, null, null); - BLOCK_STATE_MAP.set(block.stateId(), block); - propertiesKeys[propertiesOffset] = new PropertiesHolder(propertiesArray); - blocksValues[propertiesOffset++] = block; - } - POSSIBLE_STATES.set(blockId, ArrayUtils.toMap(propertiesKeys, blocksValues, propertiesOffset)); - } - // Register default state - final int defaultState = properties.getInt("defaultStateId"); - return getState(defaultState); - }); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BLOCKS, BlockImpl::createImpl); private static final Cache NBT_CACHE = Caffeine.newBuilder() .expireAfterWrite(Duration.ofMinutes(5)) .weakValues() @@ -214,6 +160,61 @@ private Block compute(byte[] properties) { return nbt == null && handler == null ? block : new BlockImpl(block.registry(), block.propertiesArray, nbt, handler); } + private static Block createImpl(String namespace, Registry.Properties properties) { + final int blockId = properties.getInt("id"); + final Registry.Properties stateObject = properties.section("states"); + + // Retrieve properties + PropertyType[] propertyTypes; + { + Registry.Properties stateProperties = properties.section("properties"); + if (stateProperties != null) { + final int stateCount = stateProperties.size(); + propertyTypes = new PropertyType[stateCount]; + int i = 0; + for (var entry : stateProperties) { + final var k = entry.getKey(); + final var v = (List) entry.getValue(); + propertyTypes[i++] = new PropertyType(k, v); + } + } else { + propertyTypes = new PropertyType[0]; + } + } + PROPERTIES_TYPE.set(blockId, propertyTypes); + + // Retrieve block states + { + final int propertiesCount = stateObject.size(); + PropertiesHolder[] propertiesKeys = new PropertiesHolder[propertiesCount]; + BlockImpl[] blocksValues = new BlockImpl[propertiesCount]; + int propertiesOffset = 0; + for (var stateEntry : stateObject) { + final String query = stateEntry.getKey(); + final var stateOverride = (Map) stateEntry.getValue(); + final var propertyMap = BlockUtils.parseProperties(query); + assert propertyTypes.length == propertyMap.size(); + byte[] propertiesArray = new byte[propertyTypes.length]; + for (var entry : propertyMap.entrySet()) { + final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), null); + final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), null); + propertiesArray[keyIndex] = valueIndex; + } + + var mainProperties = Registry.Properties.fromMap(new MergedMap<>(stateOverride, properties.asMap())); + final BlockImpl block = new BlockImpl(Registry.block(namespace, mainProperties), + propertiesArray, null, null); + BLOCK_STATE_MAP.set(block.stateId(), block); + propertiesKeys[propertiesOffset] = new PropertiesHolder(propertiesArray); + blocksValues[propertiesOffset++] = block; + } + POSSIBLE_STATES.set(blockId, ArrayUtils.toMap(propertiesKeys, blocksValues, propertiesOffset)); + } + // Register default state + final int defaultState = properties.getInt("defaultStateId"); + return getState(defaultState); + } + private static byte findKeyIndex(PropertyType[] properties, String key, BlockImpl block) { for (byte i = 0; i < properties.length; i++) { if (properties[i].key().equals(key)) return i; diff --git a/src/main/java/net/minestom/server/item/EnchantmentImpl.java b/src/main/java/net/minestom/server/item/EnchantmentImpl.java index 4a82d4efc50..40823696ba6 100644 --- a/src/main/java/net/minestom/server/item/EnchantmentImpl.java +++ b/src/main/java/net/minestom/server/item/EnchantmentImpl.java @@ -6,8 +6,11 @@ import java.util.Collection; record EnchantmentImpl(Registry.EnchantmentEntry registry) implements Enchantment { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ENCHANTMENTS, - (namespace, properties) -> new EnchantmentImpl(Registry.enchantment(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ENCHANTMENTS, EnchantmentImpl::createImpl); + + private static Enchantment createImpl(String namespace, Registry.Properties properties) { + return new EnchantmentImpl(Registry.enchantment(namespace, properties)); + } static Enchantment get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/item/MaterialImpl.java b/src/main/java/net/minestom/server/item/MaterialImpl.java index 38c1c823684..2808b424c8e 100644 --- a/src/main/java/net/minestom/server/item/MaterialImpl.java +++ b/src/main/java/net/minestom/server/item/MaterialImpl.java @@ -6,8 +6,11 @@ import java.util.Collection; record MaterialImpl(Registry.MaterialEntry registry) implements Material { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS, - (namespace, properties) -> new MaterialImpl(Registry.material(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.ITEMS, MaterialImpl::createImpl); + + private static Material createImpl(String namespace, Registry.Properties properties) { + return new MaterialImpl(Registry.material(namespace, properties)); + } static Material get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java b/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java index 95fe79b4dfb..c7e19ec0133 100644 --- a/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java +++ b/src/main/java/net/minestom/server/item/armor/TrimMaterialImpl.java @@ -11,16 +11,15 @@ import java.util.stream.Collectors; record TrimMaterialImpl(Registry.TrimMaterialEntry registry, int id) implements TrimMaterial { - static final AtomicInteger i = new AtomicInteger(); - private static final Registry.Container CONTAINER; + private static final AtomicInteger INDEX = new AtomicInteger(); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_MATERIALS, TrimMaterialImpl::createImpl); - static { - CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_MATERIALS, - (namespace, properties) -> new TrimMaterialImpl(Registry.trimMaterial(namespace, properties))); + public TrimMaterialImpl(Registry.TrimMaterialEntry registry) { + this(registry, INDEX.getAndIncrement()); } - public TrimMaterialImpl(Registry.TrimMaterialEntry registry) { - this(registry, i.getAndIncrement()); + private static TrimMaterial createImpl(String namespace, Registry.Properties properties) { + return new TrimMaterialImpl(Registry.trimMaterial(namespace, properties)); } public static TrimMaterial get(String namespace) { diff --git a/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java b/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java index 6b4ecd1aaf9..c0bbd32561f 100644 --- a/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java +++ b/src/main/java/net/minestom/server/item/armor/TrimPatternImpl.java @@ -10,17 +10,16 @@ record TrimPatternImpl(Registry.TrimPatternEntry registry, int id) implements TrimPattern { static final AtomicInteger i = new AtomicInteger(); - private static final Registry.Container CONTAINER; - - static { - CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_PATTERNS, - (namespace, properties) -> new TrimPatternImpl(Registry.trimPattern(namespace, properties))); - } + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.TRIM_PATTERNS, TrimPatternImpl::createImpl); public TrimPatternImpl(Registry.TrimPatternEntry registry) { this(registry, i.getAndIncrement()); } + private static TrimPattern createImpl(String namespace, Registry.Properties properties) { + return new TrimPatternImpl(Registry.trimPattern(namespace, properties)); + } + public static TrimPattern get(String namespace) { return CONTAINER.get(namespace); } diff --git a/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java b/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java index 2f1dd27b1c5..028e219a01e 100644 --- a/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java +++ b/src/main/java/net/minestom/server/item/banner/BannerPatternImpl.java @@ -12,14 +12,15 @@ public record BannerPatternImpl(NamespaceID namespace, int id, String identifier) implements BannerPattern { private static Map IDENTIFIERS = new HashMap<>(); - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BANNER_PATTERNS, - (namespace, properties) -> { - int id = properties.getInt("id"); - String identifier = properties.getString("identifier"); - BannerPatternImpl bannerPattern = new BannerPatternImpl(NamespaceID.from(namespace), id, identifier); - IDENTIFIERS.put(identifier, bannerPattern); - return bannerPattern; - }); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.BANNER_PATTERNS, BannerPatternImpl::createImpl); + + private static BannerPattern createImpl(String namespace, Registry.Properties properties) { + int id = properties.getInt("id"); + String identifier = properties.getString("identifier"); + BannerPatternImpl bannerPattern = new BannerPatternImpl(NamespaceID.from(namespace), id, identifier); + IDENTIFIERS.put(identifier, bannerPattern); + return bannerPattern; + } static BannerPattern get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/particle/ParticleImpl.java b/src/main/java/net/minestom/server/particle/ParticleImpl.java index d70ea41bd5f..344a5ff6086 100644 --- a/src/main/java/net/minestom/server/particle/ParticleImpl.java +++ b/src/main/java/net/minestom/server/particle/ParticleImpl.java @@ -9,8 +9,11 @@ import java.util.Collection; record ParticleImpl(NamespaceID namespace, int id, ParticleData data) implements Particle { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.PARTICLES, - (namespace, properties) -> new ParticleImpl(NamespaceID.from(namespace), properties.getInt("id"), ParticleData.defaultData(namespace))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.PARTICLES, ParticleImpl::createImpl); + + private static Particle createImpl(String namespace, Registry.Properties properties) { + return new ParticleImpl(NamespaceID.from(namespace), properties.getInt("id"), ParticleData.defaultData(namespace)); + } static Particle get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/potion/PotionEffectImpl.java b/src/main/java/net/minestom/server/potion/PotionEffectImpl.java index 0e90e62d111..0e214afe3e3 100644 --- a/src/main/java/net/minestom/server/potion/PotionEffectImpl.java +++ b/src/main/java/net/minestom/server/potion/PotionEffectImpl.java @@ -6,8 +6,11 @@ import java.util.Collection; record PotionEffectImpl(Registry.PotionEffectEntry registry) implements PotionEffect { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_EFFECTS, - (namespace, properties) -> new PotionEffectImpl(Registry.potionEffect(namespace, properties))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_EFFECTS, PotionEffectImpl::createImpl); + + private static PotionEffect createImpl(String namespace, Registry.Properties properties) { + return new PotionEffectImpl(Registry.potionEffect(namespace, properties)); + } static PotionEffect get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/potion/PotionTypeImpl.java b/src/main/java/net/minestom/server/potion/PotionTypeImpl.java index 1cb427ef9b8..719a7cc6ce7 100644 --- a/src/main/java/net/minestom/server/potion/PotionTypeImpl.java +++ b/src/main/java/net/minestom/server/potion/PotionTypeImpl.java @@ -7,8 +7,11 @@ import java.util.Collection; record PotionTypeImpl(NamespaceID namespace, int id) implements PotionType { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_TYPES, - (namespace, properties) -> new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id"))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.POTION_TYPES, PotionTypeImpl::createImpl); + + private static PotionType createImpl(String namespace, Registry.Properties properties) { + return new PotionTypeImpl(NamespaceID.from(namespace), properties.getInt("id")); + } static PotionType get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/registry/Registry.java b/src/main/java/net/minestom/server/registry/Registry.java index 787b8a5b374..16be476103e 100644 --- a/src/main/java/net/minestom/server/registry/Registry.java +++ b/src/main/java/net/minestom/server/registry/Registry.java @@ -95,7 +95,7 @@ public static Map> load(Resource resource) { } @ApiStatus.Internal - public static Container createStaticContainer(Resource resource, Container.Loader loader) { + public static Container createStaticContainer(Resource resource, Loader loader) { var entries = Registry.load(resource); Map namespaces = new HashMap<>(entries.size()); ObjectArray ids = ObjectArray.singleThread(entries.size()); @@ -156,7 +156,7 @@ public interface Loader { } @ApiStatus.Internal - public static DynamicContainer createDynamicContainer(Resource resource, Container.Loader loader) { + public static DynamicContainer createDynamicContainer(Resource resource, Loader loader) { var entries = Registry.load(resource); Map namespaces = new HashMap<>(entries.size()); for (var entry : entries.entrySet()) { @@ -203,6 +203,11 @@ public interface Loader { } } + @FunctionalInterface + public interface Loader { + T get(String namespace, Properties properties); + } + @ApiStatus.Internal public enum Resource { BLOCKS("blocks.json"), diff --git a/src/main/java/net/minestom/server/sound/SoundEventImpl.java b/src/main/java/net/minestom/server/sound/SoundEventImpl.java index fb7bd952bd3..7d2a55e6d94 100644 --- a/src/main/java/net/minestom/server/sound/SoundEventImpl.java +++ b/src/main/java/net/minestom/server/sound/SoundEventImpl.java @@ -7,8 +7,11 @@ import java.util.Collection; record SoundEventImpl(NamespaceID namespace, int id) implements SoundEvent { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.SOUNDS, - (namespace, properties) -> new SoundEventImpl(NamespaceID.from(namespace), properties.getInt("id"))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.SOUNDS, SoundEventImpl::createImpl); + + private static SoundEvent createImpl(String namespace, Registry.Properties properties) { + return new SoundEventImpl(NamespaceID.from(namespace), properties.getInt("id")); + } static SoundEvent get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java b/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java index 40606e211dd..0d19b60d457 100644 --- a/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java +++ b/src/main/java/net/minestom/server/statistic/StatisticTypeImpl.java @@ -7,8 +7,11 @@ import java.util.Collection; record StatisticTypeImpl(NamespaceID namespace, int id) implements StatisticType { - private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.STATISTICS, - (namespace, properties) -> new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id"))); + private static final Registry.Container CONTAINER = Registry.createStaticContainer(Registry.Resource.STATISTICS, StatisticTypeImpl::createImpl); + + private static StatisticType createImpl(String namespace, Registry.Properties properties) { + return new StatisticTypeImpl(NamespaceID.from(namespace), properties.getInt("id")); + } static StatisticType get(@NotNull String namespace) { return CONTAINER.get(namespace); diff --git a/src/main/java/net/minestom/server/world/biomes/BiomeImpl.java b/src/main/java/net/minestom/server/world/biomes/BiomeImpl.java index a0be8d8fc29..e2d2efdafc1 100644 --- a/src/main/java/net/minestom/server/world/biomes/BiomeImpl.java +++ b/src/main/java/net/minestom/server/world/biomes/BiomeImpl.java @@ -12,8 +12,12 @@ final class BiomeImpl implements ProtocolObject, Biome { // https://minecraft.wiki/w/Rain private final static Double SNOW_TEMPERATURE = 0.15; - private static final Registry.DynamicContainer CONTAINER = Registry.createDynamicContainer(Registry.Resource.BIOMES, - (namespace, properties) -> new BiomeImpl(Registry.biome(namespace, properties))); + private static final Registry.DynamicContainer CONTAINER = Registry.createDynamicContainer(Registry.Resource.BIOMES, BiomeImpl::createImpl); + + private static BiomeImpl createImpl(String namespace, Registry.Properties properties) { + return new BiomeImpl(Registry.biome(namespace, properties)); + } + static Collection values() { return CONTAINER.values();