package org.simantics.scl.runtime.equations; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.simantics.scl.runtime.SCLContext; import org.simantics.scl.runtime.function.Function; import org.simantics.scl.runtime.tuple.Tuple0; import org.simantics.scl.runtime.tuple.Tuple2; import gnu.trove.map.hash.THashMap; import gnu.trove.procedure.TObjectObjectProcedure; public class TestEquationContext implements EquationContext { public static final boolean TRACE = true; THashMap values = new THashMap(); THashMap> listenerMap = new THashMap>(); @Override public void listenEquationVariable(String variableName, Function listener) { if(TRACE) System.out.println("listenEquationVariable(" + variableName + ", " + listener + ")"); if(values.containsKey(variableName)) { Object value = values.get(variableName); if(TRACE) System.out.println(" apply " + value); listener.apply(value); } else { if(TRACE) System.out.println(" add listener"); ArrayList listeners = listenerMap.get(variableName); if(listeners == null) { listeners = new ArrayList(); listenerMap.put(variableName, listeners); } listeners.add(listener); } } @Override public void setEquationVariable(String variableName, Object value) { if(TRACE) System.out.println("setEquationVariable(" + variableName + ", " + value + ")"); if(values.containsKey(variableName)) throw new IllegalStateException("Value for " + variableName + " already defined (oldValue=" + values.get(variableName) + ", newValue=" + value + ")."); values.put(variableName, value); ArrayList listeners = listenerMap.remove(variableName); SCLContext context = SCLContext.getCurrent(); if(listeners != null) { Object oldEquationContex = context.put("equation", this); try { for(Function listener : listeners) { if(TRACE) System.out.println(" apply " + listener + " " + value); listener.apply(value); } } finally { context.put("equation", oldEquationContex); } } } public static List solveEquations(Function f) { TestEquationContext equationContext = new TestEquationContext(); SCLContext context = SCLContext.getCurrent(); Object oldEquationContext = context.put("equation", equationContext); try { f.apply(Tuple0.INSTANCE); } finally { context.put("equation", oldEquationContext); } ArrayList result = new ArrayList(equationContext.values.size()); equationContext.values.forEachEntry(new TObjectObjectProcedure() { @Override public boolean execute(String a, Object b) { result.add(new Tuple2(a, String.valueOf(b))); return true; } }); Collections.sort(result, (t1, t2) -> { return ((String)t1.c0).compareTo((String)t2.c0); }); return result; } public THashMap getValues() { return values; } }