diff --git a/common/addons/language-yaml/src/main/java/com/dfsek/terra/addons/yaml/YamlAddon.java b/common/addons/language-yaml/src/main/java/com/dfsek/terra/addons/yaml/YamlAddon.java index a8567658e..2d5840c41 100644 --- a/common/addons/language-yaml/src/main/java/com/dfsek/terra/addons/yaml/YamlAddon.java +++ b/common/addons/language-yaml/src/main/java/com/dfsek/terra/addons/yaml/YamlAddon.java @@ -23,6 +23,6 @@ public class YamlAddon extends TerraAddon implements EventListener { } public void loadYamlConfigs(ConfigurationDiscoveryEvent event) { - event.getLoader().open("", ".yml").thenEntries(entries -> entries.forEach(entry -> event.register(new YamlConfiguration(entry.getValue(), entry.getKey())))); + event.getLoader().open("", ".yml").thenEntries(entries -> entries.forEach(entry -> event.register(entry.getKey(), new YamlConfiguration(entry.getValue(), entry.getKey())))); } } diff --git a/common/api/build.gradle.kts b/common/api/build.gradle.kts index ef64d7c34..a903cf25c 100644 --- a/common/api/build.gradle.kts +++ b/common/api/build.gradle.kts @@ -15,8 +15,8 @@ group = "com.dfsek.terra.common" dependencies { "shadedApi"("com.dfsek:Paralithic:0.4.0") - "shadedApi"("com.dfsek.tectonic:common:2.1.1") - "shadedApi"("com.dfsek.tectonic:yaml:2.1.1") + "shadedApi"("com.dfsek.tectonic:common:2.1.2") + "shadedApi"("com.dfsek.tectonic:yaml:2.1.2") "shadedApi"("net.jafama:jafama:2.3.2") "shadedApi"("org.yaml:snakeyaml:1.27") diff --git a/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigurationDiscoveryEvent.java b/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigurationDiscoveryEvent.java index 0037dacc2..ada69920a 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigurationDiscoveryEvent.java +++ b/common/api/src/main/java/com/dfsek/terra/api/event/events/config/ConfigurationDiscoveryEvent.java @@ -5,6 +5,7 @@ import com.dfsek.terra.api.config.ConfigPack; import com.dfsek.terra.api.config.Loader; import com.dfsek.terra.api.event.events.PackEvent; +import java.util.function.BiConsumer; import java.util.function.Consumer; /** @@ -17,9 +18,9 @@ public class ConfigurationDiscoveryEvent implements PackEvent { private final ConfigPack pack; private final Loader loader; - private final Consumer consumer; + private final BiConsumer consumer; - public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, Consumer consumer) { + public ConfigurationDiscoveryEvent(ConfigPack pack, Loader loader, BiConsumer consumer) { this.pack = pack; this.loader = loader; this.consumer = consumer; @@ -34,7 +35,7 @@ public class ConfigurationDiscoveryEvent implements PackEvent { return loader; } - public void register(Configuration config) { - consumer.accept(config); + public void register(String identifier, Configuration config) { + consumer.accept(identifier, config); } } 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 ec945ff43..39a28eeef 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 @@ -18,6 +18,7 @@ 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.config.Loader; +import com.dfsek.terra.api.config.meta.Meta; import com.dfsek.terra.api.event.events.config.ConfigurationDiscoveryEvent; import com.dfsek.terra.api.event.events.config.ConfigurationLoadEvent; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPostLoadEvent; @@ -40,6 +41,7 @@ import com.dfsek.terra.config.fileloaders.FolderLoader; import com.dfsek.terra.config.fileloaders.ZIPLoader; import com.dfsek.terra.config.loaders.GenericTemplateSupplierLoader; import com.dfsek.terra.config.loaders.config.BufferedImageLoader; +import com.dfsek.terra.config.preprocessor.MetaValuePreprocessor; import com.dfsek.terra.config.prototype.ProtoConfig; import com.dfsek.terra.registry.CheckedRegistryImpl; import com.dfsek.terra.registry.OpenRegistryImpl; @@ -234,13 +236,16 @@ public class ConfigPackImpl implements ConfigPack { varScope.create(var.getKey(), var.getValue()); } - List configurations = new ArrayList<>(); + Map configurations = new HashMap<>(); - main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::add)); // Create all the configs. + main.getEventManager().callEvent(new ConfigurationDiscoveryEvent(this, loader, configurations::put)); // Create all the configs. + + selfLoader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurations)); + abstractConfigLoader.registerPreprocessor(Meta.class, new MetaValuePreprocessor(configurations)); Map, List> configs = new HashMap<>(); - for(Configuration configuration : configurations) { // Sort the configs + for(Configuration configuration : configurations.values()) { // Sort the configs ProtoConfig config = new ProtoConfig(); selfLoader.load(config, configuration); configs.computeIfAbsent(config.getType(), configType -> new ArrayList<>()).add(configuration); diff --git a/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java new file mode 100644 index 000000000..81a39bc37 --- /dev/null +++ b/common/implementation/src/main/java/com/dfsek/terra/config/preprocessor/MetaValuePreprocessor.java @@ -0,0 +1,44 @@ +package com.dfsek.terra.config.preprocessor; + +import com.dfsek.tectonic.config.Configuration; +import com.dfsek.tectonic.exception.LoadException; +import com.dfsek.tectonic.loading.ConfigLoader; +import com.dfsek.tectonic.preprocessor.Result; +import com.dfsek.tectonic.preprocessor.ValuePreprocessor; +import com.dfsek.terra.api.config.meta.Meta; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.Map; + +public class MetaValuePreprocessor implements ValuePreprocessor { + private final Map configs; + + public MetaValuePreprocessor(Map configs) { + this.configs = configs; + } + + @SuppressWarnings("unchecked") + @Override + public @NotNull Result process(AnnotatedType t, T c, ConfigLoader configLoader, Meta annotation) { + if(c instanceof String) { + String value = ((String) c).trim(); + if(value.startsWith("$")) { // it's a meta value. + String raw = value.substring(1); + int sep = raw.indexOf(':'); + String file = raw.substring(0, sep); + String key = raw.substring(sep + 1); + + if(!configs.containsKey(file)) throw new LoadException("Cannot fetch metavalue: No such config: " + file); + + Configuration config = configs.get(file); + + if(!config.contains(key)) + throw new LoadException("Cannot fetch metavalue: No such key " + key + " in configuration " + config.getName()); + + return (Result) Result.overwrite(config.get(key)); + } + } + return Result.noOp(); + } +}