started porting all the things from https://github.com/Alwinfy/ArithmeticDemo
This commit is contained in:
parent
3c73a7da98
commit
7e4ca87a91
14 changed files with 533 additions and 0 deletions
|
@ -0,0 +1,25 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexDir;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
|
||||||
|
public interface Arithmetic {
|
||||||
|
public String arithName();
|
||||||
|
|
||||||
|
public abstract Iterable<HexPattern> opTypes();
|
||||||
|
|
||||||
|
public abstract Operator getOperator(HexPattern pattern);
|
||||||
|
|
||||||
|
public static HexPattern ADD = HexPattern.fromAngles("waaw", HexDir.NORTH_EAST);
|
||||||
|
public static HexPattern SUB = HexPattern.fromAngles("wddw", HexDir.NORTH_WEST);
|
||||||
|
public static HexPattern MUL = HexPattern.fromAngles("waqaw", HexDir.SOUTH_EAST);
|
||||||
|
public static HexPattern DIV = HexPattern.fromAngles("wdedw", HexDir.NORTH_EAST);
|
||||||
|
public static HexPattern ABS = HexPattern.fromAngles("wqaqw", HexDir.NORTH_EAST);
|
||||||
|
public static HexPattern POW = HexPattern.fromAngles("wedew", HexDir.NORTH_WEST);
|
||||||
|
public static HexPattern FLOOR = HexPattern.fromAngles("ewq", HexDir.EAST);
|
||||||
|
public static HexPattern CEIL = HexPattern.fromAngles("qwe", HexDir.EAST);
|
||||||
|
public static HexPattern MOD = HexPattern.fromAngles("addwaad", HexDir.NORTH_EAST);
|
||||||
|
public static HexPattern PACK = HexPattern.fromAngles("eqqqqq", HexDir.EAST);
|
||||||
|
public static HexPattern UNPACK = HexPattern.fromAngles("qeeeee", HexDir.EAST);
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IotaMultiPredicate {
|
||||||
|
boolean test(Iterable<Iota> iotas);
|
||||||
|
|
||||||
|
static IotaMultiPredicate all(IotaPredicate child) {
|
||||||
|
return new All(child);
|
||||||
|
}
|
||||||
|
static IotaMultiPredicate bofa(IotaPredicate first, IotaPredicate second) {
|
||||||
|
return new Any(first, second);
|
||||||
|
}
|
||||||
|
static IotaMultiPredicate any(IotaPredicate needs, IotaPredicate fallback) {
|
||||||
|
return new Any(needs, fallback);
|
||||||
|
}
|
||||||
|
record Bofa(IotaPredicate first, IotaPredicate second) implements IotaMultiPredicate {
|
||||||
|
@Override
|
||||||
|
public boolean test(Iterable<Iota> iotas) {
|
||||||
|
var it = iotas.iterator();
|
||||||
|
return it.hasNext() && first.test(it.next()) && it.hasNext() && second.test(it.next()) && !it.hasNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
record Any(IotaPredicate needs, IotaPredicate fallback) implements IotaMultiPredicate {
|
||||||
|
@Override
|
||||||
|
public boolean test(Iterable<Iota> iotas) {
|
||||||
|
var ok = false;
|
||||||
|
for (var iota : iotas) {
|
||||||
|
if (needs.test(iota)) {
|
||||||
|
ok = true;
|
||||||
|
} else if (!fallback.test(iota)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
record All(IotaPredicate inner) implements IotaMultiPredicate {
|
||||||
|
@Override
|
||||||
|
public boolean test(Iterable<Iota> iotas) {
|
||||||
|
for (var iota : iotas) {
|
||||||
|
if (!inner.test(iota)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface IotaPredicate {
|
||||||
|
boolean test(Iota iota);
|
||||||
|
|
||||||
|
static IotaPredicate or(IotaPredicate left, IotaPredicate right) {
|
||||||
|
return new Or(left, right);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IotaPredicate ofType(IotaType<?> type) {
|
||||||
|
return new OfType(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
record Or(IotaPredicate left, IotaPredicate right) implements IotaPredicate {
|
||||||
|
@Override
|
||||||
|
public boolean test(Iota iota) {
|
||||||
|
return left.test(iota) || right.test(iota);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record OfType(IotaType<?> type) implements IotaPredicate {
|
||||||
|
@Override
|
||||||
|
public boolean test(Iota iota) {
|
||||||
|
return iota.getType().equals(this.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic;
|
||||||
|
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
public record IterPair<T>(T left, T right) implements Iterable<T> {
|
||||||
|
@Override
|
||||||
|
public Iterator<T> iterator() {
|
||||||
|
return new Iterator<T>() {
|
||||||
|
int ix;
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return ix < 2;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public T next() {
|
||||||
|
switch (ix++) {
|
||||||
|
case 0: return left;
|
||||||
|
case 1: return right;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.engine;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class ArithmeticEngine {
|
||||||
|
private record OpCandidates(HexPattern pattern, int arity, List<Operator> operators) {
|
||||||
|
public void addOp(Operator next) {
|
||||||
|
if (next.arity != arity) {
|
||||||
|
throw new IllegalArgumentException("Operators exist of differing arity!");
|
||||||
|
}
|
||||||
|
operators.add(next);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Arithmetic[] arithmetics;
|
||||||
|
private final Map<HexPattern, OpCandidates> operators = new HashMap<>();
|
||||||
|
private final Map<HashCons, Operator> cache = new HashMap<>();
|
||||||
|
|
||||||
|
public ArithmeticEngine(Arithmetic... arithmetics) {
|
||||||
|
this.arithmetics = arithmetics;
|
||||||
|
for (var arith : arithmetics) {
|
||||||
|
for (var op : arith.opTypes()) {
|
||||||
|
operators.compute(op, ($, info) -> {
|
||||||
|
var operator = arith.getOperator(op);
|
||||||
|
if (info == null) {
|
||||||
|
info = new OpCandidates(op, operator.arity, new ArrayList<>());
|
||||||
|
}
|
||||||
|
info.addOp(operator);
|
||||||
|
return info;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterable<HexPattern> operatorSyms() {
|
||||||
|
return operators.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public @Nullable Iota run(HexPattern operator, Stack<Iota> iotas) {
|
||||||
|
var candidates = operators.get(operator);
|
||||||
|
if (candidates == null)
|
||||||
|
return null; // not an operator
|
||||||
|
HashCons hash = new HashCons.Pattern(operator);
|
||||||
|
var args = new ArrayList<Iota>(candidates.arity());
|
||||||
|
for (var i = 0; i < candidates.arity(); i++) {
|
||||||
|
if (iotas.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Not enough args on stack for operator: " + operator);
|
||||||
|
}
|
||||||
|
var iota = iotas.pop();
|
||||||
|
hash = new HashCons.Pair(iota.getType(), hash);
|
||||||
|
args.add(iota);
|
||||||
|
}
|
||||||
|
Collections.reverse(args);
|
||||||
|
var op = resolveCandidates(args, hash, candidates);
|
||||||
|
return op.apply(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Operator resolveCandidates(List<Iota> args, HashCons hash, OpCandidates candidates) {
|
||||||
|
return cache.computeIfAbsent(hash, $ -> {
|
||||||
|
for (var op : candidates.operators()) {
|
||||||
|
if (op.accepts.test(args)) {
|
||||||
|
return op;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No implementation candidates for op " + candidates.pattern() + " on args: " + args);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.engine;
|
||||||
|
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
|
||||||
|
// Helper type for hashing lists of types.
|
||||||
|
public sealed interface HashCons {
|
||||||
|
public record Pattern(HexPattern operator) implements HashCons {}
|
||||||
|
|
||||||
|
public record Pair(IotaType<?> head, HashCons tail) implements HashCons {}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.impls;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorBinary;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorUnary;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.DoubleBinaryOperator;
|
||||||
|
import java.util.function.DoubleUnaryOperator;
|
||||||
|
|
||||||
|
import static at.petrak.hexcasting.api.casting.arithmetic.operator.Operator.downcast;
|
||||||
|
import static at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*;
|
||||||
|
|
||||||
|
public enum DoubleArithmetic implements Arithmetic {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public static final List<HexPattern> OPS = List.of(
|
||||||
|
ADD,
|
||||||
|
SUB,
|
||||||
|
MUL,
|
||||||
|
DIV,
|
||||||
|
ABS,
|
||||||
|
POW,
|
||||||
|
FLOOR,
|
||||||
|
CEIL,
|
||||||
|
MOD
|
||||||
|
);
|
||||||
|
|
||||||
|
public static final IotaMultiPredicate ACCEPTS = IotaMultiPredicate.all(IotaPredicate.ofType(DOUBLE));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String arithName() {
|
||||||
|
return "double_math";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<HexPattern> opTypes() {
|
||||||
|
return OPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operator getOperator(HexPattern pattern) {
|
||||||
|
switch (pattern) {
|
||||||
|
case ADD: return make2(Double::sum);
|
||||||
|
case SUB: return make2((p, q) -> p - q);
|
||||||
|
case MUL: return make2((p, q) -> p * q);
|
||||||
|
case DIV: return make2((p, q) -> p / q);
|
||||||
|
case ABS: return make1(Math::abs);
|
||||||
|
case POW: return make2(Math::pow);
|
||||||
|
case FLOOR: return make1(Math::floor);
|
||||||
|
case CEIL: return make1(Math::ceil);
|
||||||
|
case MOD: return make2((p, q) -> p % q);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static OperatorUnary make1(DoubleUnaryOperator op) {
|
||||||
|
return new OperatorUnary(ACCEPTS, i -> new DoubleIota(op.applyAsDouble(downcast(i, DOUBLE).getDouble())));
|
||||||
|
}
|
||||||
|
public static OperatorBinary make2(DoubleBinaryOperator op) {
|
||||||
|
return new OperatorBinary(ACCEPTS, (i, j) -> new DoubleIota(op.applyAsDouble(downcast(i, DOUBLE).getDouble(), downcast(j, DOUBLE).getDouble())));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.impls;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.Operator;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.operator.OperatorBinary;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public enum StringArithmetic implements Arithmetic {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public static final List<HexPattern> OPS = List.of(
|
||||||
|
new ADD,
|
||||||
|
new MUL,
|
||||||
|
new ABS
|
||||||
|
);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String arithName() {
|
||||||
|
return "string_math";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<HexPattern> opTypes() {
|
||||||
|
return OPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operator getOperator(HexPattern pattern) {
|
||||||
|
switch (pattern) {
|
||||||
|
case ADD: return new OperatorBinary(
|
||||||
|
IotaMultiPredicate.all(IotaPredicate.ofType(HexIotaTypes.BOOLEAN)),
|
||||||
|
(p, q) -> new Iota(p.downcast(String.class) + q.downcast(String.class)));
|
||||||
|
case MUL: return new OperatorBinary(
|
||||||
|
IotaMultiPredicate.bofa(IotaPredicate.ofClass(String.class), IotaPredicate.ofClass(Double.class)),
|
||||||
|
(p, q) -> new Iota(new String(new char[q.downcast(Double.class).intValue()]).replace("\0", p.downcast(String.class))));
|
||||||
|
case ABS: return new OperatorUnary(
|
||||||
|
IotaMultiPredicate.all(IotaPredicate.ofClass(String.class)),
|
||||||
|
s -> new Iota((double) s.downcast(String.class).length()));
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.impls;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.Arithmetic;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static at.petrak.hexcasting.common.lib.hex.HexIotaTypes.*;
|
||||||
|
|
||||||
|
public enum Vec3Arithmetic implements Arithmetic {
|
||||||
|
INSTANCE;
|
||||||
|
|
||||||
|
public static final List<HexPattern> OPS;
|
||||||
|
static {
|
||||||
|
var ops = new ArrayList<>(DoubleArithmetic.OPS);
|
||||||
|
ops.add(PACK);
|
||||||
|
ops.add(UNPACK);
|
||||||
|
ops.remove(FLOOR);
|
||||||
|
ops.remove(CEIL);
|
||||||
|
OPS = ops;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final IotaMultiPredicate ACCEPTS = IotaMultiPredicate.any(IotaPredicate.ofType(VEC3), IotaPredicate.ofType(DOUBLE));
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String arithName() {
|
||||||
|
return "vec3_math";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iterable<Symbol> opTypes() {
|
||||||
|
return OPS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Operator getOperator(Symbol name) {
|
||||||
|
switch (name.inner()) {
|
||||||
|
case "pack": return OperatorPack.INSTANCE;
|
||||||
|
case "add": return make2(name, null);
|
||||||
|
case "sub": return make2(name, null);
|
||||||
|
case "mul": return make2(name, Vec3::dot);
|
||||||
|
case "div": return make2(name, Vec3::cross);
|
||||||
|
case "abs": return make1(Vec3::len);
|
||||||
|
case "pow": return make2(name, Vec3::proj);
|
||||||
|
case "mod": return make2(name, null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
public static OperatorUnary make1(Function<Vec3, Object> op) {
|
||||||
|
return new OperatorUnary(ACCEPTS, i -> new Iota(op.apply(i.downcast(Vec3.class))));
|
||||||
|
}
|
||||||
|
public static OperatorVec3Delegating make2(Symbol name, BiFunction<Vec3, Vec3, Object> op) {
|
||||||
|
return new OperatorVec3Delegating(op, name);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.IotaType;
|
||||||
|
import at.petrak.hexcasting.api.casting.mishaps.MishapInvalidIota;
|
||||||
|
|
||||||
|
public abstract class Operator {
|
||||||
|
public final int arity;
|
||||||
|
|
||||||
|
public final IotaMultiPredicate accepts;
|
||||||
|
|
||||||
|
public Operator(int arity, IotaMultiPredicate accepts) {
|
||||||
|
this.arity = arity;
|
||||||
|
this.accepts = accepts;
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Iota apply(Iterable<Iota> iotas);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static <T extends Iota> T downcast(Iota iota, IotaType<T> iotaType) {
|
||||||
|
if (iota.getType() != iotaType)
|
||||||
|
throw new IllegalStateException("Attempting to downcast " + iota + " to type: " + iotaType);
|
||||||
|
return (T) iota;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||||
|
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
|
||||||
|
import java.util.function.BinaryOperator;
|
||||||
|
|
||||||
|
public class OperatorBinary extends Operator {
|
||||||
|
public BinaryOperator<Iota> inner;
|
||||||
|
|
||||||
|
public OperatorBinary(IotaMultiPredicate accepts, BinaryOperator<Iota> inner) {
|
||||||
|
super(2, accepts);
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iota apply(Iterable<Iota> iotas) {
|
||||||
|
var it = iotas.iterator();
|
||||||
|
return inner.apply(it.next(), it.next());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||||
|
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
|
||||||
|
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class OperatorPack extends Operator {
|
||||||
|
private OperatorPack() {
|
||||||
|
super(3, IotaMultiPredicate.all(IotaPredicate.ofType(HexIotaTypes.DOUBLE)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static OperatorPack INSTANCE = new OperatorPack();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iota apply(Iterable<Iota> iotas) {
|
||||||
|
var it = iotas.iterator();
|
||||||
|
return new Vec3Iota(new Vec3(
|
||||||
|
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),
|
||||||
|
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble(),
|
||||||
|
downcast(it.next(), HexIotaTypes.DOUBLE).getDouble()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||||
|
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
|
||||||
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
public class OperatorUnary extends Operator {
|
||||||
|
public UnaryOperator<Iota> inner;
|
||||||
|
|
||||||
|
public OperatorUnary(IotaMultiPredicate accepts, UnaryOperator<Iota> inner) {
|
||||||
|
super(1, accepts);
|
||||||
|
this.inner = inner;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iota apply(Iterable<Iota> iotas) {
|
||||||
|
return inner.apply(iotas.iterator().next());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
package at.petrak.hexcasting.api.casting.arithmetic.operator;
|
||||||
|
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaMultiPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IotaPredicate;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.IterPair;
|
||||||
|
import at.petrak.hexcasting.api.casting.arithmetic.impls.DoubleArithmetic;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.DoubleIota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.iota.Vec3Iota;
|
||||||
|
import at.petrak.hexcasting.api.casting.math.HexPattern;
|
||||||
|
import at.petrak.hexcasting.common.lib.hex.HexIotaTypes;
|
||||||
|
import kotlin.Pair;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
|
public class OperatorVec3Delegating extends Operator {
|
||||||
|
private final BiFunction<Vec3, Vec3, Iota> op;
|
||||||
|
private final Operator fb;
|
||||||
|
public OperatorVec3Delegating(BiFunction<Vec3, Vec3, Iota> core, HexPattern fallback) {
|
||||||
|
super(2, IotaMultiPredicate.any(IotaPredicate.ofType(HexIotaTypes.VEC3), IotaPredicate.ofType(HexIotaTypes.DOUBLE)));
|
||||||
|
op = core;
|
||||||
|
fb = Objects.requireNonNull(DoubleArithmetic.INSTANCE.getOperator(fallback));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Iota apply(Iterable<Iota> iotas) {
|
||||||
|
var it = iotas.iterator();
|
||||||
|
var left = it.next();
|
||||||
|
var right = it.next();
|
||||||
|
if (op != null && left instanceof Vec3Iota lh && right instanceof Vec3Iota rh) {
|
||||||
|
return op.apply(lh.getVec3(), rh.getVec3());
|
||||||
|
}
|
||||||
|
var lh = left instanceof Vec3Iota l ? l.getVec3() : triplicate(downcast(left, HexIotaTypes.DOUBLE).getDouble());
|
||||||
|
var rh = right instanceof Vec3Iota r ? r.getVec3() : triplicate(downcast(right, HexIotaTypes.DOUBLE).getDouble());
|
||||||
|
return new Vec3Iota(new Vec3(
|
||||||
|
downcast(fb.apply(new IterPair<>(new DoubleIota(lh.x()), new DoubleIota(rh.x()))), HexIotaTypes.DOUBLE).getDouble(),
|
||||||
|
downcast(fb.apply(new IterPair<>(new DoubleIota(lh.y()), new DoubleIota(rh.y()))), HexIotaTypes.DOUBLE).getDouble(),
|
||||||
|
downcast(fb.apply(new IterPair<>(new DoubleIota(lh.z()), new DoubleIota(rh.z()))), HexIotaTypes.DOUBLE).getDouble()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Vec3 triplicate(double in) {
|
||||||
|
return new Vec3(in, in, in);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue