added condition equations (see Equation#asBoolean)

DepthDependentSelector -> ConditionalSelector
This commit is contained in:
CreepyCre 2021-02-04 15:53:52 +01:00
parent fa93651cb8
commit 52362b6107
3 changed files with 69 additions and 37 deletions

View file

@ -8,9 +8,7 @@ import net.minecraft.util.registry.Registry;
import net.minecraft.util.registry.RegistryKey; import net.minecraft.util.registry.RegistryKey;
import net.minecraft.util.registry.SimpleRegistry; import net.minecraft.util.registry.SimpleRegistry;
import org.dimdev.dimdoors.pockets.virtual.reference.IdReference; import org.dimdev.dimdoors.pockets.virtual.reference.IdReference;
import org.dimdev.dimdoors.pockets.virtual.selection.DepthDependentSelector; import org.dimdev.dimdoors.pockets.virtual.selection.ConditionalSelector;
import org.dimdev.dimdoors.util.PocketGenerationParameters;
import org.dimdev.dimdoors.world.pocket.Pocket;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -56,7 +54,7 @@ public abstract class VirtualSingularPocket implements VirtualPocket {
public interface VirtualSingularPocketType<T extends VirtualSingularPocket> { public interface VirtualSingularPocketType<T extends VirtualSingularPocket> {
VirtualSingularPocketType<IdReference> ID_REFERENCE = register(new Identifier("dimdoors", IdReference.KEY), IdReference::new); VirtualSingularPocketType<IdReference> ID_REFERENCE = register(new Identifier("dimdoors", IdReference.KEY), IdReference::new);
VirtualSingularPocketType<DepthDependentSelector> DEPTH_DEPENDENT_SELECTOR = register(new Identifier("dimdoors", DepthDependentSelector.KEY), DepthDependentSelector::new); VirtualSingularPocketType<ConditionalSelector> DEPTH_DEPENDENT_SELECTOR = register(new Identifier("dimdoors", ConditionalSelector.KEY), ConditionalSelector::new);
VirtualSingularPocket fromTag(CompoundTag tag); VirtualSingularPocket fromTag(CompoundTag tag);

View file

@ -3,18 +3,22 @@ package org.dimdev.dimdoors.pockets.virtual.selection;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag; import net.minecraft.nbt.ListTag;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.dimdev.dimdoors.pockets.virtual.VirtualPocket; import org.dimdev.dimdoors.pockets.virtual.VirtualPocket;
import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket; import org.dimdev.dimdoors.pockets.virtual.VirtualSingularPocket;
import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference; import org.dimdev.dimdoors.pockets.virtual.reference.PocketGeneratorReference;
import org.dimdev.dimdoors.util.PocketGenerationParameters; import org.dimdev.dimdoors.util.PocketGenerationParameters;
import org.dimdev.dimdoors.util.math.Equation;
import org.dimdev.dimdoors.world.pocket.Pocket; import org.dimdev.dimdoors.world.pocket.Pocket;
import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
import java.util.regex.Pattern;
public class DepthDependentSelector extends VirtualSingularPocket { public class ConditionalSelector extends VirtualSingularPocket {
public static final String KEY = "depth_dependent"; private static final Logger LOGGER = LogManager.getLogger();
public static final String KEY = "conditional";
/* /*
private static final Codec<Pair<String, VirtualPocket>> PAIR_CODEC = RecordCodecBuilder.create(instance -> instance.group( private static final Codec<Pair<String, VirtualPocket>> PAIR_CODEC = RecordCodecBuilder.create(instance -> instance.group(
Codec.STRING.fieldOf("regex").forGetter(Pair::getLeft), Codec.STRING.fieldOf("regex").forGetter(Pair::getLeft),
@ -29,35 +33,33 @@ public class DepthDependentSelector extends VirtualSingularPocket {
private String name; private LinkedHashMap<String, VirtualPocket> pocketMap = Maps.newLinkedHashMap();
private LinkedHashMap<String, VirtualPocket> pocketList; private LinkedHashMap<String, Equation> equationMap = Maps.newLinkedHashMap();
public DepthDependentSelector() { public ConditionalSelector() {
} }
public DepthDependentSelector(String name, LinkedHashMap<String, VirtualPocket> pocketList) { public ConditionalSelector(LinkedHashMap<String, VirtualPocket> pocketMap) {
this.name = name; this.pocketMap = pocketMap;
this.pocketList = pocketList;
} }
public String getName() { public LinkedHashMap<String, VirtualPocket> getPocketMap() {
return name; return pocketMap;
}
public LinkedHashMap<String, VirtualPocket> getPocketList() {
return pocketList;
} }
@Override @Override
public VirtualSingularPocket fromTag(CompoundTag tag) { public VirtualSingularPocket fromTag(CompoundTag tag) {
this.name = tag.getString("id"); ListTag conditionalPockets = tag.getList("pockets", 10);
ListTag regexPockets = tag.getList("pockets", 10); for (int i = 0; i < conditionalPockets.size(); i++) {
pocketList = Maps.newLinkedHashMap(); CompoundTag pocket = conditionalPockets.getCompound(i);
for (int i = 0; i < regexPockets.size(); i++) { String condition = pocket.getString("condition");
CompoundTag pocket = regexPockets.getCompound(i); if (pocketMap.containsKey(condition)) continue;
String regex = pocket.getString("regex"); try {
if (pocketList.containsKey(regex)) continue; equationMap.put(condition, Equation.parse(condition));
pocketList.put(pocket.getString("regex"), VirtualPocket.deserialize(pocket.get("pocket"))); pocketMap.put(condition, VirtualPocket.deserialize(pocket.get("pocket")));
} catch (Equation.EquationParseException e) {
LOGGER.error("Could not parse pocket condition equation!", e);
}
} }
return this; return this;
} }
@ -66,16 +68,14 @@ public class DepthDependentSelector extends VirtualSingularPocket {
public CompoundTag toTag(CompoundTag tag) { public CompoundTag toTag(CompoundTag tag) {
super.toTag(tag); super.toTag(tag);
tag.putString("id", this.name); ListTag conditionalPockets = new ListTag();
pocketMap.forEach((condition, pocket) -> {
ListTag regexPockets = new ListTag();
pocketList.forEach((regex, pocket) -> {
CompoundTag compound = new CompoundTag(); CompoundTag compound = new CompoundTag();
compound.putString("regex", regex); compound.putString("condition", condition);
compound.put("pocket", VirtualPocket.serialize(pocket)); compound.put("pocket", VirtualPocket.serialize(pocket));
regexPockets.add(compound); conditionalPockets.add(compound);
}); });
tag.put("pockets", regexPockets); tag.put("pockets", conditionalPockets);
return tag; return tag;
} }
@ -110,11 +110,11 @@ public class DepthDependentSelector extends VirtualSingularPocket {
} }
private VirtualPocket getNextPocket(PocketGenerationParameters parameters) { private VirtualPocket getNextPocket(PocketGenerationParameters parameters) {
for (Map.Entry<String, VirtualPocket> entry : pocketList.entrySet()) { for (Map.Entry<String, VirtualPocket> entry : pocketMap.entrySet()) {
if (Pattern.compile(entry.getKey()).matcher(String.valueOf(parameters.getSourceVirtualLocation().getDepth())).matches()) { if (equationMap.get(entry.getKey()).asBoolean(parameters.toVariableMap(new HashMap<>()))) {
return entry.getValue(); return entry.getValue();
} }
} }
return pocketList.values().stream().findFirst().get(); // TODO: orElse() with some NONE VirtualPocket return pocketMap.values().stream().findFirst().get(); // TODO: orElse() with some NONE VirtualPocket
} }
} }

View file

@ -7,13 +7,27 @@ import java.util.*;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public interface Equation { public interface Equation {
double FALSE = 0d;
double TRUE = 1d;
double apply(Map<String, Double> variableMap); double apply(Map<String, Double> variableMap);
default boolean asBoolean(Map<String, Double> variableMap) {
return toBoolean(apply(variableMap));
}
static Equation parse(String equationString) throws EquationParseException { static Equation parse(String equationString) throws EquationParseException {
return StringEquationParser.INSTANCE.parse(equationString); return StringEquationParser.INSTANCE.parse(equationString);
} }
static double toDouble(boolean value) {
return value ? TRUE : FALSE;
}
static boolean toBoolean(double value) {
return value != FALSE;
}
class StringEquationParser { class StringEquationParser {
private static final Logger LOGGER = LogManager.getLogger(); private static final Logger LOGGER = LogManager.getLogger();
public static StringEquationParser INSTANCE = new StringEquationParser(); public static StringEquationParser INSTANCE = new StringEquationParser();
@ -36,6 +50,26 @@ public interface Equation {
} }
}); });
// some logic first
// ||
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> or = new HashMap<>();
or.put("||", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) || second.asBoolean(stringDoubleMap)));
parseRules.add(new SplitterParser(or));
// &&
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> and = new HashMap<>();
and.put("&&", (stringDoubleMap, first, second) -> toDouble(first.asBoolean(stringDoubleMap) || second.asBoolean(stringDoubleMap)));
parseRules.add(new SplitterParser(and));
// ==, <=, >=, <, >
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> comparators = new HashMap<>();
comparators.put("==", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) == second.apply(stringDoubleMap)));
comparators.put("<=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) <= second.apply(stringDoubleMap)));
comparators.put(">=", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) >= second.apply(stringDoubleMap)));
comparators.put("<", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) < second.apply(stringDoubleMap)));
comparators.put(">", (stringDoubleMap, first, second) -> toDouble(first.apply(stringDoubleMap) > second.apply(stringDoubleMap)));
parseRules.add(new SplitterParser(comparators));
// +, - // +, -
Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>(); Map<String, TriFunction<Map<String, Double>, Equation, Equation, Double>> sumOperations = new HashMap<>();
sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap)); sumOperations.put("+", (stringDoubleMap, first, second) -> first.apply(stringDoubleMap) + second.apply(stringDoubleMap));