From 8b196716a4c725a62e8cf834289552796b3aed49 Mon Sep 17 00:00:00 2001 From: dfsek Date: Sun, 21 Feb 2021 22:04:29 -0700 Subject: [PATCH] CheckedRegistry API --- .../dfsek/terra/config/pack/ConfigPack.java | 61 ++++++----- .../dfsek/terra/registry/CheckedRegistry.java | 102 ++++++++++++++++++ .../exception/DuplicateEntryException.java | 13 +++ .../master/ChunkGeneratorRegistry.java | 7 -- .../bukkit/listeners/CommonListener.java | 4 +- 5 files changed, 149 insertions(+), 38 deletions(-) create mode 100644 common/src/main/java/com/dfsek/terra/registry/CheckedRegistry.java create mode 100644 common/src/main/java/com/dfsek/terra/registry/exception/DuplicateEntryException.java delete mode 100644 common/src/main/java/com/dfsek/terra/registry/master/ChunkGeneratorRegistry.java diff --git a/common/src/main/java/com/dfsek/terra/config/pack/ConfigPack.java b/common/src/main/java/com/dfsek/terra/config/pack/ConfigPack.java index fb9d433e6..9ad335ecb 100644 --- a/common/src/main/java/com/dfsek/terra/config/pack/ConfigPack.java +++ b/common/src/main/java/com/dfsek/terra/config/pack/ConfigPack.java @@ -6,11 +6,14 @@ import com.dfsek.tectonic.exception.ConfigException; import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.loading.ConfigLoader; import com.dfsek.tectonic.loading.TypeRegistry; +import com.dfsek.tectonic.loading.object.ObjectTemplate; import com.dfsek.terra.api.LoaderRegistrar; import com.dfsek.terra.api.core.TerraPlugin; import com.dfsek.terra.api.core.event.events.config.ConfigPackPostLoadEvent; import com.dfsek.terra.api.core.event.events.config.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.platform.block.BlockData; import com.dfsek.terra.api.structures.loot.LootTable; +import com.dfsek.terra.api.structures.parser.lang.functions.FunctionBuilder; import com.dfsek.terra.api.structures.script.StructureScript; import com.dfsek.terra.api.util.seeded.NoiseSeeded; import com.dfsek.terra.api.world.biome.TerraBiome; @@ -46,6 +49,7 @@ import com.dfsek.terra.config.templates.OreTemplate; import com.dfsek.terra.config.templates.PaletteTemplate; import com.dfsek.terra.config.templates.StructureTemplate; import com.dfsek.terra.config.templates.TreeTemplate; +import com.dfsek.terra.registry.CheckedRegistry; import com.dfsek.terra.registry.TerraRegistry; import com.dfsek.terra.registry.config.BiomeRegistry; import com.dfsek.terra.registry.config.CarverRegistry; @@ -75,6 +79,7 @@ import java.util.Enumeration; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.function.Supplier; import java.util.logging.Level; import java.util.stream.Collectors; import java.util.zip.ZipEntry; @@ -255,10 +260,6 @@ public class ConfigPack implements LoaderRegistrar { return structureRegistry.entries().stream().map(terraStructure -> terraStructure.getTemplate().getID()).collect(Collectors.toList()); } - public TreeRegistry getTreeRegistry() { - return treeRegistry; - } - public ConfigPackTemplate getTemplate() { return template; } @@ -287,14 +288,6 @@ public class ConfigPack implements LoaderRegistrar { .registerLoader(ImageSamplerTemplate.class, () -> new ImageProviderTemplate(biomeRegistry)); } - public ScriptRegistry getScriptRegistry() { - return scriptRegistry; - } - - public BiomeRegistry getBiomeRegistry() { - return biomeRegistry; - } - public SamplerCache getSamplerCache() { return samplerCache; } @@ -307,35 +300,47 @@ public class ConfigPack implements LoaderRegistrar { return biomeProviderBuilder; } - public FunctionRegistry getFunctionRegistry() { - return functionRegistry; + public CheckedRegistry getScriptRegistry() { + return new CheckedRegistry<>(scriptRegistry); } - public NoiseRegistry getNormalizerRegistry() { - return noiseRegistry; + public CheckedRegistry getBiomeRegistry() { + return new CheckedRegistry<>(biomeRegistry); } - public CarverRegistry getCarverRegistry() { - return carverRegistry; + public CheckedRegistry getTreeRegistry() { + return new CheckedRegistry<>(treeRegistry); } - public FloraRegistry getFloraRegistry() { - return floraRegistry; + public CheckedRegistry> getFunctionRegistry() { + return new CheckedRegistry<>(functionRegistry); } - public LootRegistry getLootRegistry() { - return lootRegistry; + public CheckedRegistry>> getNormalizerRegistry() { + return new CheckedRegistry<>(noiseRegistry); } - public OreRegistry getOreRegistry() { - return oreRegistry; + public CheckedRegistry getCarverRegistry() { + return new CheckedRegistry<>(carverRegistry); } - public PaletteRegistry getPaletteRegistry() { - return paletteRegistry; + public CheckedRegistry getFloraRegistry() { + return new CheckedRegistry<>(floraRegistry); } - public StructureRegistry getStructureRegistry() { - return structureRegistry; + public CheckedRegistry getLootRegistry() { + return new CheckedRegistry<>(lootRegistry); + } + + public CheckedRegistry getOreRegistry() { + return new CheckedRegistry<>(oreRegistry); + } + + public CheckedRegistry> getPaletteRegistry() { + return new CheckedRegistry<>(paletteRegistry); + } + + public CheckedRegistry getStructureRegistry() { + return new CheckedRegistry<>(structureRegistry); } } diff --git a/common/src/main/java/com/dfsek/terra/registry/CheckedRegistry.java b/common/src/main/java/com/dfsek/terra/registry/CheckedRegistry.java new file mode 100644 index 000000000..29cb08708 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/registry/CheckedRegistry.java @@ -0,0 +1,102 @@ +package com.dfsek.terra.registry; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.loading.TypeLoader; +import com.dfsek.terra.registry.exception.DuplicateEntryException; + +import java.lang.reflect.Type; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.Consumer; + +/** + * Wrapper for a registry that ensures checked access. + * + * @param Type in registry + */ +public class CheckedRegistry implements TypeLoader { + private final TerraRegistry registry; + + public CheckedRegistry(TerraRegistry registry) { + this.registry = registry; + } + + /** + * Add a value to this registry, checking whether it is present first. + * + * @param identifier Identifier to assign value. + * @param value Value to add. + * @throws DuplicateEntryException If an entry with the same identifier is already present. + */ + public void add(String identifier, T value) throws DuplicateEntryException { + if(registry.contains(identifier)) throw new DuplicateEntryException("Entry \"" + identifier + "\" is already present in registry."); + registry.addChecked(identifier, value); + } + + /** + * Add a value to the registry, without checking presence beforehand. + *

+ * Use of this method is generally discouraged, as it is bad practice to overwrite registry values. + * + * @param identifier Identifier to assign value. + * @param value Value to add. + * @deprecated Use of {@link #add(String, Object)} is encouraged. + */ + @Deprecated + public void addUnchecked(String identifier, T value) { + registry.add(identifier, value); + } + + /** + * Get a value from the registry. + * + * @param identifier Identifier of value. + * @return Value matching the identifier, {@code null} if no value is present. + */ + public T get(String identifier) { + return registry.get(identifier); + } + + /** + * Check if the registry contains a value. + * + * @param identifier Identifier of value. + * @return Whether the registry contains the value. + */ + public boolean contains(String identifier) { + return registry.contains(identifier); + } + + /** + * Perform the given action for every value in the registry. + * + * @param consumer Action to perform on value. + */ + public void forEach(Consumer consumer) { + registry.forEach(consumer); + } + + /** + * Perform an action for every key-value pair in the registry. + * + * @param consumer Action to perform on pair. + */ + public void forEach(BiConsumer consumer) { + registry.forEach(consumer); + } + + /** + * Get the entries of this registry as a {@link Set}. + * + * @return Set containing all entries. + */ + public Set entries() { + return registry.entries(); + } + + @Override + public T load(Type t, Object c, ConfigLoader loader) throws LoadException { + return registry.load(t, c, loader); + } +} diff --git a/common/src/main/java/com/dfsek/terra/registry/exception/DuplicateEntryException.java b/common/src/main/java/com/dfsek/terra/registry/exception/DuplicateEntryException.java new file mode 100644 index 000000000..df965eabb --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/registry/exception/DuplicateEntryException.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.registry.exception; + +public class DuplicateEntryException extends Exception { + private static final long serialVersionUID = -7199021672428288780L; + + public DuplicateEntryException(String message) { + super(message); + } + + public DuplicateEntryException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/common/src/main/java/com/dfsek/terra/registry/master/ChunkGeneratorRegistry.java b/common/src/main/java/com/dfsek/terra/registry/master/ChunkGeneratorRegistry.java deleted file mode 100644 index 93ee25e94..000000000 --- a/common/src/main/java/com/dfsek/terra/registry/master/ChunkGeneratorRegistry.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.dfsek.terra.registry.master; - -import com.dfsek.terra.api.platform.world.generator.ChunkGenerator; -import com.dfsek.terra.registry.TerraRegistry; - -public class ChunkGeneratorRegistry extends TerraRegistry { -} diff --git a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/CommonListener.java b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/CommonListener.java index b4ef72b18..753b785c9 100644 --- a/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/CommonListener.java +++ b/platforms/bukkit/src/main/java/com/dfsek/terra/bukkit/listeners/CommonListener.java @@ -9,7 +9,6 @@ import com.dfsek.terra.api.util.FastRandom; import com.dfsek.terra.api.world.tree.Tree; import com.dfsek.terra.bukkit.world.BukkitAdapter; import com.dfsek.terra.config.pack.ConfigPack; -import com.dfsek.terra.registry.config.TreeRegistry; import com.dfsek.terra.world.TerraWorld; import org.bukkit.Material; import org.bukkit.TreeType; @@ -53,8 +52,7 @@ public class CommonListener implements Listener { Block block = e.getLocation().getBlock(); BlockData data = block.getBlockData(); block.setType(Material.AIR); - TreeRegistry registry = c.getTreeRegistry(); - Tree tree = registry.get(TREE_TYPE_STRING_TRANSFORMER.translate(e.getSpecies())); + Tree tree = c.getTreeRegistry().get(TREE_TYPE_STRING_TRANSFORMER.translate(e.getSpecies())); org.bukkit.Location location = e.getLocation(); if(!tree.plant(new Location(bukkit, location.getX(), location.getY(), location.getZ()), new FastRandom())) block.setBlockData(data); }