Commit cb5e1e6b authored by Nico Mack's avatar Nico Mack
Browse files

Added additional Trace logging. Improved handling of notification

suspension. Moved variable value class variable into Variable class
parent 53ed2271
......@@ -48,7 +48,7 @@ public class InputEvent extends EventObject {
* @param tick
* The turn index the event was triggered at.
*/
public InputEvent(Variable source, long tick) {
public InputEvent(Variable<?> source, long tick) {
super(source);
this.tick = tick;
}
......@@ -59,7 +59,7 @@ public class InputEvent extends EventObject {
* @param source
* The source of the event.
*/
public InputEvent(Variable source) {
public InputEvent(Variable<?> source) {
super(source);
this.tick = -1;
}
......@@ -72,4 +72,9 @@ public class InputEvent extends EventObject {
public long getTick() {
return tick;
}
@Override
public Variable<?> getSource() {
return (Variable<?>) this.source;
}
}
\ No newline at end of file
......@@ -46,10 +46,10 @@ import javax.script.ScriptEngine;
*/
@NonNullByDefault
public class Equation {
private String name;
private Mapping mapping;
private Mapping lockedMapping;
@Nullable
// private ScriptEngine scriptEngine;
private Executor scriptExecutor;
private String script;
......@@ -65,7 +65,8 @@ public class Equation {
* the variables in the script must coincide with the names of the variables in the
* mapping.
*/
public Equation(Mapping mapping, String script) {
public Equation(String name, Mapping mapping, String script) {
this.name = name;
this.mapping = mapping;
this.lockedMapping = mapping;
this.script = script;
......@@ -85,14 +86,6 @@ public class Equation {
* mapping.
*/
public void evaluate() {
// Preconditions.checkState(scriptEngine != null);
// try {
// mapping.getDependentVariable().setValue(scriptEngine.eval(replaceVariables()));
// } catch (ScriptException e) {
// Logger.getLogger(Equation.class.getSimpleName()).log(Level.SEVERE, "Exception while
// executing script!", e); //$NON-NLS-1$
// }
LinkedHashSet<Variable<?>> dependentVariables;
String evaluationErrors;
......@@ -117,7 +110,7 @@ public class Equation {
consolidatedListeners = new HashMap<>();
for (Variable<?> variable : dependentVariables) {
variable.setConsolidated(consolidated);
variable.suspendListenerNotification(consolidated);
if (consolidated)
consolidatedListeners = variable.consolidateListeners(consolidatedListeners);
try {
......@@ -125,7 +118,7 @@ public class Equation {
} catch (Exception exception) {
LOGGER.error("Error while retrieving variable {}", variable.getName(), exception); //$NON-NLS-1$
}
variable.setConsolidated(false);
variable.suspendListenerNotification(false);
}
if (consolidated && consolidatedListeners != null) {
......@@ -147,35 +140,6 @@ public class Equation {
}
}
/**
* Method used to replace variables with their actual values in the formula.
*
* @return The formula with variables replaced by their values, ready for evaluation.
*/
// private String replaceVariables() {
// String result = new String(script);
//
// for (Variable variable : lockedMapping.getIndependentVariables()) {
// result = result.replaceAll(variable.getName(), variable.getValue().toString());
// }
//
// for (Variable variable : lockedMapping.getDependentVariables()) {
// result = result.replaceAll(variable.getName(), variable.getValue().toString());
// }
//
// assert result != null;
// return result;
// }
/**
* Method for setting the script engine to use.
*
* @param engine
* The {@link ScriptEngine} instance to use for evaluating the scripted formulas.
*/
// public void setScriptEngine(ScriptEngine engine) {
// scriptEngine = engine;
// }
/**
* Method for setting the script engine to use.
*
......@@ -207,17 +171,8 @@ public class Equation {
lockedMapping = mapping.lock();
}
// /**
// * Method used to update the mapping with a variable, that is, to update the reference to a
// * variable so that the mapping will correctly map all changes of the variable. <br>
// * <br>
// * <u>Note:</u> This method depends on the equality of variables being by name and unit.
// *
// * @param variable
// * The variable to update the reference for.
// * @see Variable#equals(Object)
// */
// public void updateMapping(Variable variable) {
// mapping.updateVariableReference(variable);
// }
@Override
public String toString() {
return this.name;
}
}
\ No newline at end of file
......@@ -635,7 +635,7 @@ public class EquationSystemBuilder {
Mapping variableMapping = new Mapping(equationInputs, equationOutputs);
final LinearEquationSystem equationSystem = new LinearEquationSystem(lockToNesting);
Equation newEquation = new Equation(variableMapping, script);
Equation newEquation = new Equation(equationName, variableMapping, script);
newEquation.setExecutor(executors.get(executor));
equationSystem.addEquation(newEquation);
......
......@@ -22,10 +22,12 @@ package lu.list.itis.dkd.tui.cps.system;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.variable.Variable;
import com.google.common.base.Preconditions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.ConcurrentHashMap;
/**
......@@ -42,6 +44,8 @@ public class LinearEquationSystem extends System {
private ConcurrentHashMap<Mapping, Equation> equations;
// private ScriptEngine scriptEngine;
private static final Logger LOGGER = LoggerFactory.getLogger(LinearEquationSystem.class.getSimpleName());
/**
* Constructor issuing a super call and initialising the map of equations.
*
......@@ -76,6 +80,9 @@ public class LinearEquationSystem extends System {
@Override
public synchronized void clockTicked(long tick) {
super.clockTicked(tick);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Clock tick at {}...", tick); //$NON-NLS-1$
}
for (Equation equation : equations.values()) {
equation.evaluate();
......@@ -92,7 +99,10 @@ public class LinearEquationSystem extends System {
super.inputChanged(input);
for (Equation equation : equations.values()) {
if (equation.catersTo((Variable<?>) input.getSource())) {
if (equation.catersTo(input.getSource())) {
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Equation {} triggered by variable {}...", equation.toString(), input.getSource().getName()); //$NON-NLS-1$
}
equation.evaluate();
}
}
......
......@@ -63,7 +63,7 @@ public class PythonExecutor extends Executor {
}
engine.set(variable.getName(), array);
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), list.toString()); //$NON-NLS-1$
LOGGER.trace("Parameter -> {} = {}", variable.getName(), list.toString()); //$NON-NLS-1$
}
}
} else {
......@@ -71,7 +71,7 @@ public class PythonExecutor extends Executor {
Double numericValue = Double.valueOf(variable.getValue().toString());
engine.set(variable.getName(), new PyFloat(numericValue));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
LOGGER.trace("Parameter -> {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
}
......@@ -82,7 +82,7 @@ public class PythonExecutor extends Executor {
engine.exec(script);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval => {} | took {} ms!", script, elapsed); //$NON-NLS-1$
LOGGER.trace("Eval took {} ms | {}", elapsed, script); //$NON-NLS-1$
}
return true;
}
......@@ -97,13 +97,13 @@ public class PythonExecutor extends Executor {
PyTuple tuple = (PyTuple) engine.get(tupleMatcher.group(1));
result = tuple.__getattr__(tupleMatcher.group(2));
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}.{} = {}", variable.getName(), tupleMatcher.group(1), tupleMatcher.group(2), result); //$NON-NLS-1$
LOGGER.trace("Result <- {} = {}.{} = {}", variable.getName(), tupleMatcher.group(1), tupleMatcher.group(2), result); //$NON-NLS-1$
}
}
} else {
result = engine.get(variable.getName());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result {} = {}", variable.getName(), result); //$NON-NLS-1$
LOGGER.trace("Result <- {} = {}", variable.getName(), result); //$NON-NLS-1$
}
}
......
......@@ -293,7 +293,7 @@ public class SqlExecutor extends Executor {
public void set(Variable<?> variable) {
parameters.put(variable.getName(), variable.getValue());
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Parameter {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
LOGGER.trace("Parameter -> {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
}
......@@ -302,6 +302,7 @@ public class SqlExecutor extends Executor {
/** {@inheritDoc} */
@Override
public boolean eval(String script) {
long elapsed = System.currentTimeMillis();
Connection connection = this.getConnectionFromPool();
List<String> variables = new ArrayList<String>();
String queryString = this.interpolate(script, variables, false);
......@@ -318,6 +319,11 @@ public class SqlExecutor extends Executor {
columnNames = this.getColumnNames(rows);
columnTypes = this.getColumnTypes(rows);
columnValues = this.convertResults(rows);
elapsed = System.currentTimeMillis() - elapsed;
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Eval took {} ms | {}", elapsed, script); //$NON-NLS-1$
}
} catch (SQLException e) {
LOGGER.error("Failed to execute query!", e); //$NON-NLS-1$
success = false;
......@@ -366,10 +372,13 @@ public class SqlExecutor extends Executor {
if (variable instanceof VectorVariable) {
VectorVariable<?> vector = (VectorVariable<?>) variable;
// Suspend notification of input change listeners while populating vector
variable.suspendListenerNotification(true);
for (Object[] values : columnValues) {
Object value = values[index];
vector.add(value);
}
variable.suspendListenerNotification(false);
vector.notifyInputChangeListeners();
} else {
LOGGER.warn("Query returned multiple rows but specified variable {} is scalar!", variable.getName()); //$NON-NLS-1$
......@@ -380,6 +389,9 @@ public class SqlExecutor extends Executor {
variable.setValueFromObject(values[index]);
}
}
if (LOGGER.isTraceEnabled()) {
LOGGER.trace("Result <- {} = {}", variable.getName(), variable.getValue()); //$NON-NLS-1$
}
return variable;
}
......
......@@ -20,7 +20,6 @@
*/
package lu.list.itis.dkd.tui.cps.variable;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import org.slf4j.Logger;
......@@ -35,8 +34,6 @@ import java.util.Vector;
*/
public class BooleanVariable extends Variable<Boolean> {
protected boolean value;
/**
* @param name
* @param value
......@@ -49,19 +46,6 @@ public class BooleanVariable extends Variable<Boolean> {
this.value = value;
}
/** {@inheritDoc} */
@Override
public Boolean getValue() {
return value;
}
/** {@inheritDoc} */
@Override
public void setValue(Boolean newValue) {
this.value = newValue;
this.notifyInputChangeListeners(new InputEvent(this));
}
/** {@inheritDoc} */
@Override
public void setValueFromObject(Object object) {
......
......@@ -22,7 +22,6 @@ package lu.list.itis.dkd.tui.cps.variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import org.slf4j.Logger;
......@@ -41,7 +40,6 @@ import java.util.Vector;
*/
@NonNullByDefault
public class NumericalVariable extends Variable<Double> {
protected double value;
protected double minValue;
protected double maxValue;
protected double scale;
......@@ -151,13 +149,11 @@ public class NumericalVariable extends Variable<Double> {
// Double newValue;
// newValue = (Double) this.valueFromString(value.toString());
if (newValue < this.minValue)
this.value = this.minValue;
newValue = this.minValue;
else if (newValue > this.maxValue)
this.value = this.maxValue;
else
this.value = newValue;
newValue = this.maxValue;
this.notifyInputChangeListeners(new InputEvent(this));
super.setValue(newValue);
}
/** {@inheritDoc} */
......
......@@ -14,7 +14,6 @@
package lu.list.itis.dkd.tui.cps.variable;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import lu.list.itis.dkd.tui.utility.Point;
......@@ -32,8 +31,6 @@ import java.util.regex.Pattern;
*/
public class SpatialVariable extends Variable<Point> {
private Point point;
private static final Logger LOGGER = LoggerFactory.getLogger(SpatialVariable.class.getSimpleName());
private static final Pattern SPATIAL_STRING_PATTERN = Pattern.compile("([0-9]+\\.?[0-9]*)\\s*,\\s*([0-9]+\\.?[0-9]*)(\\s*,\\s*([0-9]+\\.?[0-9]*))?", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
......@@ -45,7 +42,7 @@ public class SpatialVariable extends Variable<Point> {
*/
public SpatialVariable(String name, String unit, Point value) {
super(Externalization.SPATIAL_TYPE, name, unit);
this.point = value;
this.value = value;
}
/**
......@@ -56,7 +53,7 @@ public class SpatialVariable extends Variable<Point> {
*/
@Override
public int hashCode() {
return this.point.hashCode();
return this.value.hashCode();
}
/**
......@@ -75,25 +72,13 @@ public class SpatialVariable extends Variable<Point> {
if (object instanceof SpatialVariable) {
SpatialVariable variable = (SpatialVariable) object;
if (name.equals(variable.getName()) && unit.equals(variable.getUnit()) && variable.getValue().equals(point)) {
if (name.equals(variable.getName()) && unit.equals(variable.getUnit()) && variable.getValue().equals(value)) {
return true;
}
}
return false;
}
/** {@inheritDoc} */
@Override
public Point getValue() {
return this.point;
}
/** {@inheritDoc} */
@Override
public void setValue(Point value) {
this.point = value;
this.notifyInputChangeListeners(new InputEvent(this));
}
/** {@inheritDoc} */
@Override
......@@ -104,7 +89,7 @@ public class SpatialVariable extends Variable<Point> {
/** {@inheritDoc} */
@Override
public Variable<Point> clone() {
SpatialVariable variable = new SpatialVariable(name, unit, point);
SpatialVariable variable = new SpatialVariable(name, unit, value);
variable.listeners = new Vector<>(listeners);
return variable;
}
......
......@@ -22,7 +22,6 @@ package lu.list.itis.dkd.tui.cps.variable;
import lu.list.itis.dkd.dbc.annotation.NonNullByDefault;
import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.InputEvent;
import lu.list.itis.dkd.tui.cps.utility.Externalization;
import org.slf4j.Logger;
......@@ -40,7 +39,6 @@ import java.util.Vector;
*/
@NonNullByDefault
public class TextVariable extends Variable<String> {
protected String value;
private static final Logger logger = LoggerFactory.getLogger(TextVariable.class.getSimpleName());
......@@ -106,12 +104,6 @@ public class TextVariable extends Variable<String> {
return false;
}
/** {@inheritDoc} */
@Override
public void setValue(String newValue) {
this.value = newValue;
this.notifyInputChangeListeners(new InputEvent(this));
}
/** {@inheritDoc} */
@Override
......@@ -119,13 +111,6 @@ public class TextVariable extends Variable<String> {
this.setValue(this.valueFromObject(object));
}
/** {@inheritDoc} */
@Override
public String getValue() {
return this.value;
}
/** {@inheritDoc} */
@Override
public TextVariable clone() {
......
......@@ -25,6 +25,9 @@ import lu.list.itis.dkd.dbc.annotation.Nullable;
import lu.list.itis.dkd.tui.cps.InputChangeListener;
import lu.list.itis.dkd.tui.cps.InputEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Vector;
......@@ -49,10 +52,14 @@ public abstract class Variable<V> implements Cloneable {
/** The listeners to notify when the variable changes value. */
protected Vector<InputChangeListener> listeners;
protected boolean listenersConsolidated = false;
protected V value;
protected int suspendNotificationSemaphore = 0;
public static final String NO_UNIT = ""; //$NON-NLS-1$
private static final Logger LOGGER = LoggerFactory.getLogger(Variable.class.getSimpleName());
/**
* Constructor initialising the name and unit fields.
*
......@@ -95,12 +102,19 @@ public abstract class Variable<V> implements Cloneable {
return unit;
}
@SuppressWarnings("unchecked")
public V getContentClass() {
return (V) value.getClass();
}
/**
* Simple getter method for the value held by the {@link Variable} instance.
*
* @return The value held by the {@link Variable} instance.
*/
public abstract V getValue();
public V getValue() {
return value;
}
/**
* Method used to set the value held by the variable.
......@@ -108,7 +122,10 @@ public abstract class Variable<V> implements Cloneable {
* @param value
* The new value the variable should have.
*/
public abstract void setValue(V value);
public void setValue(V newValue) {
this.value = newValue;
this.notifyInputChangeListeners(new InputEvent(this));
}
/**
* Method used to set the value held by the variable from an object.
......@@ -183,16 +200,24 @@ public abstract class Variable<V> implements Cloneable {
}
/**
* Sets the consolidated flag for InputChangeListeners. When consolidated, InputChangeListeners
* will not be notified on value changes.
* Sets the suspendNotification flag for InputChangeListeners. When suspend,
* InputChangeListeners will not be notified on value changes.
*
* @param consolidate
* specify <code>true</true> to switch variable in consolidated mode, <code>false</code>
* to enable notification of InputChangeListerners on value change.
* @param suspend
* specify <code>true</true> to suspend listener notification, <code>false</code> to
* enable notification of InputChangeListerners on value change.
* @see #consolidateListeners
*/
public void setConsolidated(boolean consolidate) {
listenersConsolidated = consolidate;
public synchronized void suspendListenerNotification(boolean suspend) {
if (suspend) {
suspendNotificationSemaphore++;
if (LOGGER.isTraceEnabled())
LOGGER.trace("Suspend Notification Semaphore of Variable {} raised to {}!", this.name, suspendNotificationSemaphore); //$NON-NLS-1$
} else if (suspendNotificationSemaphore > 0) {
suspendNotificationSemaphore--;
if (LOGGER.isTraceEnabled())
LOGGER.trace("Suspend Notification Semaphore of Variable {} lowered to {}!", this.name, suspendNotificationSemaphore); //$NON-NLS-1$
}
}
/**
......@@ -220,8 +245,13 @@ public abstract class Variable<V> implements Cloneable {
* specifies the event to be passed to each listeners inputChanged method.
*/
protected void notifyInputChangeListeners(InputEvent event) {
if (listenersConsolidated)
if (suspendNotificationSemaphore > 0) {
// if (LOGGER.isTraceEnabled())
// LOGGER.trace("Notification suspend for Variable {}! Semaphore was {}!", this.name,
// suspendNotificationSemaphore); //$NON-NLS-1$
return;
}
for (InputChangeListener listener : listeners) {
listener.inputChanged(event);
}
......
......@@ -30,24 +30,22 @@ import java.util.Vector;
*/
public class VectorVariable<B> extends Variable<List<B>> implements Collection<B> {
private List<B> values;
public VectorVariable(String name, String unit) {
super(Externalization.VECTOR_TYPE, name, unit);
values = new ArrayList<B>();
value = new ArrayList<B>();
}
/** {@inheritDoc} */
@Override
public List<B> getValue() {
return values;
return value;
}
/** {@inheritDoc} */
@Override
public void setValue(List<B> values) {
this.values.clear();
this.values.addAll(values);
this.value.clear();
this.value.addAll(values);
this.notifyInputChangeListeners(new InputEvent(this));
}
......@@ -56,87 +54,93 @@ public class VectorVariable<B> extends Variable<List<B>> implements Collection<B