diff --git a/common/addons/config-number-predicate/build.gradle.kts b/common/addons/config-number-predicate/build.gradle.kts new file mode 100644 index 000000000..2ea535016 --- /dev/null +++ b/common/addons/config-number-predicate/build.gradle.kts @@ -0,0 +1,13 @@ +import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar + +version = version("1.0.0") + +dependencies { + compileOnlyApi(project(":common:addons:manifest-addon-loader")) + api("com.dfsek", "paralithic", Versions.Libraries.paralithic) +} + + +tasks.named("shadowJar") { + relocate("com.dfsek.paralithic", "com.dfsek.terra.addons.numberpredicate.lib.paralithic") +} diff --git a/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/DoublePredicateLoader.java b/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/DoublePredicateLoader.java new file mode 100644 index 000000000..4b9bf789e --- /dev/null +++ b/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/DoublePredicateLoader.java @@ -0,0 +1,34 @@ +package com.dfsek.terra.addons.numberpredicate; + +import com.dfsek.paralithic.Expression; +import com.dfsek.paralithic.eval.parser.Parser; +import com.dfsek.paralithic.eval.parser.Scope; +import com.dfsek.paralithic.eval.tokenizer.ParseException; +import com.dfsek.tectonic.api.depth.DepthTracker; +import com.dfsek.tectonic.api.exception.LoadException; +import com.dfsek.tectonic.api.loader.ConfigLoader; +import com.dfsek.tectonic.api.loader.type.TypeLoader; +import org.jetbrains.annotations.NotNull; + +import java.lang.reflect.AnnotatedType; +import java.util.function.DoublePredicate; + + +public class DoublePredicateLoader implements TypeLoader { + @Override + public DoublePredicate load(@NotNull AnnotatedType annotatedType, @NotNull Object o, @NotNull ConfigLoader configLoader, + DepthTracker depthTracker) throws LoadException { + if (o instanceof String expressionString) { + Scope scope = new Scope(); + scope.addInvocationVariable("value"); + try { + Expression expression = new Parser().parse(expressionString, scope); + return d -> expression.evaluate(d) != 0; // Paralithic expressions treat '!= 0' as true + } catch(ParseException e) { + throw new LoadException("Failed to parse double predicate expression", e, depthTracker); + } + } else { + throw new LoadException("Double predicates must be defined as a string. E.g. 'value > 3'", depthTracker); + } + } +} diff --git a/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/NumberPredicateAddon.java b/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/NumberPredicateAddon.java new file mode 100644 index 000000000..e81da028d --- /dev/null +++ b/common/addons/config-number-predicate/src/main/java/com/dfsek/terra/addons/numberpredicate/NumberPredicateAddon.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2020-2021 Polyhedral Development + * + * The Terra Core Addons are licensed under the terms of the MIT License. For more details, + * reference the LICENSE file in this module's root directory. + */ + +package com.dfsek.terra.addons.numberpredicate; + +import com.dfsek.tectonic.api.config.template.object.ObjectTemplate; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.function.DoublePredicate; +import java.util.function.Supplier; + +import com.dfsek.terra.addons.manifest.api.AddonInitializer; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; +import com.dfsek.terra.api.event.functional.FunctionalEventHandler; +import com.dfsek.terra.api.inject.annotations.Inject; + +public class NumberPredicateAddon implements AddonInitializer { + + @Inject + private Platform plugin; + + @Inject + private BaseAddon addon; + + @Override + public void initialize() { + plugin.getEventManager() + .getHandler(FunctionalEventHandler.class) + .register(addon, ConfigPackPreLoadEvent.class) + .then(event -> event.getPack().applyLoader(DoublePredicate.class, new DoublePredicateLoader())) + .priority(50) + .failThrough(); + } +} diff --git a/common/addons/config-number-predicate/src/main/resources/terra.addon.yml b/common/addons/config-number-predicate/src/main/resources/terra.addon.yml new file mode 100644 index 000000000..e4014b3a3 --- /dev/null +++ b/common/addons/config-number-predicate/src/main/resources/terra.addon.yml @@ -0,0 +1,12 @@ +schema-version: 1 +contributors: + - Terra contributors +id: config-number-predicate +version: @VERSION@ +entrypoints: + - "com.dfsek.terra.addons.numberpredicate.NumberPredicateAddon" +website: + issues: https://github.com/PolyhedralDev/Terra/issues + source: https://github.com/PolyhedralDev/Terra + docs: https://terra.polydev.org +license: MIT License \ No newline at end of file