9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-21 07:49:18 +00:00

remove dfc

This commit is contained in:
NONPLAYT
2025-03-13 22:36:44 +03:00
parent 127828d16a
commit e7a219d49c
64 changed files with 5 additions and 4866 deletions

View File

@@ -181,7 +181,6 @@ public class DivineConfig {
public static boolean enableSecureSeed = false;
public static boolean smoothBedrockLayer = false;
public static boolean slopesVisualFix = false;
public static boolean enableDensityFunctionCompiler = false;
public static boolean enableStructureLayoutOptimizer = true;
public static boolean deduplicateShuffledTemplatePoolElementList = false;
private static void chunkGeneration() {
@@ -230,19 +229,6 @@ public class DivineConfig {
slopesVisualFix = getBoolean("settings.chunk-generation.slopes-visual-fix", slopesVisualFix,
"Fixes MC-258859, fixing slopes visual bug in biomes like Snowy Slopes, Frozen Peaks, Jagged Peaks, and including Terralith.");
enableDensityFunctionCompiler = getBoolean("settings.chunk-generation.experimental.enable-density-function-compiler", enableDensityFunctionCompiler,
"Whether to use density function compiler to accelerate world generation",
"",
"Density function: https://minecraft.wiki/w/Density_function",
"",
"This functionality compiles density functions from world generation",
"datapacks (including vanilla generation) to JVM bytecode to increase",
"performance by allowing JVM JIT to better optimize the code.",
"All functions provided by vanilla are implemented.",
"",
"Please test if this optimization actually benefits your server, as",
"it can sometimes slow down chunk performance than speed it up.");
enableStructureLayoutOptimizer = getBoolean("settings.chunk-generation.experimental.enable-structure-layout-optimizer", enableStructureLayoutOptimizer,
"Enables a port of the mod StructureLayoutOptimizer, which optimizes general Jigsaw structure generation");
deduplicateShuffledTemplatePoolElementList = getBoolean("settings.chunk-generation.experimental.deduplicate-shuffled-template-pool-element-list", deduplicateShuffledTemplatePoolElementList,

View File

@@ -1,13 +0,0 @@
package org.bxteam.divinemc.dfc.common;
import net.minecraft.world.level.levelgen.NoiseRouterData;
public interface IDensityFunctionsCaveScaler {
static double invokeScaleCaves(double value) {
return NoiseRouterData.QuantizedSpaghettiRarity.getSphaghettiRarity2D(value);
}
static double invokeScaleTunnels(double value) {
return NoiseRouterData.QuantizedSpaghettiRarity.getSpaghettiRarity3D(value);
}
}

View File

@@ -1,22 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.commons.InstructionAdapter;
public interface AstNode {
double evalSingle(int var1, int var2, int var3, EvalType var4);
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
AstNode[] getChildren();
AstNode transform(AstTransformer var1);
void doBytecodeGenSingle(BytecodeGen.Context var1, InstructionAdapter var2, BytecodeGen.Context.LocalVarConsumer var3);
void doBytecodeGenMulti(BytecodeGen.Context var1, InstructionAdapter var2, BytecodeGen.Context.LocalVarConsumer var3);
boolean relaxedEquals(AstNode var1);
int relaxedHashCode();
}

View File

@@ -1,5 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast;
public interface AstTransformer {
AstNode transform(AstNode var1);
}

View File

@@ -1,25 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast;
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.NoiseChunk;
public enum EvalType {
NORMAL,
INTERPOLATION;
private EvalType() {
}
public static EvalType from(DensityFunction.FunctionContext pos) {
return pos instanceof NoiseChunk ? INTERPOLATION : NORMAL;
}
public static EvalType from(DensityFunction.ContextProvider applier) {
if (applier instanceof EachApplierVanillaInterface vif) {
return vif.getType();
} else {
return applier instanceof NoiseChunk ? INTERPOLATION : NORMAL;
}
}
}

View File

@@ -1,106 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast;
import org.bxteam.divinemc.dfc.common.ast.binary.AddNode;
import org.bxteam.divinemc.dfc.common.ast.binary.MaxNode;
import org.bxteam.divinemc.dfc.common.ast.binary.MaxShortNode;
import org.bxteam.divinemc.dfc.common.ast.binary.MinNode;
import org.bxteam.divinemc.dfc.common.ast.binary.MinShortNode;
import org.bxteam.divinemc.dfc.common.ast.binary.MulNode;
import org.bxteam.divinemc.dfc.common.ast.misc.CacheLikeNode;
import org.bxteam.divinemc.dfc.common.ast.misc.ConstantNode;
import org.bxteam.divinemc.dfc.common.ast.misc.DelegateNode;
import org.bxteam.divinemc.dfc.common.ast.misc.RangeChoiceNode;
import org.bxteam.divinemc.dfc.common.ast.misc.YClampedGradientNode;
import org.bxteam.divinemc.dfc.common.ast.noise.DFTNoiseNode;
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftANode;
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftBNode;
import org.bxteam.divinemc.dfc.common.ast.noise.DFTShiftNode;
import org.bxteam.divinemc.dfc.common.ast.noise.DFTWeirdScaledSamplerNode;
import org.bxteam.divinemc.dfc.common.ast.noise.ShiftedNoiseNode;
import org.bxteam.divinemc.dfc.common.ast.spline.SplineAstNode;
import org.bxteam.divinemc.dfc.common.ast.unary.AbsNode;
import org.bxteam.divinemc.dfc.common.ast.unary.CubeNode;
import org.bxteam.divinemc.dfc.common.ast.unary.NegMulNode;
import org.bxteam.divinemc.dfc.common.ast.unary.SquareNode;
import org.bxteam.divinemc.dfc.common.ast.unary.SqueezeNode;
import org.bxteam.divinemc.dfc.common.ducks.IEqualityOverriding;
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
import org.bxteam.divinemc.dfc.common.vif.AstVanillaInterface;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import net.minecraft.world.level.levelgen.NoiseChunk;
import org.jetbrains.annotations.NotNull;
public class McToAst {
public McToAst() {
}
public static AstNode toAst(DensityFunction df) {
Objects.requireNonNull(df);
return switch (df) {
case AstVanillaInterface f -> f.getAstNode();
case NoiseChunk.BlendAlpha f -> new ConstantNode(1.0);
case NoiseChunk.BlendOffset f -> new ConstantNode(0.0);
case DensityFunctions.BlendAlpha f -> new ConstantNode(1.0);
case DensityFunctions.BlendOffset f -> new ConstantNode(0.0);
case DensityFunctions.TwoArgumentSimpleFunction f -> switch (f.type()) {
case ADD -> new AddNode(toAst(f.argument1()), toAst(f.argument2()));
case MUL -> new MulNode(toAst(f.argument1()), toAst(f.argument2()));
case MIN -> {
double rightMin = f.argument2().minValue();
if (f.argument1().minValue() < rightMin) {
yield new MinShortNode(toAst(f.argument1()), toAst(f.argument2()), rightMin);
} else {
yield new MinNode(toAst(f.argument1()), toAst(f.argument2()));
}
}
case MAX -> {
double rightMax = f.argument2().maxValue();
if (f.argument1().maxValue() > rightMax) {
yield new MaxShortNode(toAst(f.argument1()), toAst(f.argument2()), rightMax);
} else {
yield new MaxNode(toAst(f.argument1()), toAst(f.argument2()));
}
}
};
case DensityFunctions.BlendDensity f -> toAst(f.input());
case DensityFunctions.Clamp f -> new MaxNode(new ConstantNode(f.minValue()), new MinNode(new ConstantNode(f.maxValue()), toAst(f.input())));
case DensityFunctions.Constant f -> new ConstantNode(f.value());
case DensityFunctions.HolderHolder f -> toAst(f.function().value());
case DensityFunctions.Mapped f -> switch (f.type()) {
case ABS -> new AbsNode(toAst(f.input()));
case SQUARE -> new SquareNode(toAst(f.input()));
case CUBE -> new CubeNode(toAst(f.input()));
case HALF_NEGATIVE -> new NegMulNode(toAst(f.input()), 0.5);
case QUARTER_NEGATIVE -> new NegMulNode(toAst(f.input()), 0.25);
case SQUEEZE -> new SqueezeNode(toAst(f.input()));
};
case DensityFunctions.RangeChoice f -> new RangeChoiceNode(toAst(f.input()), f.minInclusive(), f.maxExclusive(), toAst(f.whenInRange()), toAst(f.whenOutOfRange()));
case DensityFunctions.Marker f -> {
DensityFunctions.Marker wrapping = new DensityFunctions.Marker(f.type(), new AstVanillaInterface(toAst(f.wrapped()), null));
((IEqualityOverriding) (Object) wrapping).c2me$overrideEquality(wrapping);
yield new DelegateNode(wrapping);
}
case IFastCacheLike f -> new CacheLikeNode(f, toAst(f.c2me$getDelegate()));
case DensityFunctions.ShiftedNoise f -> new ShiftedNoiseNode(toAst(f.shiftX()), toAst(f.shiftY()), toAst(f.shiftZ()), f.xzScale(), f.yScale(), f.noise());
case DensityFunctions.Noise f -> new DFTNoiseNode(f.noise(), f.xzScale(), f.yScale());
case DensityFunctions.Shift f -> new DFTShiftNode(f.offsetNoise());
case DensityFunctions.ShiftA f -> new DFTShiftANode(f.offsetNoise());
case DensityFunctions.ShiftB f -> new DFTShiftBNode(f.offsetNoise());
case DensityFunctions.YClampedGradient f -> new YClampedGradientNode(f.fromY(), f.toY(), f.fromValue(), f.toValue());
case DensityFunctions.WeirdScaledSampler f -> new DFTWeirdScaledSamplerNode(toAst(f.input()), f.noise(), f.rarityValueMapper());
case DensityFunctions.Spline f -> new SplineAstNode(f.spline());
default -> {
// delegateStatistics.computeIfAbsent(df.getClass(), unused -> new LongAdder()).increment();;
yield new DelegateNode(df);
}
};
}
public static @NotNull DensityFunction wrapVanilla(DensityFunction densityFunction) {
return new AstVanillaInterface(toAst(densityFunction), densityFunction);
}
}

View File

@@ -1,106 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import java.util.Objects;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public abstract class AbstractBinaryNode implements AstNode {
protected final AstNode left;
protected final AstNode right;
public AbstractBinaryNode(AstNode left, AstNode right) {
this.left = (AstNode)Objects.requireNonNull(left);
this.right = (AstNode)Objects.requireNonNull(right);
}
public AstNode[] getChildren() {
return new AstNode[]{this.left, this.right};
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
AbstractBinaryNode that = (AbstractBinaryNode)o;
return Objects.equals(this.left, that.left) && Objects.equals(this.right, that.right);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.left.hashCode();
result = 31 * result + this.right.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
AbstractBinaryNode that = (AbstractBinaryNode)o;
return this.left.relaxedEquals(that.left) && this.right.relaxedEquals(that.right);
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.left.relaxedHashCode();
result = 31 * result + this.right.relaxedHashCode();
return result;
}
protected abstract AstNode newInstance(AstNode var1, AstNode var2);
public AstNode transform(AstTransformer transformer) {
AstNode left = this.left.transform(transformer);
AstNode right = this.right.transform(transformer);
return left == this.left && right == this.right ? transformer.transform(this) : transformer.transform(this.newInstance(left, right));
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newSingleMethod(this.left);
String rightMethod = context.newSingleMethod(this.right);
context.callDelegateSingle(m, leftMethod);
context.callDelegateSingle(m, rightMethod);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newMultiMethod(this.left);
String rightMethod = context.newMultiMethod(this.right);
int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class));
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.arraylength();
m.iconst(0);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
m.store(res1, InstructionAdapter.OBJECT_TYPE);
context.callDelegateMulti(m, leftMethod);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, rightMethod, Context.MULTI_DESC, false);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
this.bytecodeGenMultiBody(m, idx, res1);
});
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
m.areturn(Type.VOID_TYPE);
}
protected abstract void bytecodeGenMultiBody(InstructionAdapter var1, int var2, int var3);
}

View File

