mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-01-24 19:13:21 +08:00
Add DynamicFloat class
This commit is contained in:
parent
bf8ee32382
commit
558471237a
74
src/main/java/emu/grasscutter/data/common/DynamicFloat.java
Normal file
74
src/main/java/emu/grasscutter/data/common/DynamicFloat.java
Normal file
@ -0,0 +1,74 @@
|
||||
package emu.grasscutter.data.common;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import it.unimi.dsi.fastutil.floats.FloatArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
|
||||
import lombok.val;
|
||||
|
||||
public class DynamicFloat {
|
||||
public static class StackOp {
|
||||
enum Op {CONSTANT, KEY, ADD, SUB, MUL, DIV};
|
||||
public Op op;
|
||||
public float fValue;
|
||||
public String sValue;
|
||||
|
||||
public StackOp(String s) {
|
||||
switch (s.toUpperCase()) {
|
||||
case "ADD" -> this.op = Op.ADD;
|
||||
case "SUB" -> this.op = Op.SUB;
|
||||
case "MUL" -> this.op = Op.MUL;
|
||||
case "DIV" -> this.op = Op.DIV;
|
||||
default -> {
|
||||
this.op = Op.KEY;
|
||||
this.sValue = s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public StackOp(float f) {
|
||||
this.op = Op.CONSTANT;
|
||||
this.fValue = f;
|
||||
}
|
||||
}
|
||||
private List<StackOp> ops;
|
||||
private boolean dynamic = false;
|
||||
private float constant = 0f;
|
||||
|
||||
public DynamicFloat(float constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
|
||||
public DynamicFloat(String key) {
|
||||
this.dynamic = true;
|
||||
this.ops = List.of(new StackOp(key));
|
||||
}
|
||||
|
||||
public DynamicFloat(List<StackOp> ops) {
|
||||
this.dynamic = true;
|
||||
this.ops = ops;
|
||||
}
|
||||
|
||||
public float get() {
|
||||
return this.get(new Object2FloatArrayMap<String>());
|
||||
}
|
||||
|
||||
public float get(Object2FloatMap<String> props) {
|
||||
if (!dynamic)
|
||||
return constant;
|
||||
|
||||
val fl = new FloatArrayList();
|
||||
for (var op : this.ops) {
|
||||
switch (op.op) {
|
||||
case CONSTANT -> fl.push(op.fValue);
|
||||
case KEY -> fl.push(props.getOrDefault(op.sValue, 0f));
|
||||
case ADD -> fl.push(fl.popFloat() + fl.popFloat());
|
||||
case SUB -> fl.push(-fl.popFloat() + fl.popFloat()); // [f0, f1, f2] -> [f0, f1-f2] (opposite of RPN order)
|
||||
case MUL -> fl.push(fl.popFloat() * fl.popFloat());
|
||||
case DIV -> fl.push((1f/fl.popFloat()) * fl.popFloat()); // [f0, f1, f2] -> [f0, f1/f2]
|
||||
}
|
||||
}
|
||||
return fl.popFloat(); // well-formed data will always have only one value left at this point
|
||||
}
|
||||
}
|
@ -7,6 +7,7 @@ import java.io.Reader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@ -14,10 +15,49 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import com.google.gson.TypeAdapter;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.google.gson.stream.JsonReader;
|
||||
import com.google.gson.stream.JsonWriter;
|
||||
|
||||
import emu.grasscutter.data.common.DynamicFloat;
|
||||
import lombok.val;
|
||||
|
||||
public final class JsonUtils {
|
||||
static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
// Adapters
|
||||
static class DynamicFloatAdapter extends TypeAdapter<DynamicFloat> {
|
||||
@Override
|
||||
public DynamicFloat read(JsonReader reader) throws IOException {
|
||||
switch (reader.peek()) {
|
||||
case STRING:
|
||||
return new DynamicFloat(reader.nextString());
|
||||
case NUMBER:
|
||||
return new DynamicFloat((float) reader.nextDouble());
|
||||
case BEGIN_ARRAY:
|
||||
reader.beginArray();
|
||||
val opStack = new ArrayList<DynamicFloat.StackOp>();
|
||||
while (reader.hasNext()) {
|
||||
opStack.add(switch (reader.peek()) {
|
||||
case STRING -> new DynamicFloat.StackOp(reader.nextString());
|
||||
case NUMBER -> new DynamicFloat.StackOp((float) reader.nextDouble());
|
||||
default -> throw new IOException("Invalid DynamicFloat definition - " + reader.peek().name());
|
||||
});
|
||||
}
|
||||
reader.endArray();
|
||||
return new DynamicFloat(opStack);
|
||||
default:
|
||||
throw new IOException("Invalid DynamicFloat definition - " + reader.peek().name());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(JsonWriter writer, DynamicFloat f) {};
|
||||
}
|
||||
|
||||
static final Gson gson = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(DynamicFloat.class, new DynamicFloatAdapter())
|
||||
.create();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public static Gson getGsonFactory() {
|
||||
|
Loading…
Reference in New Issue
Block a user