Reduce registry boilerplate

This commit is contained in:
TheMode 2021-07-30 15:29:05 +02:00
parent c9f234cb1d
commit f865a7b9dd
10 changed files with 76 additions and 135 deletions

View File

@ -1,6 +1,5 @@
package net.minestom.server.entity;
import com.google.gson.JsonObject;
import net.minestom.server.entity.metadata.EntityMeta;
import net.minestom.server.entity.metadata.PlayerMeta;
import net.minestom.server.entity.metadata.ambient.BatMeta;
@ -47,25 +46,26 @@ import java.util.Map;
import java.util.function.BiFunction;
final class EntityTypeImpl implements EntityType {
private static final Registry.Loader<EntityType> LOADER = new Registry.Loader<>();
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 Map<String, BiFunction<Entity, Metadata, EntityMeta>> ENTITY_META_SUPPLIER = createMetaMap();
private static final Map<String, Double> ACCELERATION_MAP = createAccelerationMap();
private static final Map<String, Double> DRAG_MAP = createDragMap();
static EntityType get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static EntityType getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static EntityType getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<EntityType> values() {
return LOADER.values();
return CONTAINER.values();
}
static EntityMeta createMeta(EntityType entityType, Entity entity, Metadata metadata) {
@ -80,16 +80,6 @@ final class EntityTypeImpl implements EntityType {
return DRAG_MAP.getOrDefault(namespace, 0.02);
}
static {
// Load data from file
JsonObject entities = Registry.load(Registry.Resource.ENTITIES);
entities.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject entityObject = entry.getValue().getAsJsonObject();
LOADER.register(new EntityTypeImpl(Registry.entity(namespace, entityObject, null)));
});
}
private static Map<String, BiFunction<Entity, Metadata, EntityMeta>> createMetaMap() {
Map<String, BiFunction<Entity, Metadata, EntityMeta>> supplier = new HashMap<>();
supplier.put("minecraft:area_effect_cloud", AreaEffectCloudMeta::new);

View File

@ -1,38 +1,28 @@
package net.minestom.server.item;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class EnchantmentImpl implements Enchantment {
private static final Registry.Loader<Enchantment> LOADER = new Registry.Loader<>();
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))));
static Enchantment get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static Enchantment getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static Enchantment getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<Enchantment> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject enchantments = Registry.load(Registry.Resource.ENCHANTMENTS);
enchantments.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject enchantmentObject = entry.getValue().getAsJsonObject();
LOADER.register(new EnchantmentImpl(Registry.enchantment(namespace, enchantmentObject, null)));
});
return CONTAINER.values();
}
private final Registry.EnchantmentEntry registry;

View File

@ -1,38 +1,28 @@
package net.minestom.server.item;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class MaterialImpl implements Material {
private static final Registry.Loader<Material> LOADER = new Registry.Loader<>();
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))));
static Material get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static Material getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static Material getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<Material> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject materials = Registry.load(Registry.Resource.ITEMS);
materials.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject materialObject = entry.getValue().getAsJsonObject();
LOADER.register(new MaterialImpl(Registry.material(namespace, materialObject, null)));
});
return CONTAINER.values();
}
private final Registry.MaterialEntry registry;

View File

@ -1,6 +1,5 @@
package net.minestom.server.particle;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
@ -8,33 +7,26 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class ParticleImpl implements Particle {
private static final Registry.Loader<Particle> LOADER = new Registry.Loader<>();
private static final Registry.Container<Particle> CONTAINER = new Registry.Container<>(Registry.Resource.PARTICLES,
(loader, namespace, object) -> {
final int id = object.get("id").getAsInt();
loader.register(new ParticleImpl(NamespaceID.from(namespace), id));
});
static Particle get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static Particle getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static Particle getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<Particle> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject particles = Registry.load(Registry.Resource.PARTICLES);
particles.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
final int id = object.get("id").getAsInt();
LOADER.register(new ParticleImpl(NamespaceID.from(namespace), id));
});
return CONTAINER.values();
}
private final NamespaceID namespaceID;

View File

@ -1,38 +1,28 @@
package net.minestom.server.potion;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class PotionEffectImpl implements PotionEffect {
private static final Registry.Loader<PotionEffect> LOADER = new Registry.Loader<>();
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))));
static PotionEffect get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static PotionEffect getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static PotionEffect getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<PotionEffect> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject potionEffects = Registry.load(Registry.Resource.POTION_EFFECTS);
potionEffects.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
LOADER.register(new PotionEffectImpl(Registry.potionEffect(namespace, object, null)));
});
return CONTAINER.values();
}
private final Registry.PotionEffectEntry registry;

View File

