/*******************************************************************************
- * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * Copyright (c) 2007, 2018 Association for Decentralized Information Management
* in Industry THTH ry.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
private final String name;
public TypeGroup(String name, Resource type) {
- this(name);
+ this(name, new Resource[] { type });
}
public TypeGroup(String name, Resource... types) {
this.name = name;
}
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + types.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TypeGroup other = (TypeGroup) obj;
+ return types.equals(other.types);
+ }
+
/**
* Initialize TypeGroup from a DIAGRAM.Group instance.
*
*/
public class ResourceSCLTextGridStyle extends TextGridStyle {
- final Resource style;
final Font font;
public ResourceSCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
- this.style = style;
+ super(style);
G2DResource G2D = G2DResource.getInstance(graph);
- Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
+ Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
if(fontR != null) {
font = G2DUtils.getFont(graph, fontR);
} else {
@Override
protected Object getIdentity(Resource entry) {
- return new Pair<Resource, Resource>(style, entry);
+ return new Pair<Resource, Resource>(getResource(), entry);
}
@Override
public MonitorTextGridResult calculateStyle(ReadGraph graph, Resource runtimeDiagram, Resource entry, Resource element, Variable configuration) throws DatabaseException {
DiagramResource DIA = DiagramResource.getInstance(graph);
- Variable styleVariable = Variables.getVariable(graph, style);
+ Variable styleVariable = Variables.getVariable(graph, getResource());
Function1<Resource,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.ResourceSCLTextGridStyle_texts);
Tuple3 result = Simantics.applySCLRead(graph, function, element);
-
+
AffineTransform transform = DiagramGraphUtil.getAffineTransform(graph, element);
Vec2d offset = DiagramGraphUtil.getOffset(graph, element);
boolean enabled = !DiagramGraphUtil.getProfileMonitorsHidden(graph, element);
@Override
public String getNodeName() {
- return "" + style.getResourceId();
+ return "" + getResource().getResourceId();
}
}
*/
public class SCLTextGridStyle extends TextGridStyle {
- final Resource style;
final Font font;
public SCLTextGridStyle(ReadGraph graph, Resource style) throws DatabaseException {
- this.style = style;
+ super(style);
G2DResource G2D = G2DResource.getInstance(graph);
- Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
+ Resource fontR = graph.getPossibleObject(style, G2D.HasFont);
if(fontR != null) {
font = G2DUtils.getFont(graph, fontR);
} else {
@Override
protected Object getIdentity(Resource entry) {
- return new Pair<Resource, Resource>(style, entry);
+ return new Pair<Resource, Resource>(getResource(), entry);
}
@Override
if (moduleVariable == null)
return null;
- Variable styleVariable = Variables.getVariable(graph, style);
+ Variable styleVariable = Variables.getVariable(graph, getResource());
Function1<Variable,Tuple3> function = styleVariable.getPossiblePropertyValue(graph, DIA.SCLTextGridStyle_texts);
Tuple3 result = Simantics.applySCLRead(graph, function, moduleVariable);
@Override
public String getNodeName() {
- return "" + style.getResourceId();
+ return "" + getResource().getResourceId();
}
}
*******************************************************************************/
package org.simantics.diagram.profile;
-import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
import org.simantics.databoard.Bindings;
import org.simantics.db.ReadGraph;
import org.simantics.scenegraph.profile.common.ObserverGroupListener;
import org.simantics.scenegraph.profile.common.ObserverGroupValueListener;
import org.simantics.scenegraph.profile.impl.DebugPolicy;
-import org.simantics.scl.runtime.tuple.Tuple;
-import org.simantics.scl.runtime.tuple.Tuple2;
+import org.simantics.scl.runtime.tuple.Tuple3;
import org.simantics.utils.datastructures.Pair;
/**
*/
public abstract class StyleBase<Result> implements Style {
- protected final Map<Tuple, Result> values = new ConcurrentHashMap<Tuple, Result>();
+ private Object identity;
-// private Map<Resource,ObserverGroupListener> listeners = new ConcurrentHashMap<Resource, ObserverGroupListener>();
+ public StyleBase(Object identity) {
+ this.identity = identity;
+ }
- private Map<Pair<Resource, Group>, ObserverGroupListener> listeners = new HashMap<Pair<Resource, Group>, ObserverGroupListener>();
-
+ public StyleBase() {
+ this.identity = getClass();
+ }
- private final List<Resource> removals = new ArrayList<Resource>();
+ protected <T> T getIdentity() {
+ return (T)identity;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((identity == null) ? 0 : identity.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ StyleBase other = (StyleBase) obj;
+ if (identity == null) {
+ if (other.identity != null)
+ return false;
+ } else if (!identity.equals(other.identity))
+ return false;
+ return true;
+ }
+
+ protected Resource getResource() {
+ return getIdentity();
+ }
/**
* For caching this simple base request that is done in every
*/
public void styleResultChanged(Observer observer, Resource runtimeDiagram, Resource object, Result result) {
if (result == null)
- values.remove(new Tuple2(runtimeDiagram, object));
+ StyleBaseData.getInstance().removeValue(new Tuple3(this, runtimeDiagram, object));
else
- values.put(new Tuple2(runtimeDiagram, object), result);
+ StyleBaseData.getInstance().putValue(new Tuple3(this, runtimeDiagram, object), result);
observer.update();
}
if (DebugPolicy.DEBUG_PROFILE_STYLE_GROUP_TRACKING)
System.out.println(style + ": removed from group " + group + ": " + item);
- synchronized (style.removals) {
- style.removals.add(item);
- }
+ StyleBaseData.getInstance().removeItem(style, item);
// TODO: do something here to dispose of ObserverGroupValueListeners?
super.remove(item);
listener = new GroupListener<Result>(backend.getSession(), runtimeDiagram, entry, this, group, observer);
- listeners.put(Pair.make(runtimeDiagram, group), listener);
+ StyleBaseData.getInstance().putListener(new Tuple3(this, runtimeDiagram, group), listener);
group.trackItems(backend, runtimeDiagram, listener);
listener.removeEntry(entry);
if (!listener.hasEntries()) {
listener.dispose();
- listeners.remove(Pair.make(runtimeDiagram, group));
+ StyleBaseData.getInstance().removeListener(new Tuple3(this, runtimeDiagram, group));
}
// This was too eager when multiple groups were tracked!
if (DebugPolicy.DEBUG_PROFILE_STYLE_APPLICATION)
System.out.println(StyleBase.this + ": applying style for items: " + listener.getItems());
- if (!removals.isEmpty()) {
- Resource[] removed;
- synchronized (removals) {
- removed = removals.toArray(Resource.NONE);
- removals.clear();
- }
- for (Resource item : removed) {
- cleanupStyleForItem(evaluationContext, map, item);
- }
- }
+
+ StyleBaseData data = StyleBaseData.getInstance();
+
+ data.applyRemovals(evaluationContext, this);
for (Object item : listener.getItems()) {
- Result value = values.get(new Tuple2(evaluationContext.getResource(), item));
+ Result value = data.getValue(new Tuple3(this, evaluationContext.getResource(), item));
applyStyleForItem(evaluationContext, map, item, value);
}
}
private ObserverGroupListener getListener(Resource runtime, Group group) {
- return listeners.get(Pair.make(runtime, group));
+ return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group));
}
}
--- /dev/null
+package org.simantics.diagram.profile;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.simantics.db.Resource;
+import org.simantics.scenegraph.profile.DataNodeMap;
+import org.simantics.scenegraph.profile.EvaluationContext;
+import org.simantics.scenegraph.profile.Style;
+import org.simantics.scenegraph.profile.common.ObserverGroupListener;
+import org.simantics.scl.runtime.tuple.Tuple;
+import org.simantics.scl.runtime.tuple.Tuple3;
+
+public class StyleBaseData {
+
+ private static StyleBaseData INSTANCE;
+
+ protected final Map<Tuple, Object> values = new ConcurrentHashMap<>();
+
+ private Map<Tuple3, ObserverGroupListener> listeners = new HashMap<>();
+
+ private final Map<Style, List<Resource>> removals = new HashMap<>();
+
+ private StyleBaseData() {
+ }
+
+ public static StyleBaseData getInstance() {
+ if (INSTANCE == null) {
+ synchronized (StyleBaseData.class) {
+ if (INSTANCE == null) {
+ INSTANCE = new StyleBaseData();
+ }
+ }
+ }
+ return INSTANCE;
+ }
+
+ public void removeValue(Tuple t) {
+ values.remove(t);
+ }
+
+ public void putValue(Tuple t, Object o) {
+ values.put(t, o);
+ }
+
+ public <T> T getValue(Tuple t) {
+ return (T) values.get(t);
+ }
+
+ public synchronized void removeItem(Style s, Resource r) {
+ List<Resource> l = removals.get(s);
+ if (l == null) {
+ l = new ArrayList<>();
+ removals.put(s, l);
+ }
+ l.add(r);
+ }
+
+ public void putListener(Tuple3 key, ObserverGroupListener listener) {
+ listeners.put(key, listener);
+ }
+
+ public void removeListener(Tuple3 key) {
+ listeners.remove(key);
+ }
+
+ public ObserverGroupListener getListener(Tuple3 key) {
+ return listeners.get(key);
+ }
+
+ public synchronized void applyRemovals(EvaluationContext evaluationContext, StyleBase s) {
+ List<Resource> rs = removals.remove(s);
+ if (rs == null)
+ return;
+
+ DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP);
+
+ for (Resource item : rs) {
+ s.cleanupStyleForItem(evaluationContext, map, item);
+ }
+ }
+
+}
private final Color BACKGROUND_COLOR = new Color(255, 255, 255, 192);
private static final Rectangle2D EMPTY_BOUNDS = new Rectangle2D.Double(0, 0, 0, 0);
- // NOTE: this is a hack
- String id;
-
protected double xOffset;
protected double yOffset;
- public TextGridStyle() {
- this(0.0, 2.1);
+ public TextGridStyle(Resource r) {
+ this(r, 0.0, 2.1);
}
- public TextGridStyle(double xOffset, double yOffset) {
+ public TextGridStyle(Resource r, double xOffset, double yOffset) {
+ super(r);
this.xOffset = xOffset;
this.yOffset = yOffset;
}
// This assumes that this TextGridStyle instance will be devoted to
// this row ID until the end of its life.
- String id = result.getRowId();
- //System.out.println(this + " ID: " + id);
- if (!id.equals(this.id)) {
- //System.out.println(this + " SET ID: " + this.id + " -> " + id);
- this.id = id;
- }
+// String id = result.getRowId();
+// System.out.println(this + " ID: " + id);
+// if (!id.equals(this.id)) {
+// System.out.println(this + " SET ID: " + this.id + " -> " + id);
+// this.id = id;
+// }
Integer newRow = observer.getTemporaryProperty(_node, "location");
if (newRow == null)
newRow = 1;
// Remove from existing row to add to another row if necessary.
- Integer row = observer.getProperty(_node, id);
+ Integer row = getCurrentRowNumber(observer, _node);
if (row != null && row != newRow) {
String actualId = node.getRowId(row);
+ String id = observer.getProperty(_node, rowIdKey());
if (id.equals(actualId)) {
node.removeRow(row);
}
}
row = newRow;
- node.setRowId(row, id);
- observer.setProperty(_node, id, row);
+ node.setRowId(row, result.getRowId());
+
+ setCurrentRowNumber(observer, _node, result.getRowId(), row);
+
observer.setTemporaryProperty(_node, "location", row + 1);
node.setText(2, row, value2);
@Override
protected void cleanupStyleForNode(EvaluationContext observer, INode _node) {
- Integer row = observer.getProperty(_node, id);
+ Integer row = getCurrentRowNumber(observer, _node);
//System.out.println(this + " cleanup(" + id + ", " + row + ")");
//System.out.println(element);
if (row == null)
return;
- observer.setProperty(_node, id, null);
+ clearCurrentRowNumber(observer, _node);
TextGridNode node = ProfileVariables.browseChild(_node, "TextGridStyle");
if (node != null)
node.removeRow(row);
}
+ private Integer getCurrentRowNumber(EvaluationContext observer, INode _node) {
+ String rowId = observer.getProperty(_node, rowIdKey());
+ return observer.getProperty(_node, rowId);
+ }
+
+ private void setCurrentRowNumber(EvaluationContext observer, INode _node, String rowId, int row) {
+ // Mapping style identity -> rowId (resourceId)
+ observer.setProperty(_node, rowIdKey(), rowId);
+ // Mapping rowId (resourceId) -> row number
+ observer.setProperty(_node, rowId, row);
+ }
+
+ private void clearCurrentRowNumber(EvaluationContext observer, INode _node) {
+ String rowId = observer.getProperty(_node, rowIdKey());
+ if(rowId != null) {
+ observer.setProperty(_node, rowIdKey(), null);
+ Integer row = observer.getProperty(_node, rowId);
+ if(row != null) {
+ observer.setProperty(_node, rowId, null);
+ }
+ }
+ }
+
protected void postProcessNode(TextGridNode node, int row) {
}
+ private String rowIdKey() {
+ return "style" + getIdentity().toString();
+ }
+
}