Improve Registry.Container

Signed-off-by: TheMode <themode@outlook.fr>
This commit is contained in:
TheMode 2022-01-14 10:45:44 +01:00
parent 2ef1902664
commit 7a9b08b085
10 changed files with 45 additions and 52 deletions

View File

@ -43,8 +43,8 @@ import java.util.Map;
import java.util.function.BiFunction;
record EntityTypeImpl(Registry.EntityEntry registry) implements EntityType {
private static final Registry.Container<EntityType> CONTAINER = new Registry.Container<>(Registry.Resource.ENTITIES,
(container, namespace, object) -> container.register(new EntityTypeImpl(Registry.entity(namespace, object, null))));
private static final Registry.Container<EntityType> CONTAINER = Registry.createContainer(Registry.Resource.ENTITIES,
(namespace, object) -> new EntityTypeImpl(Registry.entity(namespace, object, null)));
private static final Map<String, BiFunction<Entity, Metadata, EntityMeta>> ENTITY_META_SUPPLIER = createMetaMap();
static EntityType get(@NotNull String namespace) {

View File

@ -27,8 +27,8 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
private static final ObjectArray<Block> BLOCK_STATE_MAP = new ObjectArray<>();
// Block id -> Map<Properties, Block>
private static final ObjectArray<Map<Map<String, String>, Block>> POSSIBLE_STATES = new ObjectArray<>();
private static final Registry.Container<Block> CONTAINER = new Registry.Container<>(Registry.Resource.BLOCKS,
(container, namespace, object) -> {
private static final Registry.Container<Block> CONTAINER = Registry.createContainer(Registry.Resource.BLOCKS,
(namespace, object) -> {
final var stateObject = (Map<String, Object>) object.get("states");
// Retrieve the block states
{
@ -52,7 +52,7 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
}
// Register default state
final int defaultState = ((Number) object.get("defaultStateId")).intValue();
container.register(getState(defaultState));
return getState(defaultState);
});
private static final Cache<NBTCompound, NBTCompound> NBT_CACHE = Caffeine.newBuilder()
.expireAfterWrite(Duration.ofMinutes(5))

View File

@ -6,8 +6,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record EnchantmentImpl(Registry.EnchantmentEntry registry) implements Enchantment {
private static final Registry.Container<Enchantment> CONTAINER = new Registry.Container<>(Registry.Resource.ENCHANTMENTS,
(container, namespace, object) -> container.register(new EnchantmentImpl(Registry.enchantment(namespace, object, null))));
private static final Registry.Container<Enchantment> CONTAINER = Registry.createContainer(Registry.Resource.ENCHANTMENTS,
(namespace, object) -> new EnchantmentImpl(Registry.enchantment(namespace, object, null)));
static Enchantment get(@NotNull String namespace) {
return CONTAINER.get(namespace);

View File

@ -6,8 +6,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record MaterialImpl(Registry.MaterialEntry registry) implements Material {
private static final Registry.Container<Material> CONTAINER = new Registry.Container<>(Registry.Resource.ITEMS,
(container, namespace, object) -> container.register(new MaterialImpl(Registry.material(namespace, object, null))));
private static final Registry.Container<Material> CONTAINER = Registry.createContainer(Registry.Resource.ITEMS,
(namespace, object) -> new MaterialImpl(Registry.material(namespace, object, null)));
static Material get(@NotNull String namespace) {
return CONTAINER.get(namespace);

View File

@ -7,10 +7,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record ParticleImpl(NamespaceID namespace, int id) implements Particle {
private static final Registry.Container<Particle> CONTAINER = new Registry.Container<>(Registry.Resource.PARTICLES,
(loader, namespace, object) -> {
private static final Registry.Container<Particle> CONTAINER = Registry.createContainer(Registry.Resource.PARTICLES,
(namespace, object) -> {
final int id = ((Number) object.get("id")).intValue();
loader.register(new ParticleImpl(NamespaceID.from(namespace), id));
return new ParticleImpl(NamespaceID.from(namespace), id);
});
static Particle get(@NotNull String namespace) {

View File

@ -6,8 +6,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record PotionEffectImpl(Registry.PotionEffectEntry registry) implements PotionEffect {
private static final Registry.Container<PotionEffect> CONTAINER = new Registry.Container<>(Registry.Resource.POTION_EFFECTS,
(container, namespace, object) -> container.register(new PotionEffectImpl(Registry.potionEffect(namespace, object, null))));
private static final Registry.Container<PotionEffect> CONTAINER = Registry.createContainer(Registry.Resource.POTION_EFFECTS,
(namespace, object) -> new PotionEffectImpl(Registry.potionEffect(namespace, object, null)));
static PotionEffect get(@NotNull String namespace) {
return CONTAINER.get(namespace);

View File

@ -7,10 +7,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record PotionTypeImpl(NamespaceID namespace, int id) implements PotionType {
private static final Registry.Container<PotionType> CONTAINER = new Registry.Container<>(Registry.Resource.POTION_TYPES,
(loader, namespace, object) -> {
private static final Registry.Container<PotionType> CONTAINER = Registry.createContainer(Registry.Resource.POTION_TYPES,
(namespace, object) -> {
final int id = ((Number) object.get("id")).intValue();
loader.register(new PotionTypeImpl(NamespaceID.from(namespace), id));
return new PotionTypeImpl(NamespaceID.from(namespace), id);
});
static PotionType get(@NotNull String namespace) {

View File

@ -66,31 +66,30 @@ public final class Registry {
return map;
}
public static class Container<T extends ProtocolObject> {
// Maps do not need to be thread-safe as they are fully populated
// in the static initializer, should not be modified during runtime
@ApiStatus.Internal
public static <T extends ProtocolObject> Container<T> createContainer(Resource resource, Container.Loader<T> loader) {
Map<String, T> namespaces = new HashMap<>();
ObjectArray<T> ids = new ObjectArray<>();
for (var entry : Registry.load(resource).entrySet()) {
final String namespace = entry.getKey();
final Map<String, Object> object = entry.getValue();
final T value = loader.get(namespace, object);
ids.set(value.id(), value);
namespaces.put(value.name(), value);
}
return new Container<>(namespaces, ids);
}
// namespace -> registry data
private final Map<String, T> namespaceMap = new HashMap<>();
// id -> registry data
private final ObjectArray<T> ids = new ObjectArray<>();
private final Collection<T> objects = Collections.unmodifiableCollection(namespaceMap.values());
private final boolean initialized;
@ApiStatus.Internal
public Container(Resource resource, Loader<T> loader) {
for (var entry : Registry.load(resource).entrySet()) {
final String namespace = entry.getKey();
final Map<String, Object> object = entry.getValue();
loader.accept(this, namespace, object);
}
this.initialized = true;
this.ids.trim();
@ApiStatus.Internal
public record Container<T extends ProtocolObject>(Map<String, T> namespaces,
ObjectArray<T> ids) {
public Container {
namespaces = Map.copyOf(namespaces);
ids.trim();
}
public T get(@NotNull String namespace) {
return namespaceMap.get(namespace);
return namespaces.get(namespace);
}
public T getSafe(@NotNull String namespace) {
@ -102,17 +101,11 @@ public final class Registry {
}
public Collection<T> values() {
return objects;
}
public void register(@NotNull T value) {
Check.stateCondition(initialized, "Registering is only available within the loader lambda.");
this.ids.set(value.id(), value);
this.namespaceMap.put(value.name(), value);
return namespaces.values();
}
public interface Loader<T extends ProtocolObject> {
void accept(Container<T> container, String namespace, Map<String, Object> object);
T get(String namespace, Map<String, Object> object);
}
}

View File

@ -7,10 +7,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record SoundEventImpl(NamespaceID namespace, int id) implements SoundEvent {
private static final Registry.Container<SoundEvent> CONTAINER = new Registry.Container<>(Registry.Resource.SOUNDS,
(container, namespace, object) -> {
private static final Registry.Container<SoundEvent> CONTAINER = Registry.createContainer(Registry.Resource.SOUNDS,
(namespace, object) -> {
final int id = ((Number) object.get("id")).intValue();
container.register(new SoundEventImpl(NamespaceID.from(namespace), id));
return new SoundEventImpl(NamespaceID.from(namespace), id);
});
static SoundEvent get(@NotNull String namespace) {

View File

@ -7,10 +7,10 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
record StatisticTypeImpl(NamespaceID namespace, int id) implements StatisticType {
private static final Registry.Container<StatisticType> CONTAINER = new Registry.Container<>(Registry.Resource.STATISTICS,
(container, namespace, object) -> {
private static final Registry.Container<StatisticType> CONTAINER = Registry.createContainer(Registry.Resource.STATISTICS,
(namespace, object) -> {
final int id = ((Number) object.get("id")).intValue();
container.register(new StatisticTypeImpl(NamespaceID.from(namespace), id));
return new StatisticTypeImpl(NamespaceID.from(namespace), id);
});
static StatisticType get(@NotNull String namespace) {