@ -1,6 +1,5 @@
package net.minestom.server.potion;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
@ -8,33 +7,26 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class PotionTypeImpl implements PotionType {
private static final Registry.Loader<PotionType> LOADER = new Registry.Loader<>();
private static final Registry.Container<PotionType> CONTAINER = new Registry.Container<>(Registry.Resource.POTION_TYPES,
(loader, namespace, object) -> {
final int id = object.get("id").getAsInt();
loader.register(new PotionTypeImpl(NamespaceID.from(namespace), id));
});
static PotionType get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static PotionType getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static PotionType getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<PotionType> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject potionTypes = Registry.load(Registry.Resource.POTION_TYPES);
potionTypes.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
final int id = object.get("id").getAsInt();
LOADER.register(new PotionTypeImpl(NamespaceID.from(namespace), id));
});
return CONTAINER.values();
}
private final NamespaceID namespaceID;

View File

@ -49,7 +49,7 @@ public class Registry {
return GSON.fromJson(new InputStreamReader(resourceStream), JsonObject.class);
}
public static class Loader<T extends ProtocolObject> {
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
@ -58,6 +58,15 @@ public class Registry {
// id -> registry data
private final Int2ObjectMap<T> idMap = new Int2ObjectOpenHashMap<>();
public Container(Resource resource, Loader<T> loader) {
final JsonObject objects = Registry.load(resource);
objects.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
loader.accept(this, namespace, object);
});
}
public T get(@NotNull String namespace) {
return namespaceMap.get(namespace);
}
@ -78,6 +87,10 @@ public class Registry {
idMap.put(value.id(), value);
namespaceMap.put(value.name(), value);
}
public interface Loader<T extends ProtocolObject> {
void accept(Container<T> container, String namespace, JsonObject object);
}
}
public enum Resource {

View File

@ -1,6 +1,5 @@
package net.minestom.server.sound;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
@ -8,33 +7,26 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class SoundEventImpl implements SoundEvent {
private static final Registry.Loader<SoundEvent> LOADER = new Registry.Loader<>();
private static final Registry.Container<SoundEvent> CONTAINER = new Registry.Container<>(Registry.Resource.SOUNDS,
(container, namespace, object) -> {
final int id = object.get("id").getAsInt();
container.register(new SoundEventImpl(NamespaceID.from(namespace), id));
});
static SoundEvent get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static SoundEvent getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static SoundEvent getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<SoundEvent> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject sounds = Registry.load(Registry.Resource.SOUNDS);
sounds.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
final int id = object.get("id").getAsInt();
LOADER.register(new SoundEventImpl(NamespaceID.from(namespace), id));
});
return CONTAINER.values();
}
private final NamespaceID namespaceID;

View File

@ -1,6 +1,5 @@
package net.minestom.server.statistic;
import com.google.gson.JsonObject;
import net.minestom.server.registry.Registry;
import net.minestom.server.utils.NamespaceID;
import org.jetbrains.annotations.NotNull;
@ -8,33 +7,26 @@ import org.jetbrains.annotations.NotNull;
import java.util.Collection;
final class StatisticTypeImpl implements StatisticType {
private static final Registry.Loader<StatisticType> LOADER = new Registry.Loader<>();
private static final Registry.Container<StatisticType> CONTAINER = new Registry.Container<>(Registry.Resource.STATISTICS,
(container, namespace, object) -> {
final int id = object.get("id").getAsInt();
container.register(new StatisticTypeImpl(NamespaceID.from(namespace), id));
});
static StatisticType get(@NotNull String namespace) {
return LOADER.get(namespace);
return CONTAINER.get(namespace);
}
static StatisticType getSafe(@NotNull String namespace) {
return LOADER.getSafe(namespace);
return CONTAINER.getSafe(namespace);
}
static StatisticType getId(int id) {
return LOADER.getId(id);
return CONTAINER.getId(id);
}
static Collection<StatisticType> values() {
return LOADER.values();
}
static {
// Load data from file
JsonObject statistics = Registry.load(Registry.Resource.STATISTICS);
statistics.entrySet().forEach(entry -> {
final String namespace = entry.getKey();
final JsonObject object = entry.getValue().getAsJsonObject();
final int id = object.get("id").getAsInt();
LOADER.register(new StatisticTypeImpl(NamespaceID.from(namespace), id));
});
return CONTAINER.values();
}
private final NamespaceID namespaceID;

View File

@ -5,6 +5,8 @@ import demo.generator.NoiseTestGenerator;
import net.kyori.adventure.text.Component;
import net.minestom.server.MinecraftServer;
import net.minestom.server.adventure.audience.Audiences;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.entity.Entity;
import net.minestom.server.entity.GameMode;
import net.minestom.server.entity.ItemEntity;
@ -30,8 +32,6 @@ import net.minestom.server.item.Material;
import net.minestom.server.monitoring.BenchmarkManager;
import net.minestom.server.monitoring.TickMonitor;
import net.minestom.server.utils.MathUtils;
import net.minestom.server.coordinate.Pos;
import net.minestom.server.coordinate.Vec;
import net.minestom.server.utils.time.TimeUnit;
import net.minestom.server.world.DimensionType;