Skip to content
This repository has been archived by the owner on Jun 30, 2024. It is now read-only.

Commit

Permalink
added a completely new math engine (nibble), which is extremely fast
Browse files Browse the repository at this point in the history
  • Loading branch information
RealRTTV committed Jun 4, 2023
1 parent 2a97a7c commit 8911efd
Show file tree
Hide file tree
Showing 10 changed files with 633 additions and 429 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G
loader_version=0.14.9

# Mod Properties
mod_version = 3.0.14
mod_version = 3.0.15
maven_group = ca.rttv
archives_base_name = chatcalc

Expand Down
38 changes: 24 additions & 14 deletions src/main/java/ca/rttv/chatcalc/ChatCalc.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import ca.rttv.chatcalc.tokens.Token;
import com.mojang.logging.LogUtils;
import net.fabricmc.loader.api.FabricLoader;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.widget.TextFieldWidget;
import net.minecraft.text.Text;
Expand All @@ -18,25 +19,22 @@ public class ChatCalc {
public static final Logger LOGGER = LogUtils.getLogger();
public static final Pattern NUMBER = Pattern.compile("[-+]?\\d+(\\.\\d+)?");
public static final String SEPARATOR = ";";
public static final char SEPARATOR_CHAR = ';';

@Contract(value = "_->_", mutates = "param1")
public static boolean tryParse(TextFieldWidget field) {
final MinecraftClient client = MinecraftClient.getInstance();
String originalText = field.getText();
int cursor = field.getCursor();
String text = originalText.substring(0, cursor);
if ((text.equals("config?") || text.equals("cfg?") || text.equals("?")) && client.player != null) {
client.player.sendMessage(Text.translatable("chatcalc.config.description"));
return false;
}
String text = ChatHelper.getWord(originalText, cursor);
String[] split = text.split("=");
if (split.length == 2) {
if (Config.JSON.has(split[0])) {
Config.JSON.addProperty(split[0], split[1]);
Config.refreshJson();
return ChatHelper.replaceWord(field, "");
} else {
Optional<Triplet<String, List<Token>, String[]>> parsedFunction = Config.parseFunction(text);
Optional<Triplet<String, String, String[]>> parsedFunction = Config.parseFunction(text);
if (parsedFunction.isPresent()) {
Config.FUNCTIONS.put(parsedFunction.get().getA(), new Pair<>(parsedFunction.get().getB(), parsedFunction.get().getC()));
Config.refreshJson();
Expand All @@ -49,24 +47,36 @@ public static boolean tryParse(TextFieldWidget field) {
client.player.sendMessage(Text.translatable("chatcalc." + split[0].substring(0, split[0].length() - 1) + ".description"));
return false;
}

String word = ChatHelper.getWord(originalText, cursor);
if (NUMBER.matcher(word).matches()) {

if ((text.equals("config?") || text.equals("cfg?") || text.equals("?")) && client.player != null) {
client.player.sendMessage(Text.translatable("chatcalc.config.description"));
return false;
} else if (NUMBER.matcher(text).matches()) {
return false;
} else {
boolean add = false;
if (word.endsWith("=")) {
word = word.substring(0, word.length() - 1);
if (text.endsWith("=")) {
text = text.substring(0, text.length() - 1);
add = true;
}
try {
String solution = Config.getDecimalFormat().format(MathEngine.eval(word));
long start = System.nanoTime();
double result = Config.makeEngine().eval(text, Optional.empty());
double us = (System.nanoTime() - start) / 1_000.0;
if (FabricLoader.getInstance().isDevelopmentEnvironment()) {
MinecraftClient.getInstance().player.sendMessage(Text.literal("Took " + us + "µs to parse equation"), true);
MinecraftClient.getInstance().player.sendMessage(Text.literal("Took " + us + "µs to parse equation"), false);
}
String solution = Config.getDecimalFormat().format(result); // so fast that creating a new one everytime doesn't matter, also lets me use fields
if (solution.equals("-0")) {
solution = "0";
}
Config.saveToChatHud(originalText);
Config.saveToClipboard(originalText);
return add ? ChatHelper.addWordAfterIndex(field, solution) : ChatHelper.replaceWord(field, solution);
} catch (Exception e) {
} catch (Throwable t) {
if (Config.logExceptions()) {
LOGGER.error("ChatCalc Parse Error: ", e);
LOGGER.error("ChatCalc Parse Error: ", t);
}
return false;
}
Expand Down
35 changes: 18 additions & 17 deletions src/main/java/ca/rttv/chatcalc/Config.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package ca.rttv.chatcalc;

import ca.rttv.chatcalc.tokens.NumberToken;
import ca.rttv.chatcalc.tokens.Token;
import com.google.common.collect.ImmutableMap;
import com.google.gson.*;
import net.minecraft.client.MinecraftClient;
Expand All @@ -10,14 +8,16 @@

import java.io.*;
import java.text.DecimalFormat;
import java.util.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class Config {
public static final JsonObject JSON;
public static final Gson GSON;
public static final File CONFIG_FILE;
public static final Map<String, Pair<List<Token>, String[]>> FUNCTIONS;
public static final Map<String, Pair<String, String[]>> FUNCTIONS;
public static final ImmutableMap<String, String> DEFAULTS;

static {
Expand All @@ -28,6 +28,7 @@ public class Config {
.put("log_exceptions", "false")
.put("copy_type", "none")
.put("calculate_last", "true")
.put("engine", "nibble")
.build();
CONFIG_FILE = new File(".", "config/chatcalc.json");
GSON = new GsonBuilder().setPrettyPrinting().create();
Expand Down Expand Up @@ -72,7 +73,7 @@ public static boolean logExceptions() {
public static void refreshJson() {
try {
FileWriter writer = new FileWriter(CONFIG_FILE);
JSON.add("functions", FUNCTIONS.entrySet().stream().map(x -> x.getKey() + "(" + String.join(ChatCalc.SEPARATOR, x.getValue().getRight()) + ")=" + x.getValue().getLeft().stream().map(Object::toString).collect(Collectors.joining())).collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
JSON.add("functions", FUNCTIONS.entrySet().stream().map(x -> x.getKey() + "(" + String.join(ChatCalc.SEPARATOR, x.getValue().getRight()) + ")=" + x.getValue().getLeft()).collect(JsonArray::new, JsonArray::add, JsonArray::addAll));
writer.write(GSON.toJson(JSON));
JSON.remove("functions");
writer.close();
Expand All @@ -99,7 +100,7 @@ public static void readJson() {
} catch (Exception ignored) { }
}

public static Optional<Triplet<String, List<Token>, String[]>> parseFunction(String function) {
public static Optional<Triplet<String, String, String[]>> parseFunction(String function) {
int functionNameEnd = function.indexOf('(');
if (functionNameEnd > 0) {
String functionName = function.substring(0, functionNameEnd);
Expand All @@ -112,11 +113,7 @@ public static Optional<Triplet<String, List<Token>, String[]>> parseFunction(Str
}
}
String rest = function.substring(paramsEnd + 2);
try {
List<Token> tokens = MathEngine.tokenize(rest);
return Optional.of(new Triplet<>(functionName, tokens, params));
// System.out.printf("fn: %s, params: %s, rest: %s%n", functionName, params, rest);
} catch (Exception ignored) { }
return Optional.of(new Triplet<>(functionName, rest, params));
}
}
return Optional.empty();
Expand All @@ -138,16 +135,12 @@ public static double func(String name, double... values) {
if (values.length != FUNCTIONS.get(name).getRight().length) {
throw new IllegalArgumentException();
}
List<Token> tokens = new ArrayList<>(FUNCTIONS.get(name).getLeft());
String input = FUNCTIONS.get(name).getLeft();
FunctionParameter[] parameters = new FunctionParameter[values.length];
for (int i = 0; i < parameters.length; i++) {
parameters[i] = new FunctionParameter(FUNCTIONS.get(name).getRight()[i], values[i]);
}
MathEngine.simplify(tokens, false, Optional.of(parameters));
if (tokens.get(0) instanceof NumberToken numberToken) {
return numberToken.val;
}
throw new IllegalArgumentException();
return Config.makeEngine().eval(input, Optional.of(parameters));
} else {
if (values.length == 0) {
throw new IllegalArgumentException();
Expand All @@ -162,4 +155,12 @@ public static void saveToClipboard(String input) {
client.keyboard.setClipboard(input);
}
}

public static MathEngine makeEngine() {
if (JSON.get("engine").getAsString().equals("token")) {
return new TokenizedMathEngine();
} else {
return new NibbleMathEngine();
}
}
}
4 changes: 1 addition & 3 deletions src/main/java/ca/rttv/chatcalc/FunctionParameter.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package ca.rttv.chatcalc;

public record FunctionParameter(String name, double value) {

}
public record FunctionParameter(String name, double value) {}
Loading

0 comments on commit 8911efd

Please sign in to comment.