Skip to content

Commit

Permalink
begin rewrite of graphing logic to be more object-oriented
Browse files Browse the repository at this point in the history
  • Loading branch information
Pixaurora committed Aug 8, 2023
1 parent 362047c commit 21f3b7d
Show file tree
Hide file tree
Showing 17 changed files with 491 additions and 238 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import net.minecraft.world.level.Level;
import net.pixaurora.janerator.Janerator;
import net.pixaurora.janerator.RegistryCache;
import net.pixaurora.janerator.graphing.ConfiguredGrapherSettings;

public class ConfigFileManager {
private final Path savePath;
Expand Down Expand Up @@ -88,7 +89,7 @@ private JaneratorConfig createDefault() {
List.of(
new GraphProperties(
Level.OVERWORLD,
new GrapherFactory(
new ConfiguredGrapherSettings(
List.of(
"phi = (1 + sqrt(5)) / 2",
"log_phi = ln(phi)",
Expand Down
21 changes: 11 additions & 10 deletions src/main/java/net/pixaurora/janerator/config/GraphProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,45 +7,46 @@
import net.minecraft.resources.ResourceKey;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.levelgen.FlatLevelSource;
import net.pixaurora.janerator.graphing.ConfiguredGraphLogic;
import net.pixaurora.janerator.graphing.Grapher;
import net.pixaurora.janerator.graphing.ConfiguredGrapherSettings;

public class GraphProperties {
private ResourceKey<Level> dimension;
private GrapherFactory grapherFactory;
private ConfiguredGrapherSettings grapherSettings;
private FlatLevelSource shadedGenerator;
private FlatLevelSource outlineGenerator;

private ThreadLocal<ConfiguredGraphLogic> grapher;
private ThreadLocal<Grapher> grapher;

public static Codec<GraphProperties> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
ResourceKey.codec(Registries.DIMENSION).fieldOf("dimension").forGetter(GraphProperties::getDimension),
GrapherFactory.CODEC.fieldOf("function_to_graph").forGetter(GraphProperties::getGrapherFactory),
ConfiguredGrapherSettings.CODEC.fieldOf("function_to_graph").forGetter(GraphProperties::getGrapherSettings),
FlatLevelSource.CODEC.fieldOf("shaded_in_generator").forGetter(GraphProperties::getShadedGenerator),
FlatLevelSource.CODEC.fieldOf("outlines_generator").forGetter(GraphProperties::getOutlineGenerator)
).apply(instance, GraphProperties::new)
);

public GraphProperties(ResourceKey<Level> dimension, GrapherFactory grapherFactory, FlatLevelSource shadedGenerator, FlatLevelSource outlineGenerator) {
public GraphProperties(ResourceKey<Level> dimension, ConfiguredGrapherSettings grapherSettings, FlatLevelSource shadedGenerator, FlatLevelSource outlineGenerator) {
this.dimension = dimension;

this.grapherFactory = grapherFactory;
this.grapherSettings = grapherSettings;

this.shadedGenerator = shadedGenerator;
this.outlineGenerator = outlineGenerator;

this.grapher = ThreadLocal.withInitial(() -> this.grapherFactory.createGraphLogic());
this.grapher = ThreadLocal.withInitial(() -> Grapher.fromConfig(this.grapherSettings));
}

public ResourceKey<Level> getDimension() {
return this.dimension;
}

public GrapherFactory getGrapherFactory() {
return this.grapherFactory;
public ConfiguredGrapherSettings getGrapherSettings() {
return this.grapherSettings;
}

public ConfiguredGraphLogic getLocalGrapher() {
public Grapher getLocalGrapher() {
return this.grapher.get();
}

Expand Down
42 changes: 0 additions & 42 deletions src/main/java/net/pixaurora/janerator/config/GrapherFactory.java

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package net.pixaurora.janerator.graphing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.mariuszgromada.math.mxparser.License;
import org.mariuszgromada.math.mxparser.mXparser;

import com.mojang.serialization.Codec;
import com.mojang.serialization.codecs.RecordCodecBuilder;

import net.pixaurora.janerator.graphing.variable.InputVariable;
import net.pixaurora.janerator.graphing.variable.Variable;

public class ConfiguredGrapherSettings {
public static final Codec<ConfiguredGrapherSettings> CODEC = RecordCodecBuilder.create(
instance -> instance.group(
Codec.STRING.listOf().fieldOf("variable_definitions").forGetter(ConfiguredGrapherSettings::getVariableDefinitions),
Codec.STRING.fieldOf("return_statement").forGetter(ConfiguredGrapherSettings::getReturnStatement)
)
.apply(instance, ConfiguredGrapherSettings::new)
);

static {
License.iConfirmNonCommercialUse("Rina Shaw <[email protected]>");

mXparser.disableImpliedMultiplicationMode(); // Implied multiplication breaks searching for missing user-defined arguments
mXparser.disableAlmostIntRounding();
mXparser.disableCanonicalRounding();
mXparser.disableUlpRounding();
}

private List<String> variableDefinitions;
private String returnStatement;

private List<Variable> variables;

public ConfiguredGrapherSettings(List<String> variableDefinitions, String returnStatement) {
this.variableDefinitions = variableDefinitions;
this.returnStatement = returnStatement;

this.variables = new ArrayList<>(this.variableDefinitions.size() + 1);
this.variables.add(new InputVariable("x"));
this.variables.add(new InputVariable("z"));

Map<String, Variable> variableTable = new HashMap<>(
this.variables.stream()
.collect(Collectors.toMap(Variable::getName, variable -> variable))
);

for (String definition : variableDefinitions) {
Variable nextVariable = Variable.fromStringDefinition(variableTable, definition);

this.variables.add(nextVariable);
variableTable.put(nextVariable.getName(), nextVariable);
}

this.variables.add(Variable.fromStringDefinition(variableTable, "returnValue = " + returnStatement));
}

public List<String> getVariableDefinitions() {
return this.variableDefinitions;
}

public String getReturnStatement() {
return this.returnStatement;
}

public List<Variable> getVariables() {
return this.variables;
}
}
88 changes: 88 additions & 0 deletions src/main/java/net/pixaurora/janerator/graphing/Grapher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package net.pixaurora.janerator.graphing;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;

import net.pixaurora.janerator.graphing.instruction.Instruction;
import net.pixaurora.janerator.graphing.variable.IndependentVariable;
import net.pixaurora.janerator.graphing.variable.InputVariable;
import net.pixaurora.janerator.graphing.variable.Variable;

public class Grapher {
private List<Double> startingVariables;
private List<Instruction> intermediaryInstructions;
private int returnIndex;

public Grapher(List<Double> startingVariables, List<Instruction> instructionsToApply, int returnIndex) {
this.startingVariables = startingVariables;
this.intermediaryInstructions = instructionsToApply;
this.returnIndex = returnIndex;
}

public static Grapher fromConfig(ConfiguredGrapherSettings config) {
AtomicInteger count = new AtomicInteger(-1);
Map<String, Integer> nameToIndex = new HashMap<>(
Map.of(
"x", count.getAndIncrement(),
"z", count.getAndIncrement()
)
);

List<Variable> allVariables = config.getVariables();
List<Variable> variableDefinitions = config.getVariables().stream()
.filter(variable -> ! (variable instanceof InputVariable))
.toList();


for (Variable variable : variableDefinitions) {
nameToIndex.computeIfAbsent(variable.getName(), name -> count.getAndIncrement());
}

List<Instruction> instructions = new ArrayList<>();
List<Double> startingVariables = IntStream.range(0, count.get())
.mapToDouble(value -> 0.0)
.boxed()
.toList();

for (Variable variable : variableDefinitions) {
int setIndex = nameToIndex.get(variable.getName());
int[] accessIndexes = variable.getRequiredVariables().stream()
.map(Variable::getName)
.map(nameToIndex::get)
.mapToInt(Integer::valueOf)
.toArray();

Instruction instruction = variable.createInstruction(accessIndexes, setIndex);

boolean definedOnce = allVariables.stream()
.filter(other -> variable.getName() == other.getName())
.count() < 1;

if (
variable instanceof IndependentVariable && definedOnce
) {
instruction.execute(startingVariables);
} else {
instructions.add(instruction);
}
}

return new Grapher(startingVariables, instructions, nameToIndex.get("returnValue"));
}

public boolean isShaded(double x, double z) {
List<Double> variables = new ArrayList<>(this.startingVariables);
variables.set(0, x);
variables.set(0, z);

for (Instruction instruction : this.intermediaryInstructions) {
instruction.execute(variables);
}

return variables.get(this.returnIndex) == 0.0;
}
}
Loading

0 comments on commit 21f3b7d

Please sign in to comment.