package openmods.calc; import com.google.common.base.Strings; import com.google.common.base.Supplier; import openmods.Log; public class SingleExprEvaluator<E, M> { public interface EnvironmentConfigurator<E> { public void accept(Environment<E> env); } private final Calculator<E, M> calculator; private boolean useFallback; private M exprType; private String expr; private IExecutable<E> compiledExpr; public SingleExprEvaluator(Calculator<E, M> calculator) { this.calculator = calculator; } public static <E, M> SingleExprEvaluator<E, M> create(Calculator<E, M> calculator) { return new SingleExprEvaluator<E, M>(calculator); } public void setExpr(M exprType, String expr) { this.exprType = exprType; this.expr = expr; this.compiledExpr = null; this.useFallback = false; } public E evaluate(EnvironmentConfigurator<E> conf, Supplier<E> fallbackValue) { if (useFallback || Strings.isNullOrEmpty(expr) || exprType == null) return fallbackValue.get(); if (compiledExpr == null) { try { compiledExpr = calculator.compilers.compile(exprType, expr); } catch (Exception ex) { useFallback = true; Log.warn(ex, "Failed to compile formula %s", expr); return fallbackValue.get(); } } conf.accept(calculator.environment); try { return calculator.environment.executeAndPop(compiledExpr); } catch (Exception ex) { useFallback = true; Log.warn(ex, "Failed to execute formula %s", expr); return fallbackValue.get(); } } }