From 25339ca4ef6007f817fc53cfbbfdd08073c2f1d1 Mon Sep 17 00:00:00 2001 From: dfsek Date: Mon, 5 Jul 2021 00:02:48 -0700 Subject: [PATCH] working biome config addon --- common/addons/biome/config/build.gradle.kts | 4 + .../terra/addons/biome/BiomeConfigAddon.java | 27 +++++++ .../terra/addons/biome/BiomeConfigType.java | 47 ++++++++++++ .../dfsek/terra/api/config/ConfigPack.java | 3 + .../dfsek/terra/api/config/ConfigType.java | 4 +- .../api/registry/meta/RegistryFactory.java | 26 +++++++ .../config/fileloaders/FolderLoader.java | 1 + .../terra/config/fileloaders/ZIPLoader.java | 1 + .../terra/config/pack/ConfigPackImpl.java | 24 +++++- .../terra/registry/RegistryFactoryImpl.java | 29 ++++++++ .../terra/registry/config/BiomeRegistry.java | 19 ----- .../registry/config/ConfigTypeRegistry.java | 73 +------------------ 12 files changed, 164 insertions(+), 94 deletions(-) create mode 100644 common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigAddon.java create mode 100644 common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigType.java create mode 100644 common/api/src/main/java/com/dfsek/terra/api/registry/meta/RegistryFactory.java create mode 100644 common/implementation/src/main/java/com/dfsek/terra/registry/RegistryFactoryImpl.java delete mode 100644 common/implementation/src/main/java/com/dfsek/terra/registry/config/BiomeRegistry.java diff --git a/common/addons/biome/config/build.gradle.kts b/common/addons/biome/config/build.gradle.kts index 4b0339e03..a55e7cdac 100644 --- a/common/addons/biome/config/build.gradle.kts +++ b/common/addons/biome/config/build.gradle.kts @@ -34,6 +34,10 @@ dependencies { "testImplementation"("com.google.guava:guava:30.0-jre") } +tasks.named("jar") { + archiveBaseName.set("Terra-biome") +} + publishing { publications { create("mavenJava") { diff --git a/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigAddon.java b/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigAddon.java new file mode 100644 index 000000000..33157d194 --- /dev/null +++ b/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigAddon.java @@ -0,0 +1,27 @@ +package com.dfsek.terra.addons.biome; + +import com.dfsek.terra.api.TerraPlugin; +import com.dfsek.terra.api.addon.TerraAddon; +import com.dfsek.terra.api.addon.annotations.Addon; +import com.dfsek.terra.api.addon.annotations.Author; +import com.dfsek.terra.api.addon.annotations.Version; +import com.dfsek.terra.api.event.EventListener; +import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.injection.annotations.Inject; + +@Addon("core-biome-config") +@Author("Terra") +@Version("1.0.0") +public class BiomeConfigAddon extends TerraAddon implements EventListener { + @Inject + private TerraPlugin main; + + @Override + public void initialize() { + main.getEventManager().registerListener(this, this); + } + + public void onPackLoad(ConfigPackPreLoadEvent event) { + event.getPack().registerConfigType(new BiomeConfigType(event.getPack()), "BIOME", 5); + } +} diff --git a/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigType.java b/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigType.java new file mode 100644 index 000000000..3fd136382 --- /dev/null +++ b/common/addons/biome/config/src/main/java/com/dfsek/terra/addons/biome/BiomeConfigType.java @@ -0,0 +1,47 @@ +package com.dfsek.terra.addons.biome; + +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.loading.TypeLoader; +import com.dfsek.terra.api.TerraPlugin; +import com.dfsek.terra.api.config.ConfigFactory; +import com.dfsek.terra.api.config.ConfigPack; +import com.dfsek.terra.api.config.ConfigType; +import com.dfsek.terra.api.registry.OpenRegistry; +import com.dfsek.terra.api.util.seeded.BiomeBuilder; + +import java.lang.reflect.Type; +import java.util.function.Supplier; + +public class BiomeConfigType implements ConfigType { + private final ConfigPack pack; + private final BiomeFactory factory; + + public BiomeConfigType(ConfigPack pack) { + this.pack = pack; + this.factory = new BiomeFactory(pack); + } + + @Override + public BiomeTemplate getTemplate(ConfigPack pack, TerraPlugin main) { + return new BiomeTemplate(pack, main); + } + + @Override + public ConfigFactory getFactory() { + return factory; + } + + @Override + public Class getTypeClass() { + return BiomeBuilder.class; + } + + @Override + public Supplier> registrySupplier() { + return () -> pack.getRegistryFactory().create(registry -> (TypeLoader) (t, c, loader) -> { + if(c.equals("SELF")) return null; + return registry.load(t, c, loader); + }); + } +} diff --git a/common/api/src/main/java/com/dfsek/terra/api/config/ConfigPack.java b/common/api/src/main/java/com/dfsek/terra/api/config/ConfigPack.java index f0c09a41c..7a7b45a8e 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/config/ConfigPack.java +++ b/common/api/src/main/java/com/dfsek/terra/api/config/ConfigPack.java @@ -1,5 +1,6 @@ package com.dfsek.terra.api.config; +import com.dfsek.terra.api.registry.meta.RegistryFactory; import com.dfsek.terra.api.registry.meta.RegistryHolder; import com.dfsek.terra.api.tectonic.LoaderHolder; import com.dfsek.terra.api.tectonic.LoaderRegistrar; @@ -41,4 +42,6 @@ public interface ConfigPack extends LoaderRegistrar, LoaderHolder, RegistryHolde boolean doBetaCarvers(); boolean vanillaFlora(); + + RegistryFactory getRegistryFactory(); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/config/ConfigType.java b/common/api/src/main/java/com/dfsek/terra/api/config/ConfigType.java index 7e8ed0b39..46aa2de98 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/config/ConfigType.java +++ b/common/api/src/main/java/com/dfsek/terra/api/config/ConfigType.java @@ -7,10 +7,10 @@ import com.dfsek.terra.api.registry.OpenRegistry; import java.util.function.Supplier; -public interface ConfigType { +public interface ConfigType { T getTemplate(ConfigPack pack, TerraPlugin main); - void callback(ConfigPack pack, TerraPlugin main, T loadedConfig) throws LoadException; + ConfigFactory getFactory(); Class getTypeClass(); diff --git a/common/api/src/main/java/com/dfsek/terra/api/registry/meta/RegistryFactory.java b/common/api/src/main/java/com/dfsek/terra/api/registry/meta/RegistryFactory.java new file mode 100644 index 000000000..bc041c4f5 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/registry/meta/RegistryFactory.java @@ -0,0 +1,26 @@ +package com.dfsek.terra.api.registry.meta; + +import com.dfsek.tectonic.loading.TypeLoader; +import com.dfsek.terra.api.registry.OpenRegistry; + +import java.util.function.Function; + +/** + * Helpers to avoid creating entire registry implementations for simple overrides. + */ +public interface RegistryFactory { + /** + * Create a generic OpenRegistry. + * @param Type of registry. + * @return New OpenRegistry + */ + OpenRegistry create(); + + /** + * Create an OpenRegistry with custom {@link TypeLoader} + * @param loader Function to create loader. + * @param Type of registry. + * @return New OpenRegistry. + */ + OpenRegistry create(Function, TypeLoader> loader); +} diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/FolderLoader.java b/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/FolderLoader.java index f54708bff..f27728d92 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/FolderLoader.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/FolderLoader.java @@ -32,6 +32,7 @@ public class FolderLoader extends Loader { paths.filter(Files::isRegularFile).filter(file -> file.toString().toLowerCase().endsWith(extension)).forEach(file -> { try { String rel = newPath.toPath().relativize(file).toString(); + if(rel.equals("pack.yml")) return; streams.put(rel, new FileInputStream(file.toFile())); } catch(FileNotFoundException e) { e.printStackTrace(); diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/ZIPLoader.java b/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/ZIPLoader.java index 8c94af81a..fd571baa9 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/ZIPLoader.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/fileloaders/ZIPLoader.java @@ -28,6 +28,7 @@ public class ZIPLoader extends Loader { Enumeration entries = file.entries(); while(entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); + if(entry.getName().equals("pack.yml")) continue; if(!entry.isDirectory() && entry.getName().startsWith(directory) && entry.getName().endsWith(extension)) { try { String rel = entry.getName().substring(directory.length()); diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java index d8f947c78..8b34f9f89 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java +++ b/common/implementation/src/main/java/com/dfsek/terra/config/pack/ConfigPackImpl.java @@ -13,12 +13,16 @@ import com.dfsek.tectonic.loading.TypeRegistry; import com.dfsek.tectonic.loading.object.ObjectTemplate; import com.dfsek.terra.api.TerraPlugin; import com.dfsek.terra.api.addon.TerraAddon; +import com.dfsek.terra.api.config.AbstractableTemplate; +import com.dfsek.terra.api.config.ConfigFactory; import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigType; import com.dfsek.terra.api.event.events.config.ConfigPackPostLoadEvent; import com.dfsek.terra.api.event.events.config.ConfigPackPreLoadEvent; import com.dfsek.terra.api.registry.CheckedRegistry; import com.dfsek.terra.api.registry.OpenRegistry; +import com.dfsek.terra.api.registry.exception.DuplicateEntryException; +import com.dfsek.terra.api.registry.meta.RegistryFactory; import com.dfsek.terra.api.structure.LootTable; import com.dfsek.terra.api.structure.Structure; import com.dfsek.terra.api.util.generic.pair.ImmutablePair; @@ -33,6 +37,7 @@ import com.dfsek.terra.config.loaders.config.BufferedImageLoader; import com.dfsek.terra.config.prototype.ProtoConfig; import com.dfsek.terra.registry.CheckedRegistryImpl; import com.dfsek.terra.registry.OpenRegistryImpl; +import com.dfsek.terra.registry.RegistryFactoryImpl; import com.dfsek.terra.registry.config.ConfigTypeRegistry; import com.dfsek.terra.registry.config.NoiseRegistry; import com.dfsek.terra.world.TerraWorldImpl; @@ -63,6 +68,8 @@ import java.util.zip.ZipFile; public class ConfigPackImpl implements ConfigPack { private final ConfigPackTemplate template = new ConfigPackTemplate(); + private final RegistryFactory registryFactory = new RegistryFactoryImpl(); + private final Map> loaders = new HashMap<>(); private final Map>> objectLoaders = new HashMap<>(); @@ -84,7 +91,7 @@ public class ConfigPackImpl implements ConfigPack { public ConfigPackImpl(File folder, TerraPlugin main) throws ConfigException { try { - this.configTypeRegistry = new ConfigTypeRegistry((id, configType) -> { + this.configTypeRegistry = new ConfigTypeRegistry(main, (id, configType) -> { OpenRegistry openRegistry = configType.registrySupplier().get(); registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry))); }); @@ -127,7 +134,7 @@ public class ConfigPackImpl implements ConfigPack { public ConfigPackImpl(ZipFile file, TerraPlugin main) throws ConfigException { try { - this.configTypeRegistry = new ConfigTypeRegistry((id, configType) -> { + this.configTypeRegistry = new ConfigTypeRegistry(main, (id, configType) -> { OpenRegistry openRegistry = configType.registrySupplier().get(); registryMap.put(configType.getTypeClass(), ImmutablePair.of(openRegistry, new CheckedRegistryImpl<>(openRegistry))); }); @@ -238,8 +245,12 @@ public class ConfigPackImpl implements ConfigPack { } for(ConfigType configType : configTypeRegistry.entries()) { - for(ConfigTemplate config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()), () -> configType.getTemplate(this, main))) { - ((ConfigType) configType).callback(this, main, config); + for(AbstractableTemplate config : abstractConfigLoader.loadConfigs(configs.getOrDefault(configType, Collections.emptyList()), () -> configType.getTemplate(this, main))) { + try { + ((CheckedRegistry) getRegistry(configType.getTypeClass())).add(config.getID(), ((ConfigFactory) configType.getFactory()).build(config, main)); + } catch(DuplicateEntryException e) { + throw new LoadException("Duplicate registry entry: ", e); + } } } @@ -361,4 +372,9 @@ public class ConfigPackImpl implements ConfigPack { public boolean vanillaFlora() { return template.vanillaDecorations(); } + + @Override + public RegistryFactory getRegistryFactory() { + return registryFactory; + } } diff --git a/common/implementation/src/main/java/com/dfsek/terra/registry/RegistryFactoryImpl.java b/common/implementation/src/main/java/com/dfsek/terra/registry/RegistryFactoryImpl.java new file mode 100644 index 000000000..d9c0d6e81 --- /dev/null +++ b/common/implementation/src/main/java/com/dfsek/terra/registry/RegistryFactoryImpl.java @@ -0,0 +1,29 @@ +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.api.registry.OpenRegistry; +import com.dfsek.terra.api.registry.meta.RegistryFactory; +import com.dfsek.terra.api.util.generic.Lazy; + +import java.lang.reflect.Type; +import java.util.function.Function; + +public class RegistryFactoryImpl implements RegistryFactory { + @Override + public OpenRegistry create() { + return new OpenRegistryImpl<>(); + } + + @Override + public OpenRegistry create(Function, TypeLoader> loader) { + return new OpenRegistryImpl<>() { + private final Lazy> loaderCache = Lazy.of(() -> loader.apply(this)); + @Override + public T load(Type type, Object o, ConfigLoader configLoader) throws LoadException { + return loaderCache.value().load(type, o, configLoader); + } + }; + } +} diff --git a/common/implementation/src/main/java/com/dfsek/terra/registry/config/BiomeRegistry.java b/common/implementation/src/main/java/com/dfsek/terra/registry/config/BiomeRegistry.java deleted file mode 100644 index 67205999d..000000000 --- a/common/implementation/src/main/java/com/dfsek/terra/registry/config/BiomeRegistry.java +++ /dev/null @@ -1,19 +0,0 @@ -package com.dfsek.terra.registry.config; - -import com.dfsek.tectonic.exception.LoadException; -import com.dfsek.tectonic.loading.ConfigLoader; -import com.dfsek.terra.api.util.seeded.BiomeBuilder; -import com.dfsek.terra.registry.OpenRegistryImpl; - -import java.lang.reflect.Type; - -public class BiomeRegistry extends OpenRegistryImpl { - @Override - public BiomeBuilder load(Type type, Object o, ConfigLoader configLoader) throws LoadException { - if(o.equals("SELF")) return null; - BiomeBuilder biome = get((String) o); - if(biome == null) - throw new LoadException("No such " + type.getTypeName() + " matching \"" + o + "\" was found in this registry."); - return biome; - } -} diff --git a/common/implementation/src/main/java/com/dfsek/terra/registry/config/ConfigTypeRegistry.java b/common/implementation/src/main/java/com/dfsek/terra/registry/config/ConfigTypeRegistry.java index 0f216b884..03e75e1bd 100644 --- a/common/implementation/src/main/java/com/dfsek/terra/registry/config/ConfigTypeRegistry.java +++ b/common/implementation/src/main/java/com/dfsek/terra/registry/config/ConfigTypeRegistry.java @@ -1,91 +1,26 @@ package com.dfsek.terra.registry.config; -import com.dfsek.tectonic.config.ConfigTemplate; -import com.dfsek.tectonic.exception.LoadException; import com.dfsek.terra.api.TerraPlugin; -import com.dfsek.terra.api.config.AbstractableTemplate; -import com.dfsek.terra.api.config.ConfigFactory; -import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.ConfigType; -import com.dfsek.terra.api.registry.OpenRegistry; -import com.dfsek.terra.config.pack.ConfigPackImpl; import com.dfsek.terra.registry.OpenRegistryImpl; import java.util.LinkedHashMap; import java.util.function.BiConsumer; -import java.util.function.Supplier; public class ConfigTypeRegistry extends OpenRegistryImpl> { private final BiConsumer> callback; - public ConfigTypeRegistry(BiConsumer> callback) { + private final TerraPlugin main; + public ConfigTypeRegistry(TerraPlugin main, BiConsumer> callback) { super(new LinkedHashMap<>()); // Ordered this.callback = callback; - add("PACK", new PackBuilder()); + this.main = main; } @Override public boolean add(String identifier, Entry> value) { callback.accept(identifier, value.getValue()); + main.getDebugLogger().info("Registered config registry with ID " + identifier + " to class " + value.getValue().getTypeClass().getCanonicalName()); return super.add(identifier, value); } - - private static final class PackBuilder implements ConfigType { - - @Override - public ConfigTemplate getTemplate(ConfigPack pack, TerraPlugin main) { - return new ConfigTemplate() { - }; - } - - @Override - public void callback(ConfigPack pack, TerraPlugin main, ConfigTemplate loadedConfig) { - - } - - @Override - public Class getTypeClass() { - return ConfigPack.class; - } - - @Override - public Supplier> registrySupplier() { - return OpenRegistryImpl::new; - } - } - - private static final class ConfigBuilder implements ConfigType { - private final ConfigFactory factory; - private final Supplier provider; - private final Class clazz; - private final Supplier> registrySupplier; - - private ConfigBuilder(ConfigFactory factory, Supplier provider, Class clazz, Supplier> registrySupplier) { - this.factory = factory; - this.provider = provider; - this.clazz = clazz; - this.registrySupplier = registrySupplier; - } - - @Override - public T getTemplate(ConfigPack pack, TerraPlugin main) { - return provider.get(); - } - - @SuppressWarnings("deprecation") - @Override - public void callback(ConfigPack pack, TerraPlugin main, T loadedConfig) throws LoadException { - pack.getRegistry(clazz).addUnchecked(loadedConfig.getID(), factory.build(loadedConfig, main)); - } - - @Override - public Class getTypeClass() { - return clazz; - } - - @Override - public Supplier> registrySupplier() { - return registrySupplier; - } - } }