@@ -1,50 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class AddNode extends AbstractBinaryNode {
public AddNode(AstNode left, AstNode right) {
super(left, right);
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new AddNode(left, right);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.left.evalSingle(x, y, z, type) + this.right.evalSingle(x, y, z, type);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
double[] res1 = new double[res.length];
this.left.evalMulti(res, x, y, z, type);
this.right.evalMulti(res1, x, y, z, type);
for(int i = 0; i < res1.length; ++i) {
res[i] += res1[i];
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.add(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.add(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
}
}

View File

@@ -1,50 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class MaxNode extends AbstractBinaryNode {
public MaxNode(AstNode left, AstNode right) {
super(left, right);
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new MaxNode(left, right);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return Math.max(this.left.evalSingle(x, y, z, type), this.right.evalSingle(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
double[] res1 = new double[res.length];
this.left.evalMulti(res, x, y, z, type);
this.right.evalMulti(res1, x, y, z, type);
for(int i = 0; i < res1.length; ++i) {
res[i] = Math.max(res[i], res1[i]);
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.areturn(Type.DOUBLE_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.astore(Type.DOUBLE_TYPE);
}
}

View File

@@ -1,92 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class MaxShortNode extends AbstractBinaryNode {
private final double rightMax;
public MaxShortNode(AstNode left, AstNode right, double rightMax) {
super(left, right);
this.rightMax = rightMax;
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new MaxShortNode(left, right, this.rightMax);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double evaled = this.left.evalSingle(x, y, z, type);
return evaled >= this.rightMax ? evaled : Math.max(evaled, this.right.evalSingle(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.left.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = res[i] >= this.rightMax ? res[i] : Math.max(res[i], this.right.evalSingle(x[i], y[i], z[i], type));
}
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newSingleMethod(this.left);
String rightMethod = context.newSingleMethod(this.right);
Label minLabel = new Label();
context.callDelegateSingle(m, leftMethod);
m.dup2();
m.dconst(this.rightMax);
m.cmpl(Type.DOUBLE_TYPE);
m.iflt(minLabel);
m.areturn(Type.DOUBLE_TYPE);
m.visitLabel(minLabel);
context.callDelegateSingle(m, rightMethod);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newMultiMethod(this.left);
String rightMethodSingle = context.newSingleMethod(this.right);
context.callDelegateMulti(m, leftMethod);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
Label minLabel = new Label();
Label end = new Label();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.dup2();
m.dconst(this.rightMax);
m.cmpl(Type.DOUBLE_TYPE);
m.iflt(minLabel);
m.goTo(end);
m.visitLabel(minLabel);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.visitLabel(end);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,50 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class MinNode extends AbstractBinaryNode {
public MinNode(AstNode left, AstNode right) {
super(left, right);
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new MinNode(left, right);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return Math.min(this.left.evalSingle(x, y, z, type), this.right.evalSingle(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
double[] res1 = new double[res.length];
this.left.evalMulti(res, x, y, z, type);
this.right.evalMulti(res1, x, y, z, type);
for(int i = 0; i < res1.length; ++i) {
res[i] = Math.min(res[i], res1[i]);
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.areturn(Type.DOUBLE_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.astore(Type.DOUBLE_TYPE);
}
}

View File

@@ -1,92 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class MinShortNode extends AbstractBinaryNode {
private final double rightMin;
public MinShortNode(AstNode left, AstNode right, double rightMin) {
super(left, right);
this.rightMin = rightMin;
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new MinShortNode(left, right, this.rightMin);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double evaled = this.left.evalSingle(x, y, z, type);
return evaled <= this.rightMin ? evaled : Math.min(evaled, this.right.evalSingle(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.left.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = res[i] <= this.rightMin ? res[i] : Math.min(res[i], this.right.evalSingle(x[i], y[i], z[i], type));
}
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newSingleMethod(this.left);
String rightMethod = context.newSingleMethod(this.right);
Label minLabel = new Label();
context.callDelegateSingle(m, leftMethod);
m.dup2();
m.dconst(this.rightMin);
m.cmpg(Type.DOUBLE_TYPE);
m.ifgt(minLabel);
m.areturn(Type.DOUBLE_TYPE);
m.visitLabel(minLabel);
context.callDelegateSingle(m, rightMethod);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newMultiMethod(this.left);
String rightMethodSingle = context.newSingleMethod(this.right);
context.callDelegateMulti(m, leftMethod);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
Label minLabel = new Label();
Label end = new Label();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.dup2();
m.dconst(this.rightMin);
m.cmpg(Type.DOUBLE_TYPE);
m.ifgt(minLabel);
m.goTo(end);
m.visitLabel(minLabel);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.visitLabel(end);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,92 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.binary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class MulNode extends AbstractBinaryNode {
public MulNode(AstNode left, AstNode right) {
super(left, right);
}
protected AstNode newInstance(AstNode left, AstNode right) {
return new MulNode(left, right);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double evaled = this.left.evalSingle(x, y, z, type);
return evaled == 0.0 ? 0.0 : evaled * this.right.evalSingle(x, y, z, type);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.left.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = res[i] == 0.0 ? 0.0 : res[i] * this.right.evalSingle(x[i], y[i], z[i], type);
}
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newSingleMethod(this.left);
String rightMethod = context.newSingleMethod(this.right);
Label notZero = new Label();
context.callDelegateSingle(m, leftMethod);
m.dup2();
m.dconst(0.0);
m.cmpl(Type.DOUBLE_TYPE);
m.ifne(notZero);
m.dconst(0.0);
m.areturn(Type.DOUBLE_TYPE);
m.visitLabel(notZero);
context.callDelegateSingle(m, rightMethod);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String leftMethod = context.newMultiMethod(this.left);
String rightMethodSingle = context.newSingleMethod(this.right);
context.callDelegateMulti(m, leftMethod);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
Label minLabel = new Label();
Label end = new Label();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.dup2();
m.dconst(0.0);
m.cmpl(Type.DOUBLE_TYPE);
m.ifne(minLabel);
m.pop2();
m.dconst(0.0);
m.goTo(end);
m.visitLabel(minLabel);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, rightMethodSingle, Context.SINGLE_DESC, false);
m.mul(Type.DOUBLE_TYPE);
m.visitLabel(end);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
protected void bytecodeGenMultiBody(InstructionAdapter m, int idx, int res1) {
throw new UnsupportedOperationException();
}
}

View File

@@ -1,23 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.dfvisitor;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import net.minecraft.world.level.levelgen.NoiseChunk;
import org.jetbrains.annotations.NotNull;
public class StripBlending implements DensityFunction.Visitor {
public static final StripBlending INSTANCE = new StripBlending();
private StripBlending() {
}
public @NotNull DensityFunction apply(@NotNull DensityFunction densityFunction) {
return switch (densityFunction) {
case NoiseChunk.BlendAlpha _ -> DensityFunctions.constant(1.0);
case NoiseChunk.BlendOffset _ -> DensityFunctions.constant(0.0);
case DensityFunctions.BlendAlpha _ -> DensityFunctions.constant(1.0);
case DensityFunctions.BlendOffset _ -> DensityFunctions.constant(0.0);
default -> densityFunction;
};
}
}

View File

@@ -1,256 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.bxteam.divinemc.dfc.common.gen.IMultiMethod;
import org.bxteam.divinemc.dfc.common.gen.ISingleMethod;
import org.bxteam.divinemc.dfc.common.gen.SubCompiledDensityFunction;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class CacheLikeNode implements AstNode {
private final IFastCacheLike cacheLike;
private final AstNode delegate;
public CacheLikeNode(IFastCacheLike cacheLike, AstNode delegate) {
this.cacheLike = cacheLike;
this.delegate = (AstNode)Objects.requireNonNull(delegate);
}
public double evalSingle(int x, int y, int z, EvalType type) {
if (this.cacheLike == null) {
return this.delegate.evalSingle(x, y, z, type);
} else {
double cached = this.cacheLike.c2me$getCached(x, y, z, type);
if (Double.doubleToRawLongBits(cached) != 9222769054270909007L) {
return cached;
} else {
double eval = this.delegate.evalSingle(x, y, z, type);
this.cacheLike.c2me$cache(x, y, z, type, eval);
return eval;
}
}
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
if (this.cacheLike == null) {
this.delegate.evalMulti(res, x, y, z, type);
} else {
boolean cached = this.cacheLike.c2me$getCached(res, x, y, z, type);
if (!cached) {
this.delegate.evalMulti(res, x, y, z, type);
this.cacheLike.c2me$cache(res, x, y, z, type);
}
}
}
public AstNode[] getChildren() {
return new AstNode[]{this.delegate};
}
public AstNode transform(AstTransformer transformer) {
AstNode delegate = this.delegate.transform(transformer);
return this.delegate == delegate ? transformer.transform(this) : transformer.transform(new CacheLikeNode(this.cacheLike, delegate));
}
public void doBytecodeGenSingle(@NotNull Context context, @NotNull InstructionAdapter m, Context.@NotNull LocalVarConsumer localVarConsumer) {
String delegateMethod = context.newSingleMethod(this.delegate);
String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike);
this.genPostprocessingMethod(context, cacheLikeField);
int eval = localVarConsumer.createLocalVariable("eval", Type.DOUBLE_TYPE.getDescriptor());
Label cacheExists = new Label();
Label cacheMiss = new Label();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.ifnonnull(cacheExists);
context.callDelegateSingle(m, delegateMethod);
m.areturn(Type.DOUBLE_TYPE);
m.visitLabel(cacheExists);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.load(1, Type.INT_TYPE);
m.load(2, Type.INT_TYPE);
m.load(3, Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$getCached", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)}));
m.dup2();
m.invokestatic(Type.getInternalName(Double.class), "doubleToRawLongBits", Type.getMethodDescriptor(Type.LONG_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
m.lconst(9222769054270909007L);
m.lcmp();
m.ifeq(cacheMiss);
m.areturn(Type.DOUBLE_TYPE);
m.visitLabel(cacheMiss);
m.pop2();
context.callDelegateSingle(m, delegateMethod);
m.store(eval, Type.DOUBLE_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.load(1, Type.INT_TYPE);
m.load(2, Type.INT_TYPE);
m.load(3, Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(eval, Type.DOUBLE_TYPE);
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$cache", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class), Type.DOUBLE_TYPE}));
m.load(eval, Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(@NotNull Context context, @NotNull InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String delegateMethod = context.newMultiMethod(this.delegate);
String cacheLikeField = context.newField(IFastCacheLike.class, this.cacheLike);
this.genPostprocessingMethod(context, cacheLikeField);
Label cacheExists = new Label();
Label cacheMiss = new Label();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.ifnonnull(cacheExists);
context.callDelegateMulti(m, delegateMethod);
m.areturn(Type.VOID_TYPE);
m.visitLabel(cacheExists);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$getCached", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class)}));
m.ifeq(cacheMiss);
m.areturn(Type.VOID_TYPE);
m.visitLabel(cacheMiss);
context.callDelegateMulti(m, delegateMethod);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$cache", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class)}));
m.areturn(Type.VOID_TYPE);
}
private void genPostprocessingMethod(@NotNull Context context, String cacheLikeField) {
String methodName = String.format("postProcessing_%s", cacheLikeField);
String delegateSingle = context.newSingleMethod(this.delegate);
String delegateMulti = context.newMultiMethod(this.delegate);
context.genPostprocessingMethod(methodName, (m) -> {
Label cacheExists = new Label();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.dup();
m.ifnonnull(cacheExists);
m.pop();
m.pop();
m.areturn(Type.VOID_TYPE);
m.visitLabel(cacheExists);
m.anew(Type.getType(SubCompiledDensityFunction.class));
m.dup();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.invokedynamic("evalSingle", Type.getMethodDescriptor(Type.getType(ISingleMethod.class), new Type[]{Type.getType(context.classDesc)}), new Handle(6, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", false), new Object[]{Type.getMethodType(Context.SINGLE_DESC), new Handle(5, context.className, delegateSingle, Context.SINGLE_DESC, false), Type.getMethodType(Context.SINGLE_DESC)});
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.invokedynamic("evalMulti", Type.getMethodDescriptor(Type.getType(IMultiMethod.class), new Type[]{Type.getType(context.classDesc)}), new Handle(6, "java/lang/invoke/LambdaMetafactory", "metafactory", "(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;", false), new Object[]{Type.getMethodType(Context.MULTI_DESC), new Handle(5, context.className, delegateMulti, Context.MULTI_DESC, false), Type.getMethodType(Context.MULTI_DESC)});
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.checkcast(Type.getType(DensityFunction.class));
m.invokespecial(Type.getInternalName(SubCompiledDensityFunction.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(ISingleMethod.class), Type.getType(IMultiMethod.class), Type.getType(DensityFunction.class)}), false);
m.checkcast(Type.getType(DensityFunction.class));
m.invokeinterface(Type.getInternalName(IFastCacheLike.class), "c2me$withDelegate", Type.getMethodDescriptor(Type.getType(DensityFunction.class), new Type[]{Type.getType(DensityFunction.class)}));
m.putfield(context.className, cacheLikeField, Type.getDescriptor(IFastCacheLike.class));
m.areturn(Type.VOID_TYPE);
});
}
public IFastCacheLike getCacheLike() {
return this.cacheLike;
}
public AstNode getDelegate() {
return this.delegate;
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
CacheLikeNode that = (CacheLikeNode)o;
return equals(this.cacheLike, that.cacheLike) && Objects.equals(this.delegate, that.delegate);
} else {
return false;
}
}
private static boolean equals(IFastCacheLike a, IFastCacheLike b) {
if (a instanceof DensityFunctions.Marker wrappingA) {
if (b instanceof DensityFunctions.Marker wrappingB) {
return wrappingA.type() == wrappingB.type();
}
}
return a.equals(b);
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + hashCode(this.cacheLike);
result = 31 * result + this.delegate.hashCode();
return result;
}
private static int hashCode(IFastCacheLike o) {
if (o instanceof DensityFunctions.Marker wrapping) {
return wrapping.type().hashCode();
} else {
return o.hashCode();
}
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
CacheLikeNode that = (CacheLikeNode)o;
return relaxedEquals(this.cacheLike, that.cacheLike) && this.delegate.relaxedEquals(that.delegate);
} else {
return false;
}
}
private static boolean relaxedEquals(IFastCacheLike a, IFastCacheLike b) {
if (a instanceof DensityFunctions.Marker wrappingA) {
if (b instanceof DensityFunctions.Marker wrappingB) {
return wrappingA.type() == wrappingB.type();
}
}
return a.getClass() == b.getClass();
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + relaxedHashCode(this.cacheLike);
result = 31 * result + this.delegate.relaxedHashCode();
return result;
}
private static int relaxedHashCode(IFastCacheLike o) {
if (o instanceof DensityFunctions.Marker wrapping) {
return wrapping.type().hashCode();
} else {
return o.getClass().hashCode();
}
}
}

View File

@@ -1,72 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Arrays;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class ConstantNode implements AstNode {
private final double value;
public ConstantNode(double value) {
this.value = value;
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.value;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
Arrays.fill(res, this.value);
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
m.dconst(this.value);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.dconst(this.value);
m.invokestatic(Type.getInternalName(Arrays.class), "fill", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.DOUBLE_TYPE}), false);
m.areturn(Type.VOID_TYPE);
}
public double getValue() {
return this.value;
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
ConstantNode that = (ConstantNode)o;
return Double.compare(this.value, that.value) == 0;
} else {
return false;
}
}
public int hashCode() {
return Double.hashCode(this.value);
}
public boolean relaxedEquals(AstNode o) {
return this.equals(o);
}
public int relaxedHashCode() {
return this.hashCode();
}
}

View File

@@ -1,140 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
import org.bxteam.divinemc.dfc.common.vif.NoisePosVanillaInterface;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DelegateNode implements AstNode {
private final DensityFunction densityFunction;
public DelegateNode(DensityFunction densityFunction) {
this.densityFunction = Objects.requireNonNull(densityFunction);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.densityFunction.compute(new NoisePosVanillaInterface(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
if (res.length == 1) {
res[0] = this.evalSingle(x[0], y[0], z[0], type);
} else {
this.densityFunction.fillArray(res, new EachApplierVanillaInterface(x, y, z, type));
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String newField = context.newField(DensityFunction.class, this.densityFunction);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
m.anew(Type.getType(NoisePosVanillaInterface.class));
m.dup();
m.load(1, Type.INT_TYPE);
m.load(2, Type.INT_TYPE);
m.load(3, Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(Type.getInternalName(NoisePosVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)), false);
m.invokeinterface(Type.getInternalName(DensityFunction.class), "compute", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.getType(DensityFunction.FunctionContext.class)));
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String newField = context.newField(DensityFunction.class, this.densityFunction);
Label moreThanTwoLabel = new Label();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.arraylength();
m.iconst(1);
m.ificmpgt(moreThanTwoLabel);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.iconst(0);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
m.anew(Type.getType(NoisePosVanillaInterface.class));
m.dup();
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.iconst(0);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.iconst(0);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.iconst(0);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(Type.getInternalName(NoisePosVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.getType(EvalType.class)), false);
m.invokeinterface(Type.getInternalName(DensityFunction.class), "compute", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.getType(DensityFunction.FunctionContext.class)));
m.astore(Type.DOUBLE_TYPE);
m.areturn(Type.VOID_TYPE);
m.visitLabel(moreThanTwoLabel);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, newField, Type.getDescriptor(DensityFunction.class));
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.anew(Type.getType(EachApplierVanillaInterface.class));
m.dup();
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(Type.getInternalName(EachApplierVanillaInterface.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class), Type.getType(ArrayCache.class)), false);
m.invokeinterface(Type.getInternalName(DensityFunction.class), "fillArray", Type.getMethodDescriptor(Type.VOID_TYPE, Type.getType(double[].class), Type.getType(DensityFunction.ContextProvider.class)));
m.areturn(Type.VOID_TYPE);
}
public DensityFunction getDelegate() {
return this.densityFunction;
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DelegateNode that = (DelegateNode)o;
return Objects.equals(this.densityFunction, that.densityFunction);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + Objects.hashCode(this.getClass());
result = 31 * result + Objects.hashCode(this.densityFunction);
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DelegateNode that = (DelegateNode)o;
return this.densityFunction.getClass() == that.densityFunction.getClass();
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + Objects.hashCode(this.getClass());
result = 31 * result + Objects.hashCode(this.densityFunction.getClass());
return result;
}
}

View File

@@ -1,337 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import java.util.Objects;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class RangeChoiceNode implements AstNode {
private final AstNode input;
private final double minInclusive;
private final double maxExclusive;
private final AstNode whenInRange;
private final AstNode whenOutOfRange;
public RangeChoiceNode(AstNode input, double minInclusive, double maxExclusive, AstNode whenInRange, AstNode whenOutOfRange) {
this.input = (AstNode)Objects.requireNonNull(input);
this.minInclusive = minInclusive;
this.maxExclusive = maxExclusive;
this.whenInRange = (AstNode)Objects.requireNonNull(whenInRange);
this.whenOutOfRange = (AstNode)Objects.requireNonNull(whenOutOfRange);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = this.input.evalSingle(x, y, z, type);
return v >= this.minInclusive && v < this.maxExclusive ? this.whenInRange.evalSingle(x, y, z, type) : this.whenOutOfRange.evalSingle(x, y, z, type);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.input.evalMulti(res, x, y, z, type);
int numInRange = 0;
int numOutOfRange;
for(numOutOfRange = 0; numOutOfRange < x.length; ++numOutOfRange) {
double v = res[numOutOfRange];
if (v >= this.minInclusive && v < this.maxExclusive) {
++numInRange;
}
}
numOutOfRange = res.length - numInRange;
if (numInRange == 0) {
this.evalChildMulti(this.whenOutOfRange, res, x, y, z, type);
} else if (numInRange == res.length) {
this.evalChildMulti(this.whenInRange, res, x, y, z, type);
} else {
int idx1 = 0;
int[] i1 = new int[numInRange];
double[] res1 = new double[numInRange];
int[] x1 = new int[numInRange];
int[] y1 = new int[numInRange];
int[] z1 = new int[numInRange];
int idx2 = 0;
int[] i2 = new int[numOutOfRange];
double[] res2 = new double[numOutOfRange];
int[] x2 = new int[numOutOfRange];
int[] y2 = new int[numOutOfRange];
int[] z2 = new int[numOutOfRange];
int i;
for(i = 0; i < res.length; ++i) {
double v = res[i];
int index;
if (v >= this.minInclusive && v < this.maxExclusive) {
index = idx1++;
i1[index] = i;
x1[index] = x[i];
y1[index] = y[i];
z1[index] = z[i];
} else {
index = idx2++;
i2[index] = i;
x2[index] = x[i];
y2[index] = y[i];
z2[index] = z[i];
}
}
this.evalChildMulti(this.whenInRange, res1, x1, y1, z1, type);
this.evalChildMulti(this.whenOutOfRange, res2, x2, y2, z2, type);
for(i = 0; i < numInRange; ++i) {
res[i1[i]] = res1[i];
}
for(i = 0; i < numOutOfRange; ++i) {
res[i2[i]] = res2[i];
}
}
}
public static void evalMultiStatic(double[] res, int[] x, int[] y, int[] z, EvalType type, double minInclusive, double maxExclusive, BytecodeGen.EvalSingleInterface whenInRangeSingle, BytecodeGen.EvalSingleInterface whenOutOfRangeSingle, BytecodeGen.EvalMultiInterface inputMulti, BytecodeGen.EvalMultiInterface whenInRangeMulti, BytecodeGen.EvalMultiInterface whenOutOfRangeMulti) {
inputMulti.evalMulti(res, x, y, z, type);
int numInRange = 0;
int numOutOfRange;
for(numOutOfRange = 0; numOutOfRange < x.length; ++numOutOfRange) {
double v = res[numOutOfRange];
if (v >= minInclusive && v < maxExclusive) {
++numInRange;
}
}
numOutOfRange = res.length - numInRange;
if (numInRange == 0) {
evalChildMulti(whenOutOfRangeSingle, whenOutOfRangeMulti, res, x, y, z, type);
} else if (numInRange == res.length) {
evalChildMulti(whenInRangeSingle, whenInRangeMulti, res, x, y, z, type);
} else {
int idx1 = 0;
int[] i1 = new int[numInRange];
double[] res1 = new double[numInRange];
int[] x1 = new int[numInRange];
int[] y1 = new int[numInRange];
int[] z1 = new int[numInRange];
int idx2 = 0;
int[] i2 = new int[numOutOfRange];
double[] res2 = new double[numOutOfRange];
int[] x2 = new int[numOutOfRange];
int[] y2 = new int[numOutOfRange];
int[] z2 = new int[numOutOfRange];
int i;
for(i = 0; i < res.length; ++i) {
double v = res[i];
int index;
if (v >= minInclusive && v < maxExclusive) {
index = idx1++;
i1[index] = i;
x1[index] = x[i];
y1[index] = y[i];
z1[index] = z[i];
} else {
index = idx2++;
i2[index] = i;
x2[index] = x[i];
y2[index] = y[i];
z2[index] = z[i];
}
}
evalChildMulti(whenInRangeSingle, whenInRangeMulti, res1, x1, y1, z1, type);
evalChildMulti(whenOutOfRangeSingle, whenOutOfRangeMulti, res2, x2, y2, z2, type);
for(i = 0; i < numInRange; ++i) {
res[i1[i]] = res1[i];
}
for(i = 0; i < numOutOfRange; ++i) {
res[i2[i]] = res2[i];
}
}
}
private static void evalChildMulti(BytecodeGen.EvalSingleInterface single, BytecodeGen.EvalMultiInterface multi, double[] res, int[] x, int[] y, int[] z, EvalType type) {
if (res.length == 1) {
res[0] = single.evalSingle(x[0], y[0], z[0], type);
} else {
multi.evalMulti(res, x, y, z, type);
}
}
private void evalChildMulti(AstNode child, double[] res, int[] x, int[] y, int[] z, EvalType type) {
if (res.length == 1) {
res[0] = child.evalSingle(x[0], y[0], z[0], type);
} else {
child.evalMulti(res, x, y, z, type);
}
}
public AstNode[] getChildren() {
return new AstNode[]{this.input, this.whenInRange, this.whenOutOfRange};
}
public AstNode transform(AstTransformer transformer) {
AstNode input = this.input.transform(transformer);
AstNode whenInRange = this.whenInRange.transform(transformer);
AstNode whenOutOfRange = this.whenOutOfRange.transform(transformer);
return this.input == input && this.whenInRange == whenInRange && this.whenOutOfRange == whenOutOfRange ? transformer.transform(this) : transformer.transform(new RangeChoiceNode(input, this.minInclusive, this.maxExclusive, whenInRange, whenOutOfRange));
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String inputMethod = context.newSingleMethod(this.input);
String whenInRangeMethod = context.newSingleMethod(this.whenInRange);
String whenOutOfRangeMethod = context.newSingleMethod(this.whenOutOfRange);
int inputValue = localVarConsumer.createLocalVariable("inputValue", Type.DOUBLE_TYPE.getDescriptor());
context.callDelegateSingle(m, inputMethod);
m.store(inputValue, Type.DOUBLE_TYPE);
Label whenOutOfRangeLabel = new Label();
Label end = new Label();
m.load(inputValue, Type.DOUBLE_TYPE);
m.dconst(this.minInclusive);
m.cmpl(Type.DOUBLE_TYPE);
m.iflt(whenOutOfRangeLabel);
m.load(inputValue, Type.DOUBLE_TYPE);
m.dconst(this.maxExclusive);
m.cmpg(Type.DOUBLE_TYPE);
m.ifge(whenOutOfRangeLabel);
if (whenInRangeMethod.equals(inputMethod)) {
m.load(inputValue, Type.DOUBLE_TYPE);
} else {
context.callDelegateSingle(m, whenInRangeMethod);
}
m.goTo(end);
m.visitLabel(whenOutOfRangeLabel);
if (whenOutOfRangeMethod.equals(inputMethod)) {
m.load(inputValue, Type.DOUBLE_TYPE);
} else {
context.callDelegateSingle(m, whenOutOfRangeMethod);
}
m.visitLabel(end);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String inputSingle = context.newSingleMethod(this.input);
String whenInRangeSingle = context.newSingleMethod(this.whenInRange);
String whenOutOfRangeSingle = context.newSingleMethod(this.whenOutOfRange);
String inputMulti = context.newMultiMethod(this.input);
context.callDelegateMulti(m, inputMulti);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
Label whenOutOfRangeLabel = new Label();
Label end = new Label();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.dconst(this.minInclusive);
m.cmpl(Type.DOUBLE_TYPE);
m.iflt(whenOutOfRangeLabel);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.dconst(this.maxExclusive);
m.cmpg(Type.DOUBLE_TYPE);
m.ifge(whenOutOfRangeLabel);
if (whenInRangeSingle.equals(inputSingle)) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
} else {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, whenInRangeSingle, Context.SINGLE_DESC, false);
}
m.goTo(end);
m.visitLabel(whenOutOfRangeLabel);
if (whenOutOfRangeSingle.equals(inputSingle)) {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
} else {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, whenOutOfRangeSingle, Context.SINGLE_DESC, false);
}
m.visitLabel(end);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
RangeChoiceNode that = (RangeChoiceNode)o;
return Double.compare(this.minInclusive, that.minInclusive) == 0 && Double.compare(this.maxExclusive, that.maxExclusive) == 0 && Objects.equals(this.input, that.input) && Objects.equals(this.whenInRange, that.whenInRange) && Objects.equals(this.whenOutOfRange, that.whenOutOfRange);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.input.hashCode();
result = 31 * result + Double.hashCode(this.minInclusive);
result = 31 * result + Double.hashCode(this.maxExclusive);
result = 31 * result + this.whenInRange.hashCode();
result = 31 * result + this.whenOutOfRange.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
RangeChoiceNode that = (RangeChoiceNode)o;
return Double.compare(this.minInclusive, that.minInclusive) == 0 && Double.compare(this.maxExclusive, that.maxExclusive) == 0 && this.input.relaxedEquals(that.input) && this.whenInRange.relaxedEquals(that.whenInRange) && this.whenOutOfRange.relaxedEquals(that.whenOutOfRange);
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.input.relaxedHashCode();
result = 31 * result + Double.hashCode(this.minInclusive);
result = 31 * result + Double.hashCode(this.maxExclusive);
result = 31 * result + this.whenInRange.relaxedHashCode();
result = 31 * result + this.whenOutOfRange.relaxedHashCode();
return result;
}
}

View File

@@ -1,82 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class RootNode implements AstNode {
private final AstNode next;
public RootNode(AstNode next) {
this.next = (AstNode)Objects.requireNonNull(next);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.next.evalSingle(x, y, z, type);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.next.evalMulti(res, x, y, z, type);
}
public AstNode[] getChildren() {
return new AstNode[]{this.next};
}
public AstNode transform(AstTransformer transformer) {
AstNode next = this.next.transform(transformer);
return next == this.next ? transformer.transform(this) : transformer.transform(new RootNode(next));
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String nextMethod = context.newSingleMethod(this.next);
context.callDelegateSingle(m, nextMethod);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String nextMethod = context.newMultiMethod(this.next);
context.callDelegateMulti(m, nextMethod);
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
RootNode that = (RootNode)o;
return Objects.equals(this.next, that.next);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.next.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
RootNode that = (RootNode)o;
return this.next.relaxedEquals(that.next);
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.next.relaxedHashCode();
return result;
}
}

View File

@@ -1,100 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.misc;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import net.minecraft.util.Mth;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class YClampedGradientNode implements AstNode {
private final double fromY;
private final double toY;
private final double fromValue;
private final double toValue;
public YClampedGradientNode(double fromY, double toY, double fromValue, double toValue) {
this.fromY = fromY;
this.toY = toY;
this.fromValue = fromValue;
this.toValue = toValue;
}
public double evalSingle(int x, int y, int z, EvalType type) {
return Mth.clampedMap((double)y, this.fromY, this.toY, this.fromValue, this.toValue);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = Mth.clampedMap((double)y[i], this.fromY, this.toY, this.fromValue, this.toValue);
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
m.load(2, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.fromY);
m.dconst(this.toY);
m.dconst(this.fromValue);
m.dconst(this.toValue);
m.invokestatic(Type.getInternalName(Mth.class), "clampedMap", "(DDDDD)D", false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.fromY);
m.dconst(this.toY);
m.dconst(this.fromValue);
m.dconst(this.toValue);
m.invokestatic(Type.getInternalName(Mth.class), "clampedMap", "(DDDDD)D", false);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
YClampedGradientNode that = (YClampedGradientNode)o;
return Double.compare(this.fromY, that.fromY) == 0 && Double.compare(this.toY, that.toY) == 0 && Double.compare(this.fromValue, that.fromValue) == 0 && Double.compare(this.toValue, that.toValue) == 0;
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + Double.hashCode(this.fromY);
result = 31 * result + Double.hashCode(this.toY);
result = 31 * result + Double.hashCode(this.fromValue);
result = 31 * result + Double.hashCode(this.toValue);
return result;
}
public boolean relaxedEquals(AstNode o) {
return this.equals(o);
}
public int relaxedHashCode() {
return this.hashCode();
}
}

View File

@@ -1,131 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DFTNoiseNode implements AstNode {
private final DensityFunction.NoiseHolder noise;
private final double xzScale;
private final double yScale;
public DFTNoiseNode(DensityFunction.NoiseHolder noise, double xzScale, double yScale) {
this.noise = (DensityFunction.NoiseHolder)Objects.requireNonNull(noise);
this.xzScale = xzScale;
this.yScale = yScale;
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.noise.getValue((double)x * this.xzScale, (double)y * this.yScale, (double)z * this.xzScale);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = this.noise.getValue((double)x[i] * this.xzScale, (double)y[i] * this.yScale, (double)z[i] * this.xzScale);
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.load(2, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.yScale);
m.mul(Type.DOUBLE_TYPE);
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.yScale);
m.mul(Type.DOUBLE_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTNoiseNode that = (DFTNoiseNode)o;
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && Objects.equals(this.noise, that.noise);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.noise.hashCode();
result = 31 * result + Double.hashCode(this.xzScale);
result = 31 * result + Double.hashCode(this.yScale);
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTNoiseNode that = (DFTNoiseNode)o;
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0;
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + Double.hashCode(this.xzScale);
result = 31 * result + Double.hashCode(this.yScale);
return result;
}
}

View File

@@ -1,115 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DFTShiftANode implements AstNode {
private final DensityFunction.NoiseHolder offsetNoise;
public DFTShiftANode(DensityFunction.NoiseHolder offsetNoise) {
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.offsetNoise.getValue((double)x * 0.25, 0.0, (double)z * 0.25) * 4.0;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = this.offsetNoise.getValue((double)x[i] * 0.25, 0.0, (double)z[i] * 0.25) * 4.0;
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.dconst(0.0);
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.dconst(0.0);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTShiftANode that = (DFTShiftANode)o;
return Objects.equals(this.offsetNoise, that.offsetNoise);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
Object o = this.getClass();
result = 31 * result + o.hashCode();
result = 31 * result + this.offsetNoise.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else {
return o != null && this.getClass() == o.getClass();
}
}
public int relaxedHashCode() {
return this.getClass().hashCode();
}
}

View File

@@ -1,115 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DFTShiftBNode implements AstNode {
private final DensityFunction.NoiseHolder offsetNoise;
public DFTShiftBNode(DensityFunction.NoiseHolder offsetNoise) {
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.offsetNoise.getValue((double)z * 0.25, (double)x * 0.25, 0.0) * 4.0;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = this.offsetNoise.getValue((double)z[i] * 0.25, (double)x[i] * 0.25, 0.0) * 4.0;
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.dconst(0.0);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.dconst(0.0);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTShiftBNode that = (DFTShiftBNode)o;
return Objects.equals(this.offsetNoise, that.offsetNoise);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
Object o = this.getClass();
result = 31 * result + o.hashCode();
result = 31 * result + this.offsetNoise.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else {
return o != null && this.getClass() == o.getClass();
}
}
public int relaxedHashCode() {
return this.getClass().hashCode();
}
}

View File

@@ -1,123 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DFTShiftNode implements AstNode {
private final DensityFunction.NoiseHolder offsetNoise;
public DFTShiftNode(DensityFunction.NoiseHolder offsetNoise) {
this.offsetNoise = (DensityFunction.NoiseHolder)Objects.requireNonNull(offsetNoise);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return this.offsetNoise.getValue((double)x * 0.25, (double)y * 0.25, (double)z * 0.25) * 4.0;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = this.offsetNoise.getValue((double)x[i] * 0.25, (double)y[i] * 0.25, (double)z[i] * 0.25) * 4.0;
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(2, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.offsetNoise);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(0.25);
m.mul(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.dconst(4.0);
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTShiftNode that = (DFTShiftNode)o;
return Objects.equals(this.offsetNoise, that.offsetNoise);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
Object o = this.getClass();
result = 31 * result + o.hashCode();
result = 31 * result + this.offsetNoise.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else {
return o != null && this.getClass() == o.getClass();
}
}
public int relaxedHashCode() {
return this.getClass().hashCode();
}
}

View File

@@ -1,169 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.IDensityFunctionsCaveScaler;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import org.jetbrains.annotations.NotNull;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class DFTWeirdScaledSamplerNode implements AstNode {
private final AstNode input;
private final DensityFunction.NoiseHolder noise;
private final DensityFunctions.WeirdScaledSampler.RarityValueMapper mapper;
public DFTWeirdScaledSamplerNode(AstNode input, DensityFunction.NoiseHolder noise, DensityFunctions.WeirdScaledSampler.RarityValueMapper mapper) {
this.input = Objects.requireNonNull(input);
this.noise = Objects.requireNonNull(noise);
this.mapper = Objects.requireNonNull(mapper);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = this.input.evalSingle(x, y, z, type);
double d = (this.mapper.mapper).get(v);
return d * Math.abs(this.noise.getValue((double)x / d, (double)y / d, (double)z / d));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.input.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
double d = (this.mapper.mapper).get(res[i]);
res[i] = d * Math.abs(this.noise.getValue((double)x[i] / d, (double)y[i] / d, (double)z[i] / d));
}
}
public AstNode[] getChildren() {
return new AstNode[]{this.input};
}
public AstNode transform(AstTransformer transformer) {
AstNode input = this.input.transform(transformer);
return input == this.input ? transformer.transform(this) : transformer.transform(new DFTWeirdScaledSamplerNode(input, this.noise, this.mapper));
}
public void doBytecodeGenSingle(BytecodeGen.@NotNull Context context, InstructionAdapter m, BytecodeGen.Context.@NotNull LocalVarConsumer localVarConsumer) {
String inputMethod = context.newSingleMethod(this.input);
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
int scale = localVarConsumer.createLocalVariable("scale", Type.DOUBLE_TYPE.getDescriptor());
context.callDelegateSingle(m, inputMethod);
switch (this.mapper) {
case TYPE1 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleTunnels", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
case TYPE2 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleCaves", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
default -> throw new UnsupportedOperationException(String.format("Unknown mapper %s", this.mapper));
}
m.store(scale, Type.DOUBLE_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.load(2, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.invokestatic(Type.getInternalName(Math.class), "abs", "(D)D", false);
m.load(scale, Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String inputMethod = context.newMultiMethod(this.input);
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
context.callDelegateMulti(m, inputMethod);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
int scale = localVarConsumer.createLocalVariable("scale", Type.DOUBLE_TYPE.getDescriptor());
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
switch (this.mapper) {
case TYPE1 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleTunnels", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
case TYPE2 -> m.invokestatic(Type.getInternalName(IDensityFunctionsCaveScaler.class), "invokeScaleCaves", Type.getMethodDescriptor(Type.DOUBLE_TYPE, Type.DOUBLE_TYPE), true);
default -> throw new UnsupportedOperationException(String.format("Unknown mapper %s", this.mapper));
}
m.store(scale, Type.DOUBLE_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.load(scale, Type.DOUBLE_TYPE);
m.div(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.invokestatic(Type.getInternalName(Math.class), "abs", "(D)D", false);
m.load(scale, Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTWeirdScaledSamplerNode that = (DFTWeirdScaledSamplerNode)o;
return Objects.equals(this.input, that.input) && Objects.equals(this.noise, that.noise) && this.mapper == that.mapper;
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.input.hashCode();
result = 31 * result + this.noise.hashCode();
result = 31 * result + this.mapper.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
DFTWeirdScaledSamplerNode that = (DFTWeirdScaledSamplerNode)o;
return this.input.relaxedEquals(that.input) && this.mapper == that.mapper;
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.input.relaxedHashCode();
result = 31 * result + this.mapper.hashCode();
return result;
}
}

View File

@@ -1,215 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.noise;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen.Context;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class ShiftedNoiseNode implements AstNode {
private final AstNode shiftX;
private final AstNode shiftY;
private final AstNode shiftZ;
private final double xzScale;
private final double yScale;
private final DensityFunction.NoiseHolder noise;
public ShiftedNoiseNode(AstNode shiftX, AstNode shiftY, AstNode shiftZ, double xzScale, double yScale, DensityFunction.NoiseHolder noise) {
this.shiftX = (AstNode)Objects.requireNonNull(shiftX);
this.shiftY = (AstNode)Objects.requireNonNull(shiftY);
this.shiftZ = (AstNode)Objects.requireNonNull(shiftZ);
this.xzScale = xzScale;
this.yScale = yScale;
this.noise = (DensityFunction.NoiseHolder)Objects.requireNonNull(noise);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double d = (double)x * this.xzScale + this.shiftX.evalSingle(x, y, z, type);
double e = (double)y * this.yScale + this.shiftY.evalSingle(x, y, z, type);
double f = (double)z * this.xzScale + this.shiftZ.evalSingle(x, y, z, type);
return this.noise.getValue(d, e, f);
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
double[] res1 = new double[res.length];
double[] res2 = new double[res.length];
this.shiftX.evalMulti(res, x, y, z, type);
this.shiftY.evalMulti(res1, x, y, z, type);
this.shiftZ.evalMulti(res2, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = this.noise.getValue((double)x[i] * this.xzScale + res[i], (double)y[i] * this.yScale + res1[i], (double)z[i] * this.xzScale + res2[i]);
}
}
public AstNode[] getChildren() {
return new AstNode[]{this.shiftX, this.shiftY, this.shiftZ};
}
public AstNode transform(AstTransformer transformer) {
AstNode shiftX = this.shiftX.transform(transformer);
AstNode shiftY = this.shiftY.transform(transformer);
AstNode shiftZ = this.shiftZ.transform(transformer);
return shiftX == this.shiftX && shiftY == this.shiftY && shiftZ == this.shiftZ ? transformer.transform(this) : transformer.transform(new ShiftedNoiseNode(shiftX, shiftY, shiftZ, this.xzScale, this.yScale, this.noise));
}
public void doBytecodeGenSingle(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
String shiftXMethod = context.newSingleMethod(this.shiftX);
String shiftYMethod = context.newSingleMethod(this.shiftY);
String shiftZMethod = context.newSingleMethod(this.shiftZ);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(1, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
context.callDelegateSingle(m, shiftXMethod);
m.add(Type.DOUBLE_TYPE);
m.load(2, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.yScale);
m.mul(Type.DOUBLE_TYPE);
context.callDelegateSingle(m, shiftYMethod);
m.add(Type.DOUBLE_TYPE);
m.load(3, Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
context.callDelegateSingle(m, shiftZMethod);
m.add(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(Context context, InstructionAdapter m, Context.LocalVarConsumer localVarConsumer) {
String noiseField = context.newField(DensityFunction.NoiseHolder.class, this.noise);
String shiftXMethod = context.newMultiMethod(this.shiftX);
String shiftYMethod = context.newMultiMethod(this.shiftY);
String shiftZMethod = context.newMultiMethod(this.shiftZ);
int res1 = localVarConsumer.createLocalVariable("res1", Type.getDescriptor(double[].class));
int res2 = localVarConsumer.createLocalVariable("res2", Type.getDescriptor(double[].class));
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.arraylength();
m.iconst(0);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
m.store(res1, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.arraylength();
m.iconst(0);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "getDoubleArray", Type.getMethodDescriptor(Type.getType(double[].class), new Type[]{Type.INT_TYPE, Type.BOOLEAN_TYPE}), false);
m.store(res2, InstructionAdapter.OBJECT_TYPE);
context.callDelegateMulti(m, shiftXMethod);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, shiftYMethod, Context.MULTI_DESC, false);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(res2, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, shiftZMethod, Context.MULTI_DESC, false);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, noiseField, Type.getDescriptor(DensityFunction.NoiseHolder.class));
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.add(Type.DOUBLE_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.yScale);
m.mul(Type.DOUBLE_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.add(Type.DOUBLE_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.cast(Type.INT_TYPE, Type.DOUBLE_TYPE);
m.dconst(this.xzScale);
m.mul(Type.DOUBLE_TYPE);
m.load(res2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.DOUBLE_TYPE);
m.add(Type.DOUBLE_TYPE);
m.invokevirtual(Type.getInternalName(DensityFunction.NoiseHolder.class), "getValue", "(DDD)D", false);
m.astore(Type.DOUBLE_TYPE);
});
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(res1, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.load(res2, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(Type.getInternalName(ArrayCache.class), "recycle", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class)}), false);
m.areturn(Type.VOID_TYPE);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
ShiftedNoiseNode that = (ShiftedNoiseNode)o;
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && Objects.equals(this.shiftX, that.shiftX) && Objects.equals(this.shiftY, that.shiftY) && Objects.equals(this.shiftZ, that.shiftZ) && Objects.equals(this.noise, that.noise);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.shiftX.hashCode();
result = 31 * result + this.shiftY.hashCode();
result = 31 * result + this.shiftZ.hashCode();
result = 31 * result + Double.hashCode(this.xzScale);
result = 31 * result + Double.hashCode(this.yScale);
result = 31 * result + this.noise.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
ShiftedNoiseNode that = (ShiftedNoiseNode)o;
return Double.compare(this.xzScale, that.xzScale) == 0 && Double.compare(this.yScale, that.yScale) == 0 && this.shiftX.relaxedEquals(that.shiftX) && this.shiftY.relaxedEquals(that.shiftY) && this.shiftZ.relaxedEquals(that.shiftZ);
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.shiftX.relaxedHashCode();
result = 31 * result + this.shiftY.relaxedHashCode();
result = 31 * result + this.shiftZ.relaxedHashCode();
result = 31 * result + Double.hashCode(this.xzScale);
result = 31 * result + Double.hashCode(this.yScale);
return result;
}
}

View File

@@ -1,453 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.spline;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ast.McToAst;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.bxteam.divinemc.dfc.common.vif.NoisePosVanillaInterface;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntObjectPair;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import net.minecraft.util.CubicSpline;
import net.minecraft.util.Mth;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import org.bxteam.divinemc.util.Assertions;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AnalyzerAdapter;
import org.objectweb.asm.commons.InstructionAdapter;
public class SplineAstNode implements AstNode {
public static final String SPLINE_METHOD_DESC;
private final CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline;
public SplineAstNode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
this.spline = spline;
}
public double evalSingle(int x, int y, int z, EvalType type) {
return (double)this.spline.apply(new DensityFunctions.Spline.Point(new NoisePosVanillaInterface(x, y, z, type)));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
for(int i = 0; i < res.length; ++i) {
res[i] = this.evalSingle(x[i], y[i], z[i], type);
}
}
public AstNode[] getChildren() {
return new AstNode[0];
}
public AstNode transform(AstTransformer transformer) {
return transformer.transform(this);
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
ValuesMethodDef splineMethod = doBytecodeGenSpline(context, this.spline);
callSplineSingle(context, m, splineMethod);
m.cast(Type.FLOAT_TYPE, Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
private static ValuesMethodDef doBytecodeGenSpline(BytecodeGen.Context context, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
String name = context.getCachedSplineMethod(spline);
if (name != null) {
return new ValuesMethodDef(false, name, 0.0F);
} else if (spline instanceof CubicSpline.Constant) {
CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline1 = (CubicSpline.Constant)spline;
return new ValuesMethodDef(true, (String)null, spline1.value());
} else {
name = context.nextMethodName("Spline");
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 18, name, SPLINE_METHOD_DESC, context.classWriter.visitMethod(18, name, SPLINE_METHOD_DESC, (String)null, (String[])null)));
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList();
Label start = new Label();
Label end = new Label();
m.visitLabel(start);
BytecodeGen.Context.LocalVarConsumer localVarConsumer = (localName, localDesc) -> {
int ordinal = extraLocals.size() + 5;
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
return ordinal;
};
if (spline instanceof CubicSpline.Multipoint) {
CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> impl = (CubicSpline.Multipoint)spline;
ValuesMethodDef[] valuesMethods = (ValuesMethodDef[])impl.values().stream().map((spline1x) -> {
return doBytecodeGenSpline(context, spline1x);
}).toArray((x$0) -> {
return new ValuesMethodDef[x$0];
});
String locations = context.newField(float[].class, impl.locations());
String derivatives = context.newField(float[].class, impl.derivatives());
int point = localVarConsumer.createLocalVariable("point", Type.FLOAT_TYPE.getDescriptor());
int rangeForLocation = localVarConsumer.createLocalVariable("rangeForLocation", Type.INT_TYPE.getDescriptor());
int lastConst = impl.locations().length - 1;
String locationFunction = context.newSingleMethod(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)impl.coordinate()).function().value()));
context.callDelegateSingle(m, locationFunction);
m.cast(Type.DOUBLE_TYPE, Type.FLOAT_TYPE);
m.store(point, Type.FLOAT_TYPE);
if (valuesMethods.length == 1) {
m.load(point, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
callSplineSingle(context, m, valuesMethods[0]);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
m.iconst(0);
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
m.areturn(Type.FLOAT_TYPE);
} else {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
m.load(point, Type.FLOAT_TYPE);
m.invokestatic(Type.getInternalName(SplineSupport.class), "findRangeForLocation", Type.getMethodDescriptor(Type.INT_TYPE, new Type[]{Type.getType(float[].class), Type.FLOAT_TYPE}), false);
m.store(rangeForLocation, Type.INT_TYPE);
Label label1 = new Label();
Label label2 = new Label();
m.load(rangeForLocation, Type.INT_TYPE);
m.ifge(label1);
m.load(point, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
callSplineSingle(context, m, valuesMethods[0]);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
m.iconst(0);
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
m.areturn(Type.FLOAT_TYPE);
m.visitLabel(label1);
m.load(rangeForLocation, Type.INT_TYPE);
m.iconst(lastConst);
m.ificmpne(label2);
m.load(point, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
callSplineSingle(context, m, valuesMethods[lastConst]);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
m.iconst(lastConst);
m.invokestatic(Type.getInternalName(SplineSupport.class), "sampleOutsideRange", Type.getMethodDescriptor(Type.FLOAT_TYPE, new Type[]{Type.FLOAT_TYPE, Type.getType(float[].class), Type.FLOAT_TYPE, Type.getType(float[].class), Type.INT_TYPE}), false);
m.areturn(Type.FLOAT_TYPE);
m.visitLabel(label2);
int loc0 = localVarConsumer.createLocalVariable("loc0", Type.FLOAT_TYPE.getDescriptor());
int loc1 = localVarConsumer.createLocalVariable("loc1", Type.FLOAT_TYPE.getDescriptor());
int locDist = localVarConsumer.createLocalVariable("locDist", Type.FLOAT_TYPE.getDescriptor());
int k = localVarConsumer.createLocalVariable("k", Type.FLOAT_TYPE.getDescriptor());
int n = localVarConsumer.createLocalVariable("n", Type.FLOAT_TYPE.getDescriptor());
int o = localVarConsumer.createLocalVariable("o", Type.FLOAT_TYPE.getDescriptor());
int onDist = localVarConsumer.createLocalVariable("onDist", Type.FLOAT_TYPE.getDescriptor());
int p = localVarConsumer.createLocalVariable("p", Type.FLOAT_TYPE.getDescriptor());
int q = localVarConsumer.createLocalVariable("q", Type.FLOAT_TYPE.getDescriptor());
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
m.load(rangeForLocation, Type.INT_TYPE);
m.aload(Type.FLOAT_TYPE);
m.store(loc0, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, locations, Type.getDescriptor(float[].class));
m.load(rangeForLocation, Type.INT_TYPE);
m.iconst(1);
m.add(Type.INT_TYPE);
m.aload(Type.FLOAT_TYPE);
m.store(loc1, Type.FLOAT_TYPE);
m.load(loc1, Type.FLOAT_TYPE);
m.load(loc0, Type.FLOAT_TYPE);
m.sub(Type.FLOAT_TYPE);
m.store(locDist, Type.FLOAT_TYPE);
m.load(point, Type.FLOAT_TYPE);
m.load(loc0, Type.FLOAT_TYPE);
m.sub(Type.FLOAT_TYPE);
m.load(locDist, Type.FLOAT_TYPE);
m.div(Type.FLOAT_TYPE);
m.store(k, Type.FLOAT_TYPE);
Label[] jumpLabels = new Label[valuesMethods.length - 1];
boolean[] jumpGenerated = new boolean[valuesMethods.length - 1];
for(int i = 0; i < valuesMethods.length - 1; ++i) {
jumpLabels[i] = new Label();
}
Label defaultLabel = new Label();
Label label3 = new Label();
m.load(rangeForLocation, Type.INT_TYPE);
m.tableswitch(0, valuesMethods.length - 2, defaultLabel, jumpLabels);
for(int i = 0; i < valuesMethods.length - 1; ++i) {
if (!jumpGenerated[i]) {
m.visitLabel(jumpLabels[i]);
jumpGenerated[i] = true;
for(int j = i + 1; j < valuesMethods.length - 1; ++j) {
if (valuesMethods[i].equals(valuesMethods[j]) && valuesMethods[i + 1].equals(valuesMethods[j + 1])) {
m.visitLabel(jumpLabels[j]);
jumpGenerated[j] = true;
}
}
callSplineSingle(context, m, valuesMethods[i]);
if (valuesMethods[i].equals(valuesMethods[i + 1])) {
m.dup();
m.store(n, Type.FLOAT_TYPE);
m.store(o, Type.FLOAT_TYPE);
} else {
m.store(n, Type.FLOAT_TYPE);
callSplineSingle(context, m, valuesMethods[i + 1]);
m.store(o, Type.FLOAT_TYPE);
}
m.goTo(label3);
}
}
m.visitLabel(defaultLabel);
m.iconst(0);
m.aconst("boom");
m.invokestatic(Type.getInternalName(Assertions.class), "assertTrue", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.BOOLEAN_TYPE, Type.getType(String.class)}), false);
m.fconst(Float.NaN);
m.areturn(Type.FLOAT_TYPE);
m.visitLabel(label3);
m.load(o, Type.FLOAT_TYPE);
m.load(n, Type.FLOAT_TYPE);
m.sub(Type.FLOAT_TYPE);
m.store(onDist, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
m.load(rangeForLocation, Type.INT_TYPE);
m.aload(Type.FLOAT_TYPE);
m.load(locDist, Type.FLOAT_TYPE);
m.mul(Type.FLOAT_TYPE);
m.load(onDist, Type.FLOAT_TYPE);
m.sub(Type.FLOAT_TYPE);
m.store(p, Type.FLOAT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, derivatives, Type.getDescriptor(float[].class));
m.load(rangeForLocation, Type.INT_TYPE);
m.iconst(1);
m.add(Type.INT_TYPE);
m.aload(Type.FLOAT_TYPE);
m.neg(Type.FLOAT_TYPE);
m.load(locDist, Type.FLOAT_TYPE);
m.mul(Type.FLOAT_TYPE);
m.load(onDist, Type.FLOAT_TYPE);
m.add(Type.FLOAT_TYPE);
m.store(q, Type.FLOAT_TYPE);
m.load(k, Type.FLOAT_TYPE);
m.load(n, Type.FLOAT_TYPE);
m.load(o, Type.FLOAT_TYPE);
m.invokestatic(Type.getInternalName(Mth.class), "lerp", "(FFF)F", false);
m.load(k, Type.FLOAT_TYPE);
m.fconst(1.0F);
m.load(k, Type.FLOAT_TYPE);
m.sub(Type.FLOAT_TYPE);
m.mul(Type.FLOAT_TYPE);
m.load(k, Type.FLOAT_TYPE);
m.load(p, Type.FLOAT_TYPE);
m.load(q, Type.FLOAT_TYPE);
m.invokestatic(Type.getInternalName(Mth.class), "lerp", "(FFF)F", false);
m.mul(Type.FLOAT_TYPE);
m.add(Type.FLOAT_TYPE);
m.areturn(Type.FLOAT_TYPE);
}
} else {
if (!(spline instanceof CubicSpline.Constant)) {
throw new UnsupportedOperationException(String.format("Unsupported spline implementation: %s", spline.getClass().getName()));
}
CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> floatFunction = (CubicSpline.Constant)spline;
m.fconst(floatFunction.value());
m.areturn(Type.FLOAT_TYPE);
}
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
m.visitLocalVariable("x", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 1);
m.visitLocalVariable("y", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 2);
m.visitLocalVariable("z", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 3);
m.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 4);
Iterator var35 = extraLocals.iterator();
while(var35.hasNext()) {
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var35.next();
m.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
}
m.visitMaxs(0, 0);
context.cacheSplineMethod(spline, name);
return new ValuesMethodDef(false, name, 0.0F);
}
}
private static void callSplineSingle(BytecodeGen.Context context, InstructionAdapter m, ValuesMethodDef target) {
if (target.isConst()) {
m.fconst(target.constValue());
} else {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(1, Type.INT_TYPE);
m.load(2, Type.INT_TYPE);
m.load(3, Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, target.generatedMethod(), SPLINE_METHOD_DESC, false);
}
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
context.delegateToSingle(m, localVarConsumer, this);
m.areturn(Type.VOID_TYPE);
}
private static boolean deepEquals(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b) {
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
if (b instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
return a1.value() == b1.value();
}
}
if (a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
if (b instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
boolean equals1 = Arrays.equals(a1.derivatives(), b1.derivatives()) && Arrays.equals(a1.locations(), b1.locations()) && a1.values().size() == b1.values().size() && McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).equals(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)b1.coordinate()).function().value()));
if (!equals1) {
return false;
}
int size = a1.values().size();
for(int i = 0; i < size; ++i) {
if (!deepEquals((CubicSpline)a1.values().get(i), (CubicSpline)b1.values().get(i))) {
return false;
}
}
return true;
}
}
return false;
}
private static boolean deepRelaxedEquals(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a, CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b) {
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
if (b instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
return a1.value() == b1.value();
}
}
if (a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
if (b instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> b1) {
boolean equals1 = a1.values().size() == b1.values().size() && McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).relaxedEquals(McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)b1.coordinate()).function().value()));
if (!equals1) {
return false;
}
int size = a1.values().size();
for(int i = 0; i < size; ++i) {
if (!deepRelaxedEquals((CubicSpline)a1.values().get(i), (CubicSpline)b1.values().get(i))) {
return false;
}
}
return true;
}
}
return false;
}
private static int deepHashcode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a) {
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
return Float.hashCode(a1.value());
} else if (!(a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1)) {
return a.hashCode();
} else {
int result = 1;
result = 31 * result + Arrays.hashCode(a1.derivatives());
result = 31 * result + Arrays.hashCode(a1.locations());
CubicSpline spline;
for(Iterator var4 = a1.values().iterator(); var4.hasNext(); result = 31 * result + deepHashcode(spline)) {
spline = (CubicSpline)var4.next();
}
result = 31 * result + McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).hashCode();
return result;
}
}
private static int deepRelaxedHashcode(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a) {
if (a instanceof CubicSpline.Constant<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1) {
return Float.hashCode(a1.value());
} else if (!(a instanceof CubicSpline.Multipoint<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> a1)) {
return a.hashCode();
} else {
int result = 1;
CubicSpline spline;
for(Iterator var4 = a1.values().iterator(); var4.hasNext(); result = 31 * result + deepRelaxedHashcode(spline)) {
spline = (CubicSpline)var4.next();
}
result = 31 * result + McToAst.toAst((DensityFunction)((DensityFunctions.Spline.Coordinate)a1.coordinate()).function().value()).relaxedHashCode();
return result;
}
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
SplineAstNode that = (SplineAstNode)o;
return deepEquals(this.spline, that.spline);
} else {
return false;
}
}
public int hashCode() {
return deepHashcode(this.spline);
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
SplineAstNode that = (SplineAstNode)o;
return deepRelaxedEquals(this.spline, that.spline);
} else {
return false;
}
}
public int relaxedHashCode() {
return deepRelaxedHashcode(this.spline);
}
static {
SPLINE_METHOD_DESC = Type.getMethodDescriptor(Type.getType(Float.TYPE), new Type[]{Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(EvalType.class)});
}
private static record ValuesMethodDef(boolean isConst, String generatedMethod, float constValue) {
private ValuesMethodDef(boolean isConst, String generatedMethod, float constValue) {
this.isConst = isConst;
this.generatedMethod = generatedMethod;
this.constValue = constValue;
}
public boolean isConst() {
return this.isConst;
}
public String generatedMethod() {
return this.generatedMethod;
}
public float constValue() {
return this.constValue;
}
}
}

View File

@@ -1,29 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.spline;
public class SplineSupport {
public SplineSupport() {
}
public static int findRangeForLocation(float[] locations, float x) {
int min = 0;
int i = locations.length;
while(i > 0) {
int j = i / 2;
int k = min + j;
if (x < locations[k]) {
i = j;
} else {
min = k + 1;
i -= j + 1;
}
}
return min - 1;
}
public static float sampleOutsideRange(float point, float[] locations, float value, float[] derivatives, int i) {
float f = derivatives[i];
return f == 0.0F ? value : value + f * (point - locations[i]);
}
}

View File

@@ -1,49 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class AbsNode extends AbstractUnaryNode {
public AbsNode(AstNode operand) {
super(operand);
}
protected AstNode newInstance(AstNode operand) {
return new AbsNode(operand);
}
public double evalSingle(int x, int y, int z, EvalType type) {
return Math.abs(this.operand.evalSingle(x, y, z, type));
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.operand.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = Math.abs(res[i]);
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.invokestatic(Type.getInternalName(Math.class), "abs", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenMulti(context, m, localVarConsumer);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.invokestatic(Type.getInternalName(Math.class), "abs", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE}), false);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
}

View File

@@ -1,72 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.AstTransformer;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import java.util.Objects;
import org.objectweb.asm.commons.InstructionAdapter;
public abstract class AbstractUnaryNode implements AstNode {
protected final AstNode operand;
public AbstractUnaryNode(AstNode operand) {
this.operand = (AstNode)Objects.requireNonNull(operand);
}
public AstNode[] getChildren() {
return new AstNode[]{this.operand};
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
AbstractUnaryNode that = (AbstractUnaryNode)o;
return Objects.equals(this.operand, that.operand);
} else {
return false;
}
}
public int hashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.operand.hashCode();
return result;
}
public boolean relaxedEquals(AstNode o) {
if (this == o) {
return true;
} else if (o != null && this.getClass() == o.getClass()) {
AbstractUnaryNode that = (AbstractUnaryNode)o;
return this.operand.relaxedEquals(that.operand);
} else {
return false;
}
}
public int relaxedHashCode() {
int result = 1;
result = 31 * result + this.getClass().hashCode();
result = 31 * result + this.operand.relaxedHashCode();
return result;
}
protected abstract AstNode newInstance(AstNode var1);
public AstNode transform(AstTransformer transformer) {
AstNode operand = this.operand.transform(transformer);
return this.operand == operand ? transformer.transform(this) : transformer.transform(this.newInstance(operand));
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String operandMethod = context.newSingleMethod(this.operand);
context.callDelegateSingle(m, operandMethod);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
String operandMethod = context.newMultiMethod(this.operand);
context.callDelegateMulti(m, operandMethod);
}
}

View File

@@ -1,56 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class CubeNode extends AbstractUnaryNode {
public CubeNode(AstNode operand) {
super(operand);
}
protected AstNode newInstance(AstNode operand) {
return new CubeNode(operand);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = this.operand.evalSingle(x, y, z, type);
return v * v * v;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.operand.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] = res[i] * res[i] * res[i];
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.dup2();
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenMulti(context, m, localVarConsumer);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.dup2();
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
}

View File

@@ -1,83 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class NegMulNode extends AbstractUnaryNode {
private final double negMul;
public NegMulNode(AstNode operand, double negMul) {
super(operand);
this.negMul = negMul;
}
protected AstNode newInstance(AstNode operand) {
return new NegMulNode(operand, this.negMul);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = this.operand.evalSingle(x, y, z, type);
return v > 0.0 ? v : v * this.negMul;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.operand.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
double v = res[i];
res[i] = v > 0.0 ? v : v * this.negMul;
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
m.store(v, Type.DOUBLE_TYPE);
Label negMulLabel = new Label();
Label end = new Label();
m.load(v, Type.DOUBLE_TYPE);
m.dconst(0.0);
m.cmpl(Type.DOUBLE_TYPE);
m.ifle(negMulLabel);
m.load(v, Type.DOUBLE_TYPE);
m.goTo(end);
m.visitLabel(negMulLabel);
m.load(v, Type.DOUBLE_TYPE);
m.dconst(this.negMul);
m.mul(Type.DOUBLE_TYPE);
m.visitLabel(end);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenMulti(context, m, localVarConsumer);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.store(v, Type.DOUBLE_TYPE);
Label negMulLabel = new Label();
Label end = new Label();
m.load(v, Type.DOUBLE_TYPE);
m.dconst(0.0);
m.cmpl(Type.DOUBLE_TYPE);
m.ifle(negMulLabel);
m.load(v, Type.DOUBLE_TYPE);
m.goTo(end);
m.visitLabel(negMulLabel);
m.load(v, Type.DOUBLE_TYPE);
m.dconst(this.negMul);
m.mul(Type.DOUBLE_TYPE);
m.visitLabel(end);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
}

View File

@@ -1,52 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class SquareNode extends AbstractUnaryNode {
public SquareNode(AstNode operand) {
super(operand);
}
protected AstNode newInstance(AstNode operand) {
return new SquareNode(operand);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = this.operand.evalSingle(x, y, z, type);
return v * v;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.operand.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
res[i] *= res[i];
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenMulti(context, m, localVarConsumer);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
}

View File

@@ -1,84 +0,0 @@
package org.bxteam.divinemc.dfc.common.ast.unary;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.gen.BytecodeGen;
import net.minecraft.util.Mth;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
public class SqueezeNode extends AbstractUnaryNode {
public SqueezeNode(AstNode operand) {
super(operand);
}
protected AstNode newInstance(AstNode operand) {
return new SqueezeNode(operand);
}
public double evalSingle(int x, int y, int z, EvalType type) {
double v = Mth.clamp(this.operand.evalSingle(x, y, z, type), -1.0, 1.0);
return v / 2.0 - v * v * v / 24.0;
}
public void evalMulti(double[] res, int[] x, int[] y, int[] z, EvalType type) {
this.operand.evalMulti(res, x, y, z, type);
for(int i = 0; i < res.length; ++i) {
double v = Mth.clamp(res[i], -1.0, 1.0);
res[i] = v / 2.0 - v * v * v / 24.0;
}
}
public void doBytecodeGenSingle(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenSingle(context, m, localVarConsumer);
m.dconst(1.0);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.dconst(-1.0);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
m.store(v, Type.DOUBLE_TYPE);
m.load(v, Type.DOUBLE_TYPE);
m.dconst(2.0);
m.div(Type.DOUBLE_TYPE);
m.load(v, Type.DOUBLE_TYPE);
m.dup2();
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.dconst(24.0);
m.div(Type.DOUBLE_TYPE);
m.sub(Type.DOUBLE_TYPE);
m.areturn(Type.DOUBLE_TYPE);
}
public void doBytecodeGenMulti(BytecodeGen.Context context, InstructionAdapter m, BytecodeGen.Context.LocalVarConsumer localVarConsumer) {
super.doBytecodeGenMulti(context, m, localVarConsumer);
context.doCountedLoop(m, localVarConsumer, (idx) -> {
int v = localVarConsumer.createLocalVariable("v", Type.DOUBLE_TYPE.getDescriptor());
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.dup2();
m.aload(Type.DOUBLE_TYPE);
m.dconst(1.0);
m.invokestatic(Type.getInternalName(Math.class), "min", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.dconst(-1.0);
m.invokestatic(Type.getInternalName(Math.class), "max", Type.getMethodDescriptor(Type.DOUBLE_TYPE, new Type[]{Type.DOUBLE_TYPE, Type.DOUBLE_TYPE}), false);
m.store(v, Type.DOUBLE_TYPE);
m.load(v, Type.DOUBLE_TYPE);
m.dconst(2.0);
m.div(Type.DOUBLE_TYPE);
m.load(v, Type.DOUBLE_TYPE);
m.dup2();
m.dup2();
m.mul(Type.DOUBLE_TYPE);
m.mul(Type.DOUBLE_TYPE);
m.dconst(24.0);
m.div(Type.DOUBLE_TYPE);
m.sub(Type.DOUBLE_TYPE);
m.astore(Type.DOUBLE_TYPE);
});
m.areturn(Type.VOID_TYPE);
}
}

View File

@@ -1,7 +0,0 @@
package org.bxteam.divinemc.dfc.common.ducks;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
public interface IArrayCacheCapable {
ArrayCache c2me$getArrayCache();
}

View File

@@ -1,5 +0,0 @@
package org.bxteam.divinemc.dfc.common.ducks;
public interface IBlendingAwareVisitor {
boolean c2me$isBlendingEnabled();
}

View File

@@ -1,5 +0,0 @@
package org.bxteam.divinemc.dfc.common.ducks;
public interface ICoordinatesFilling {
void c2me$fillCoordinates(int[] var1, int[] var2, int[] var3);
}

View File

@@ -1,7 +0,0 @@
package org.bxteam.divinemc.dfc.common.ducks;
public interface IEqualityOverriding {
void c2me$overrideEquality(Object var1);
Object c2me$getOverriddenEquality();
}

View File

@@ -1,20 +0,0 @@
package org.bxteam.divinemc.dfc.common.ducks;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import net.minecraft.world.level.levelgen.DensityFunction;
public interface IFastCacheLike extends DensityFunction {
long CACHE_MISS_NAN_BITS = 9222769054270909007L;
double c2me$getCached(int var1, int var2, int var3, EvalType var4);
boolean c2me$getCached(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
void c2me$cache(int var1, int var2, int var3, EvalType var4, double var5);
void c2me$cache(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
DensityFunction c2me$getDelegate();
DensityFunction c2me$withDelegate(DensityFunction var1);
}

View File

@@ -1,499 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import com.google.common.io.Files;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ast.McToAst;
import org.bxteam.divinemc.dfc.common.ast.dfvisitor.StripBlending;
import org.bxteam.divinemc.dfc.common.ast.misc.ConstantNode;
import org.bxteam.divinemc.dfc.common.ast.misc.RootNode;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import org.bxteam.divinemc.dfc.common.vif.AstVanillaInterface;
import it.unimi.dsi.fastutil.Hash;
import it.unimi.dsi.fastutil.Pair;
import it.unimi.dsi.fastutil.ints.IntObjectPair;
import it.unimi.dsi.fastutil.objects.Object2ReferenceMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceMaps;
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenCustomHashMap;
import it.unimi.dsi.fastutil.objects.Object2ReferenceOpenHashMap;
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;
import net.minecraft.util.CubicSpline;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.DensityFunctions;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.AnalyzerAdapter;
import org.objectweb.asm.commons.InstructionAdapter;
public class BytecodeGen {
private static final File exportDir = new File("./cache/c2me-dfc");
private static final AtomicLong ordinal = new AtomicLong();
public static final Hash.Strategy<AstNode> RELAXED_STRATEGY;
private static final Object2ReferenceMap<AstNode, Class<?>> compilationCache;
public BytecodeGen() {
}
public static DensityFunction compile(DensityFunction densityFunction, Reference2ReferenceMap<DensityFunction, DensityFunction> tempCache) {
DensityFunction cached = (DensityFunction)tempCache.get(densityFunction);
if (cached != null) {
return cached;
} else if (densityFunction instanceof AstVanillaInterface) {
AstVanillaInterface vif = (AstVanillaInterface)densityFunction;
AstNode ast = vif.getAstNode();
return new CompiledDensityFunction(compile0(ast), vif.getBlendingFallback());
} else {
AstNode ast = McToAst.toAst(densityFunction.mapAll(StripBlending.INSTANCE));
if (ast instanceof ConstantNode) {
ConstantNode constantNode = (ConstantNode)ast;
return DensityFunctions.constant(constantNode.getValue());
} else {
CompiledDensityFunction compiled = new CompiledDensityFunction(compile0(ast), densityFunction);
tempCache.put(densityFunction, compiled);
return compiled;
}
}
}
public static synchronized CompiledEntry compile0(AstNode node) {
Class<?> cached = (Class)compilationCache.get(node);
ClassWriter writer = new ClassWriter(3);
String name = cached != null ? String.format("DfcCompiled_discarded") : String.format("DfcCompiled_%d", ordinal.getAndIncrement());
writer.visit(65, 17, name, (String)null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(CompiledEntry.class)});
RootNode rootNode = new RootNode(node);
Context genContext = new Context(writer, name);
genContext.newSingleMethod0((adapter, localVarConsumer) -> {
rootNode.doBytecodeGenSingle(genContext, adapter, localVarConsumer);
}, "evalSingle", true);
genContext.newMultiMethod0((adapter, localVarConsumer) -> {
rootNode.doBytecodeGenMulti(genContext, adapter, localVarConsumer);
}, "evalMulti", true);
List<Object> args = (List)genContext.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
return ((Context.FieldRecord)o.getValue()).ordinal();
})).map(Map.Entry::getKey).collect(Collectors.toCollection(ArrayList::new));
if (cached != null) {
try {
return (CompiledEntry)cached.getConstructor(List.class).newInstance(args);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException var11) {
ReflectiveOperationException e = var11;
throw new RuntimeException(e);
}
} else {
genConstructor(genContext);
genGetArgs(genContext);
genNewInstance(genContext);
Object var8;
for(ListIterator<Object> iterator = args.listIterator(); iterator.hasNext(); var8 = iterator.next()) {
}
byte[] bytes = writer.toByteArray();
dumpClass(genContext.className, bytes);
Class<?> defined = defineClass(genContext.className, bytes);
compilationCache.put(node, defined);
try {
return (CompiledEntry)defined.getConstructor(List.class).newInstance(args);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | InstantiationException var12) {
ReflectiveOperationException e = var12;
throw new RuntimeException(e);
}
}
}
private static void genConstructor(Context context) {
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 1, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), context.classWriter.visitMethod(1, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), (String)null, (String[])null)));
Label start = new Label();
Label end = new Label();
m.visitLabel(start);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(Type.getInternalName(Object.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[0]), false);
Iterator var4 = context.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
return ((Context.FieldRecord)o.getValue()).ordinal();
})).toList().iterator();
while(var4.hasNext()) {
Map.Entry<Object, Context.FieldRecord> entry = (Map.Entry)var4.next();
String name = ((Context.FieldRecord)entry.getValue()).name();
Class<?> type = ((Context.FieldRecord)entry.getValue()).type();
int ordinal = ((Context.FieldRecord)entry.getValue()).ordinal();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.iconst(ordinal);
m.invokeinterface(Type.getInternalName(List.class), "get", Type.getMethodDescriptor(InstructionAdapter.OBJECT_TYPE, new Type[]{Type.INT_TYPE}));
m.checkcast(Type.getType(type));
m.putfield(context.className, name, Type.getDescriptor(type));
}
var4 = context.postProcessMethods.stream().sorted().toList().iterator();
while(var4.hasNext()) {
String postProcessingMethod = (String)var4.next();
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(context.className, postProcessingMethod, "()V", false);
}
m.areturn(Type.VOID_TYPE);
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
m.visitMaxs(0, 0);
}
private static void genGetArgs(Context context) {
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 17, "getArgs", Type.getMethodDescriptor(Type.getType(List.class), new Type[0]), context.classWriter.visitMethod(17, "getArgs", Type.getMethodDescriptor(Type.getType(List.class), new Type[0]), (String)null, (String[])null)));
Label start = new Label();
Label end = new Label();
m.visitLabel(start);
m.anew(Type.getType(ArrayList.class));
m.dup();
m.iconst(context.args.size());
m.invokespecial(Type.getInternalName(ArrayList.class), "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.INT_TYPE}), false);
m.store(1, InstructionAdapter.OBJECT_TYPE);
Iterator var4 = context.args.entrySet().stream().sorted(Comparator.comparingInt((o) -> {
return ((Context.FieldRecord)o.getValue()).ordinal();
})).toList().iterator();
while(var4.hasNext()) {
Map.Entry<Object, Context.FieldRecord> entry = (Map.Entry)var4.next();
String name = ((Context.FieldRecord)entry.getValue()).name();
Class<?> type = ((Context.FieldRecord)entry.getValue()).type();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.getfield(context.className, name, Type.getDescriptor(type));
m.invokeinterface(Type.getInternalName(List.class), "add", Type.getMethodDescriptor(Type.BOOLEAN_TYPE, new Type[]{InstructionAdapter.OBJECT_TYPE}));
m.pop();
}
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.areturn(InstructionAdapter.OBJECT_TYPE);
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
m.visitMaxs(0, 0);
}
private static void genNewInstance(Context context) {
InstructionAdapter m = new InstructionAdapter(new AnalyzerAdapter(context.className, 17, "newInstance", Type.getMethodDescriptor(Type.getType(CompiledEntry.class), new Type[]{Type.getType(List.class)}), context.classWriter.visitMethod(17, "newInstance", Type.getMethodDescriptor(Type.getType(CompiledEntry.class), new Type[]{Type.getType(List.class)}), (String)null, (String[])null)));
Label start = new Label();
Label end = new Label();
m.visitLabel(start);
m.anew(Type.getType(context.classDesc));
m.dup();
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.invokespecial(context.className, "<init>", Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(List.class)}), false);
m.areturn(InstructionAdapter.OBJECT_TYPE);
m.visitLabel(end);
m.visitLocalVariable("this", context.classDesc, (String)null, start, end, 0);
m.visitLocalVariable("list", Type.getDescriptor(List.class), (String)null, start, end, 1);
m.visitMaxs(0, 0);
}
private static void dumpClass(String className, byte[] bytes) {
File outputFile = new File(exportDir, className + ".class");
outputFile.getParentFile().mkdirs();
try {
Files.write(bytes, outputFile);
} catch (IOException var4) {
IOException e = var4;
e.printStackTrace();
}
}
private static Class<?> defineClass(final String className, final byte[] bytes) {
ClassLoader classLoader = new ClassLoader(BytecodeGen.class.getClassLoader()) {
public Class<?> loadClass(String name) throws ClassNotFoundException {
return name.equals(className) ? super.defineClass(name, bytes, 0, bytes.length) : super.loadClass(name);
}
};
try {
return classLoader.loadClass(className);
} catch (ClassNotFoundException var4) {
ClassNotFoundException e = var4;
throw new RuntimeException(e);
}
}
static {
try {
org.bxteam.divinemc.util.Files.deleteRecursively(exportDir);
} catch (IOException var1) {
IOException e = var1;
e.printStackTrace();
}
RELAXED_STRATEGY = new Hash.Strategy<AstNode>() {
public int hashCode(AstNode o) {
return o.relaxedHashCode();
}
public boolean equals(AstNode a, AstNode b) {
return a.relaxedEquals(b);
}
};
compilationCache = Object2ReferenceMaps.synchronize(new Object2ReferenceOpenCustomHashMap<>(RELAXED_STRATEGY));
}
public static class Context {
public static final String SINGLE_DESC;
public static final String MULTI_DESC;
public final ClassWriter classWriter;
public final String className;
public final String classDesc;
private int methodIdx = 0;
private final Object2ReferenceOpenHashMap<AstNode, String> singleMethods = new Object2ReferenceOpenHashMap<>();
private final Object2ReferenceOpenHashMap<AstNode, String> multiMethods = new Object2ReferenceOpenHashMap<>();
private final Object2ReferenceOpenHashMap<CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate>, String> splineMethods = new Object2ReferenceOpenHashMap<>();
private final ObjectOpenHashSet<String> postProcessMethods = new ObjectOpenHashSet<>();
private final Reference2ObjectOpenHashMap<Object, FieldRecord> args = new Reference2ObjectOpenHashMap<>();
public Context(ClassWriter classWriter, String className) {
this.classWriter = (ClassWriter)Objects.requireNonNull(classWriter);
this.className = (String)Objects.requireNonNull(className);
this.classDesc = String.format("L%s;", this.className);
}
public String nextMethodName() {
return String.format("method_%d", this.methodIdx++);
}
public String nextMethodName(String suffix) {
return String.format("method_%d_%s", this.methodIdx++, suffix);
}
public String newSingleMethod(AstNode node) {
return this.singleMethods.computeIfAbsent(node, (AstNode node1) -> this.newSingleMethod((adapter, localVarConsumer) -> node1.doBytecodeGenSingle(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName())));
}
public String newSingleMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator) {
return this.newSingleMethod(generator, this.nextMethodName());
}
public String newSingleMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name) {
this.newSingleMethod0(generator, name, false);
return name;
}
private void newSingleMethod0(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name, boolean isPublic) {
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, (isPublic ? 1 : 2) | 16, name, SINGLE_DESC, this.classWriter.visitMethod((isPublic ? 1 : 2) | 16, name, SINGLE_DESC, (String)null, (String[])null)));
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList<>();
Label start = new Label();
Label end = new Label();
adapter.visitLabel(start);
generator.accept(adapter, (localName, localDesc) -> {
int ordinal = extraLocals.size() + 5;
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
return ordinal;
});
adapter.visitLabel(end);
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
adapter.visitLocalVariable("x", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 1);
adapter.visitLocalVariable("y", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 2);
adapter.visitLocalVariable("z", Type.INT_TYPE.getDescriptor(), (String)null, start, end, 3);
adapter.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 4);
Iterator var8 = extraLocals.iterator();
while(var8.hasNext()) {
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var8.next();
adapter.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
}
adapter.visitMaxs(0, 0);
}
public String newMultiMethod(AstNode node) {
return this.multiMethods.computeIfAbsent(node, (AstNode node1) -> this.newMultiMethod((adapter, localVarConsumer) -> node1.doBytecodeGenMulti(this, adapter, localVarConsumer), nextMethodName(node.getClass().getSimpleName())));
}
public String newMultiMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator) {
return this.newMultiMethod(generator, this.nextMethodName());
}
public String newMultiMethod(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name) {
this.newMultiMethod0(generator, name, false);
return name;
}
private void newMultiMethod0(BiConsumer<InstructionAdapter, LocalVarConsumer> generator, String name, boolean isPublic) {
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, (isPublic ? 1 : 2) | 16, name, MULTI_DESC, this.classWriter.visitMethod((isPublic ? 1 : 2) | 16, name, MULTI_DESC, (String)null, (String[])null)));
List<IntObjectPair<Pair<String, String>>> extraLocals = new ArrayList();
Label start = new Label();
Label end = new Label();
adapter.visitLabel(start);
generator.accept(adapter, (localName, localDesc) -> {
int ordinal = extraLocals.size() + 7;
extraLocals.add(IntObjectPair.of(ordinal, Pair.of(localName, localDesc)));
return ordinal;
});
adapter.visitLabel(end);
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
adapter.visitLocalVariable("res", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 1);
adapter.visitLocalVariable("x", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 2);
adapter.visitLocalVariable("y", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 3);
adapter.visitLocalVariable("z", Type.getType(double[].class).getDescriptor(), (String)null, start, end, 4);
adapter.visitLocalVariable("evalType", Type.getType(EvalType.class).getDescriptor(), (String)null, start, end, 5);
adapter.visitLocalVariable("arrayCache", Type.getType(ArrayCache.class).getDescriptor(), (String)null, start, end, 6);
Iterator var8 = extraLocals.iterator();
while(var8.hasNext()) {
IntObjectPair<Pair<String, String>> local = (IntObjectPair)var8.next();
adapter.visitLocalVariable((String)((Pair)local.right()).left(), (String)((Pair)local.right()).right(), (String)null, start, end, local.leftInt());
}
adapter.visitMaxs(0, 0);
}
public String getCachedSplineMethod(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline) {
return (String)this.splineMethods.get(spline);
}
public void cacheSplineMethod(CubicSpline<DensityFunctions.Spline.Point, DensityFunctions.Spline.Coordinate> spline, String method) {
this.splineMethods.put(spline, method);
}
public void callDelegateSingle(InstructionAdapter m, String target) {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(1, Type.INT_TYPE);
m.load(2, Type.INT_TYPE);
m.load(3, Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(this.className, target, SINGLE_DESC, false);
}
public void callDelegateMulti(InstructionAdapter m, String target) {
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.load(6, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(this.className, target, MULTI_DESC, false);
}
public <T> String newField(Class<T> type, T data) {
FieldRecord existing = (FieldRecord)this.args.get(data);
if (existing != null) {
return existing.name();
} else {
int size = this.args.size();
String name = String.format("field_%d", size);
this.classWriter.visitField(2, name, Type.getDescriptor(type), (String)null, (Object)null);
this.args.put(data, new FieldRecord(name, size, type));
return name;
}
}
public void doCountedLoop(InstructionAdapter m, LocalVarConsumer localVarConsumer, IntConsumer bodyGenerator) {
int loopIdx = localVarConsumer.createLocalVariable("loopIdx", Type.INT_TYPE.getDescriptor());
m.iconst(0);
m.store(loopIdx, Type.INT_TYPE);
Label start = new Label();
Label end = new Label();
m.visitLabel(start);
m.load(loopIdx, Type.INT_TYPE);
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.arraylength();
m.ificmpge(end);
bodyGenerator.accept(loopIdx);
m.iinc(loopIdx, 1);
m.goTo(start);
m.visitLabel(end);
}
public void delegateToSingle(InstructionAdapter m, LocalVarConsumer localVarConsumer, AstNode current) {
String singleMethod = this.newSingleMethod(current);
this.doCountedLoop(m, localVarConsumer, (idx) -> {
m.load(1, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.load(0, InstructionAdapter.OBJECT_TYPE);
m.load(2, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(3, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(4, InstructionAdapter.OBJECT_TYPE);
m.load(idx, Type.INT_TYPE);
m.aload(Type.INT_TYPE);
m.load(5, InstructionAdapter.OBJECT_TYPE);
m.invokevirtual(this.className, singleMethod, SINGLE_DESC, false);
m.astore(Type.DOUBLE_TYPE);
});
}
public void genPostprocessingMethod(String name, Consumer<InstructionAdapter> generator) {
if (!this.postProcessMethods.contains(name)) {
InstructionAdapter adapter = new InstructionAdapter(new AnalyzerAdapter(this.className, 18, name, "()V", this.classWriter.visitMethod(18, name, "()V", (String)null, (String[])null)));
Label start = new Label();
Label end = new Label();
adapter.visitLabel(start);
generator.accept(adapter);
adapter.visitLabel(end);
adapter.visitMaxs(0, 0);
adapter.visitLocalVariable("this", this.classDesc, (String)null, start, end, 0);
this.postProcessMethods.add(name);
}
}
static {
SINGLE_DESC = Type.getMethodDescriptor(Type.getType(Double.TYPE), new Type[]{Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(Integer.TYPE), Type.getType(EvalType.class)});
MULTI_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, new Type[]{Type.getType(double[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(int[].class), Type.getType(EvalType.class), Type.getType(ArrayCache.class)});
}
public interface LocalVarConsumer {
int createLocalVariable(String var1, String var2);
}
private static record FieldRecord(String name, int ordinal, Class<?> type) {
private FieldRecord(String name, int ordinal, Class<?> type) {
this.name = name;
this.ordinal = ordinal;
this.type = type;
}
public String name() {
return this.name;
}
public int ordinal() {
return this.ordinal;
}
public Class<?> type() {
return this.type;
}
}
}
@FunctionalInterface
public interface EvalMultiInterface {
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5);
}
@FunctionalInterface
public interface EvalSingleInterface {
double evalSingle(int var1, int var2, int var3, EvalType var4);
}
}

View File

@@ -1,98 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import com.google.common.base.Suppliers;
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
import java.util.List;
import java.util.ListIterator;
import java.util.Objects;
import java.util.function.Supplier;
import net.minecraft.world.level.levelgen.DensityFunction;
public class CompiledDensityFunction extends SubCompiledDensityFunction {
private final CompiledEntry compiledEntry;
public CompiledDensityFunction(CompiledEntry compiledEntry, DensityFunction blendingFallback) {
super(compiledEntry, compiledEntry, blendingFallback);
this.compiledEntry = (CompiledEntry)Objects.requireNonNull(compiledEntry);
}
private CompiledDensityFunction(CompiledEntry compiledEntry, Supplier<DensityFunction> blendingFallback) {
super(compiledEntry, compiledEntry, blendingFallback);
this.compiledEntry = (CompiledEntry)Objects.requireNonNull(compiledEntry);
}
public DensityFunction mapAll(Visitor visitor) {
if (visitor instanceof IBlendingAwareVisitor blendingAwareVisitor) {
if (blendingAwareVisitor.c2me$isBlendingEnabled()) {
DensityFunction fallback1 = this.getFallback();
if (fallback1 == null) {
throw new IllegalStateException("blendingFallback is no more");
}
return fallback1.mapAll(visitor);
}
}
boolean modified = false;
List<Object> args = this.compiledEntry.getArgs();
ListIterator<Object> iterator = args.listIterator();
Object next;
while(iterator.hasNext()) {
next = iterator.next();
if (next instanceof DensityFunction df) {
if (!(df instanceof IFastCacheLike)) {
DensityFunction applied = df.mapAll(visitor);
if (df != applied) {
iterator.set(applied);
modified = true;
}
}
}
if (next instanceof NoiseHolder noise) {
NoiseHolder applied = visitor.visitNoise(noise);
if (noise != applied) {
iterator.set(applied);
modified = true;
}
}
}
iterator = args.listIterator();
while(iterator.hasNext()) {
next = iterator.next();
if (next instanceof IFastCacheLike cacheLike) {
DensityFunction applied = visitor.apply(cacheLike);
if (applied == cacheLike.c2me$getDelegate()) {
iterator.set((Object)null);
modified = true;
} else {
if (!(applied instanceof IFastCacheLike)) {
throw new UnsupportedOperationException("Unsupported transformation on Wrapping node");
}
IFastCacheLike newCacheLike = (IFastCacheLike)applied;
iterator.set(newCacheLike);
modified = true;
}
}
}
Supplier<DensityFunction> fallback = this.blendingFallback != null ? Suppliers.memoize(() -> {
DensityFunction densityFunction = (DensityFunction)this.blendingFallback.get();
return densityFunction != null ? densityFunction.mapAll(visitor) : null;
}) : null;
if (fallback != this.blendingFallback) {
modified = true;
}
if (modified) {
return new CompiledDensityFunction(this.compiledEntry.newInstance(args), fallback);
} else {
return this;
}
}
}

View File

@@ -1,15 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import java.util.List;
public interface CompiledEntry extends ISingleMethod, IMultiMethod {
double evalSingle(int var1, int var2, int var3, EvalType var4);
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5, ArrayCache var6);
CompiledEntry newInstance(List<?> var1);
List<Object> getArgs();
}

View File

@@ -1,28 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
import org.jetbrains.annotations.NotNull;
public class DelegatingBlendingAwareVisitor implements IBlendingAwareVisitor, DensityFunction.Visitor {
private final DensityFunction.Visitor delegate;
private final boolean blendingEnabled;
public DelegatingBlendingAwareVisitor(DensityFunction.Visitor delegate, boolean blendingEnabled) {
this.delegate = Objects.requireNonNull(delegate);
this.blendingEnabled = blendingEnabled;
}
public @NotNull DensityFunction apply(@NotNull DensityFunction densityFunction) {
return this.delegate.apply(densityFunction);
}
public DensityFunction.@NotNull NoiseHolder visitNoise(DensityFunction.@NotNull NoiseHolder noiseDensityFunction) {
return this.delegate.visitNoise(noiseDensityFunction);
}
public boolean c2me$isBlendingEnabled() {
return this.blendingEnabled;
}
}

View File

@@ -1,9 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
@FunctionalInterface
public interface IMultiMethod {
void evalMulti(double[] var1, int[] var2, int[] var3, int[] var4, EvalType var5, ArrayCache var6);
}

View File

@@ -1,8 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
@FunctionalInterface
public interface ISingleMethod {
double evalSingle(int var1, int var2, int var3, EvalType var4);
}

View File

@@ -1,142 +0,0 @@
package org.bxteam.divinemc.dfc.common.gen;
import com.google.common.base.Suppliers;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ducks.IArrayCacheCapable;
import org.bxteam.divinemc.dfc.common.ducks.IBlendingAwareVisitor;
import org.bxteam.divinemc.dfc.common.ducks.ICoordinatesFilling;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import org.bxteam.divinemc.dfc.common.vif.EachApplierVanillaInterface;
import java.util.Objects;
import java.util.function.Supplier;
import net.minecraft.util.KeyDispatchDataCodec;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.NoiseChunk;
import net.minecraft.world.level.levelgen.blending.Blender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SubCompiledDensityFunction implements DensityFunction {
private static final Logger LOGGER = LoggerFactory.getLogger(SubCompiledDensityFunction.class);
private final ISingleMethod singleMethod;
private final IMultiMethod multiMethod;
protected final Supplier<DensityFunction> blendingFallback;
public SubCompiledDensityFunction(ISingleMethod singleMethod, IMultiMethod multiMethod, DensityFunction blendingFallback) {
this(singleMethod, multiMethod, unwrap(blendingFallback));
}
protected SubCompiledDensityFunction(ISingleMethod singleMethod, IMultiMethod multiMethod, Supplier<DensityFunction> blendingFallback) {
this.singleMethod = (ISingleMethod)Objects.requireNonNull(singleMethod);
this.multiMethod = (IMultiMethod)Objects.requireNonNull(multiMethod);
this.blendingFallback = blendingFallback;
}
private static Supplier<DensityFunction> unwrap(DensityFunction densityFunction) {
if (densityFunction instanceof SubCompiledDensityFunction scdf) {
return scdf.blendingFallback;
} else {
return densityFunction != null ? Suppliers.ofInstance(densityFunction) : null;
}
}
public double compute(FunctionContext pos) {
if (pos.getBlender() != Blender.empty()) {
DensityFunction fallback = this.getFallback();
if (fallback == null) {
throw new IllegalStateException("blendingFallback is no more");
} else {
return fallback.compute(pos);
}
} else {
return this.singleMethod.evalSingle(pos.blockX(), pos.blockY(), pos.blockZ(), EvalType.from(pos));
}
}
public void fillArray(double[] densities, ContextProvider applier) {
if (applier instanceof NoiseChunk sampler) {
if (sampler.getBlender() != Blender.empty()) {
DensityFunction fallback = this.getFallback();
if (fallback == null) {
throw new IllegalStateException("blendingFallback is no more");
}
fallback.fillArray(densities, applier);
return;
}
}
if (applier instanceof EachApplierVanillaInterface vanillaInterface) {
this.multiMethod.evalMulti(densities, vanillaInterface.getX(), vanillaInterface.getY(), vanillaInterface.getZ(), EvalType.from(applier), vanillaInterface.c2me$getArrayCache());
} else {
ArrayCache var10000;
if (applier instanceof IArrayCacheCapable cacheCapable) {
var10000 = cacheCapable.c2me$getArrayCache();
} else {
var10000 = new ArrayCache();
}
ArrayCache cache = var10000;
int[] x = cache.getIntArray(densities.length, false);
int[] y = cache.getIntArray(densities.length, false);
int[] z = cache.getIntArray(densities.length, false);
if (applier instanceof ICoordinatesFilling coordinatesFilling) {
coordinatesFilling.c2me$fillCoordinates(x, y, z);
} else {
for(int i = 0; i < densities.length; ++i) {
FunctionContext pos = applier.forIndex(i);
x[i] = pos.blockX();
y[i] = pos.blockY();
z[i] = pos.blockZ();
}
}
this.multiMethod.evalMulti(densities, x, y, z, EvalType.from(applier), cache);
}
}
public DensityFunction mapAll(Visitor visitor) {
if (this.getClass() != SubCompiledDensityFunction.class) {
throw new AbstractMethodError();
} else {
if (visitor instanceof IBlendingAwareVisitor) {
IBlendingAwareVisitor blendingAwareVisitor = (IBlendingAwareVisitor)visitor;
if (blendingAwareVisitor.c2me$isBlendingEnabled()) {
DensityFunction fallback1 = this.getFallback();
if (fallback1 == null) {
throw new IllegalStateException("blendingFallback is no more");
}
return fallback1.mapAll(visitor);
}
}
boolean modified = false;
Supplier<DensityFunction> fallback = this.blendingFallback != null ? Suppliers.memoize(() -> {
DensityFunction densityFunction = (DensityFunction)this.blendingFallback.get();
return densityFunction != null ? densityFunction.mapAll(visitor) : null;
}) : null;
if (fallback != this.blendingFallback) {
modified = true;
}
return modified ? new SubCompiledDensityFunction(this.singleMethod, this.multiMethod, fallback) : this;
}
}
public double minValue() {
return Double.MIN_VALUE;
}
public double maxValue() {
return Double.MAX_VALUE;
}
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
throw new UnsupportedOperationException();
}
protected DensityFunction getFallback() {
return this.blendingFallback != null ? (DensityFunction)this.blendingFallback.get() : null;
}
}

View File

@@ -1,57 +0,0 @@
package org.bxteam.divinemc.dfc.common.util;
import it.unimi.dsi.fastutil.ints.Int2ReferenceArrayMap;
import it.unimi.dsi.fastutil.objects.ReferenceArrayList;
import java.util.Arrays;
public class ArrayCache {
private final Int2ReferenceArrayMap<ReferenceArrayList<double[]>> doubleArrayCache = new Int2ReferenceArrayMap<>();
private final Int2ReferenceArrayMap<ReferenceArrayList<int[]>> intArrayCache = new Int2ReferenceArrayMap<>();
public ArrayCache() {
}
public double[] getDoubleArray(int size, boolean zero) {
ReferenceArrayList<double[]> list = this.doubleArrayCache.computeIfAbsent(size, (k) -> {
return new ReferenceArrayList<>();
});
if (list.isEmpty()) {
return new double[size];
} else {
double[] popped = list.pop();
if (zero) {
Arrays.fill(popped, 0.0);
}
return popped;
}
}
public int[] getIntArray(int size, boolean zero) {
ReferenceArrayList<int[]> list = this.intArrayCache.computeIfAbsent(size, (k) -> {
return new ReferenceArrayList<>();
});
if (list.isEmpty()) {
return new int[size];
} else {
int[] popped = list.pop();
if (zero) {
Arrays.fill(popped, 0);
}
return popped;
}
}
public void recycle(double[] array) {
this.doubleArrayCache.computeIfAbsent(array.length, (k) -> {
return new ReferenceArrayList<>();
}).add(array);
}
public void recycle(int[] array) {
this.intArrayCache.computeIfAbsent(array.length, (k) -> {
return new ReferenceArrayList<>();
}).add(array);
}
}

View File

@@ -1,98 +0,0 @@
package org.bxteam.divinemc.dfc.common.vif;
import org.bxteam.divinemc.dfc.common.ast.AstNode;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ast.misc.CacheLikeNode;
import org.bxteam.divinemc.dfc.common.ast.misc.DelegateNode;
import org.bxteam.divinemc.dfc.common.ducks.IFastCacheLike;
import java.util.Objects;
import net.minecraft.util.KeyDispatchDataCodec;
import net.minecraft.world.level.levelgen.DensityFunction;
import net.minecraft.world.level.levelgen.NoiseChunk;
import net.minecraft.world.level.levelgen.blending.Blender;
public class AstVanillaInterface implements DensityFunction {
private final AstNode astNode;
private final DensityFunction blendingFallback;
public AstVanillaInterface(AstNode astNode, DensityFunction blendingFallback) {
this.astNode = (AstNode)Objects.requireNonNull(astNode);
this.blendingFallback = blendingFallback;
}
public double compute(FunctionContext pos) {
if (pos.getBlender() != Blender.empty()) {
if (this.blendingFallback == null) {
throw new IllegalStateException("blendingFallback is no more");
} else {
return this.blendingFallback.compute(pos);
}
} else {
return this.astNode.evalSingle(pos.blockX(), pos.blockY(), pos.blockZ(), EvalType.from(pos));
}
}
public void fillArray(double[] densities, ContextProvider applier) {
if (applier instanceof NoiseChunk sampler) {
if (sampler.getBlender() != Blender.empty()) {
if (this.blendingFallback == null) {
throw new IllegalStateException("blendingFallback is no more");
}
this.blendingFallback.fillArray(densities, applier);
return;
}
}
if (applier instanceof EachApplierVanillaInterface vanillaInterface) {
this.astNode.evalMulti(densities, vanillaInterface.getX(), vanillaInterface.getY(), vanillaInterface.getZ(), EvalType.from(applier));
} else {
int[] x = new int[densities.length];
int[] y = new int[densities.length];
int[] z = new int[densities.length];
for(int i = 0; i < densities.length; ++i) {
FunctionContext pos = applier.forIndex(i);
x[i] = pos.blockX();
y[i] = pos.blockY();
z[i] = pos.blockZ();
}
this.astNode.evalMulti(densities, x, y, z, EvalType.from(applier));
}
}
public DensityFunction mapAll(Visitor visitor) {
AstNode transformed = this.astNode.transform((astNode) -> {
if (astNode instanceof DelegateNode delegateNode) {
return new DelegateNode(delegateNode.getDelegate().mapAll(visitor));
} else if (astNode instanceof CacheLikeNode cacheLikeNode) {
return new CacheLikeNode((IFastCacheLike)cacheLikeNode.getCacheLike().mapAll(visitor), cacheLikeNode.getDelegate());
} else {
return astNode;
}
});
DensityFunction blendingFallback1 = this.blendingFallback != null ? this.blendingFallback.mapAll(visitor) : null;
return transformed == this.astNode && blendingFallback1 == this.blendingFallback ? this : new AstVanillaInterface(transformed, blendingFallback1);
}
public double minValue() {
return this.blendingFallback.minValue();
}
public double maxValue() {
return this.blendingFallback.maxValue();
}
public KeyDispatchDataCodec<? extends DensityFunction> codec() {
throw new UnsupportedOperationException();
}
public AstNode getAstNode() {
return this.astNode;
}
public DensityFunction getBlendingFallback() {
return this.blendingFallback;
}
}

View File

@@ -1,58 +0,0 @@
package org.bxteam.divinemc.dfc.common.vif;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import org.bxteam.divinemc.dfc.common.ducks.IArrayCacheCapable;
import org.bxteam.divinemc.dfc.common.util.ArrayCache;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
public class EachApplierVanillaInterface implements DensityFunction.ContextProvider, IArrayCacheCapable {
private final int[] x;
private final int[] y;
private final int[] z;
private final EvalType type;
private final ArrayCache cache;
public EachApplierVanillaInterface(int[] x, int[] y, int[] z, EvalType type) {
this(x, y, z, type, new ArrayCache());
}
public EachApplierVanillaInterface(int[] x, int[] y, int[] z, EvalType type, ArrayCache cache) {
this.x = (int[])Objects.requireNonNull(x);
this.y = (int[])Objects.requireNonNull(y);
this.z = (int[])Objects.requireNonNull(z);
this.type = (EvalType)Objects.requireNonNull(type);
this.cache = (ArrayCache)Objects.requireNonNull(cache);
}
public DensityFunction.FunctionContext forIndex(int index) {
return new NoisePosVanillaInterface(this.x[index], this.y[index], this.z[index], this.type);
}
public void fillAllDirectly(double[] densities, DensityFunction densityFunction) {
for(int i = 0; i < this.x.length; ++i) {
densities[i] = densityFunction.compute(this.forIndex(i));
}
}
public int[] getX() {
return this.x;
}
public int[] getY() {
return this.y;
}
public int[] getZ() {
return this.z;
}
public EvalType getType() {
return this.type;
}
public ArrayCache c2me$getArrayCache() {
return this.cache;
}
}

View File

@@ -1,35 +0,0 @@
package org.bxteam.divinemc.dfc.common.vif;
import org.bxteam.divinemc.dfc.common.ast.EvalType;
import java.util.Objects;
import net.minecraft.world.level.levelgen.DensityFunction;
public class NoisePosVanillaInterface implements DensityFunction.FunctionContext {
private final int x;
private final int y;
private final int z;
private final EvalType type;
public NoisePosVanillaInterface(int x, int y, int z, EvalType type) {
this.x = x;
this.y = y;
this.z = z;
this.type = (EvalType)Objects.requireNonNull(type);
}
public int blockX() {
return this.x;
}
public int blockY() {
return this.y;
}
public int blockZ() {
return this.z;
}
public EvalType getType() {
return this.type;
}
}