From ab9fcfe016ef75da40eb00a46d4a54b50e534511 Mon Sep 17 00:00:00 2001 From: Antti Villberg Date: Wed, 26 Sep 2018 06:53:54 +0200 Subject: [PATCH] Fix diagram profiles to work with latest DB changes gitlab #96 Change-Id: I799c1f22422126290aed0868d6fe4ceed6bccaa9 --- .../simantics/diagram/adapter/TypeGroup.java | 24 +++++- .../profile/ResourceSCLTextGridStyle.java | 13 ++- .../diagram/profile/SCLTextGridStyle.java | 11 ++- .../simantics/diagram/profile/StyleBase.java | 82 +++++++++++------- .../diagram/profile/StyleBaseData.java | 86 +++++++++++++++++++ .../diagram/profile/TextGridStyle.java | 62 +++++++++---- 6 files changed, 215 insertions(+), 63 deletions(-) create mode 100644 bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java index e025fb2dd..b7b4ba2ff 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/TypeGroup.java @@ -1,5 +1,5 @@ /******************************************************************************* - * 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 @@ -39,7 +39,7 @@ public class TypeGroup implements Group { private final String name; public TypeGroup(String name, Resource type) { - this(name); + this(name, new Resource[] { type }); } public TypeGroup(String name, Resource... types) { @@ -47,6 +47,26 @@ public class TypeGroup implements Group { 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. * diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java index 3bbbf8081..c9a83ff8b 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/ResourceSCLTextGridStyle.java @@ -23,13 +23,12 @@ import org.simantics.utils.datastructures.Pair; */ 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 { @@ -51,7 +50,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { @Override protected Object getIdentity(Resource entry) { - return new Pair(style, entry); + return new Pair(getResource(), entry); } @Override @@ -63,10 +62,10 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { 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 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); @@ -79,7 +78,7 @@ public class ResourceSCLTextGridStyle extends TextGridStyle { @Override public String getNodeName() { - return "" + style.getResourceId(); + return "" + getResource().getResourceId(); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java index 4401f2213..16b205388 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/SCLTextGridStyle.java @@ -25,13 +25,12 @@ import org.simantics.utils.datastructures.Pair; */ 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 { @@ -53,7 +52,7 @@ public class SCLTextGridStyle extends TextGridStyle { @Override protected Object getIdentity(Resource entry) { - return new Pair(style, entry); + return new Pair(getResource(), entry); } @Override @@ -81,7 +80,7 @@ public class SCLTextGridStyle extends TextGridStyle { if (moduleVariable == null) return null; - Variable styleVariable = Variables.getVariable(graph, style); + Variable styleVariable = Variables.getVariable(graph, getResource()); Function1 function = styleVariable.getPossiblePropertyValue(graph, DIA.SCLTextGridStyle_texts); Tuple3 result = Simantics.applySCLRead(graph, function, moduleVariable); @@ -97,7 +96,7 @@ public class SCLTextGridStyle extends TextGridStyle { @Override public String getNodeName() { - return "" + style.getResourceId(); + return "" + getResource().getResourceId(); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java index 21071ba74..e1d8b1fbf 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBase.java @@ -11,12 +11,7 @@ *******************************************************************************/ 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; @@ -44,8 +39,7 @@ import org.simantics.scenegraph.profile.Style; 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; /** @@ -72,14 +66,48 @@ import org.simantics.utils.datastructures.Pair; */ public abstract class StyleBase implements Style { - protected final Map values = new ConcurrentHashMap(); + private Object identity; -// private Map listeners = new ConcurrentHashMap(); + public StyleBase(Object identity) { + this.identity = identity; + } - private Map, ObserverGroupListener> listeners = new HashMap, ObserverGroupListener>(); - + public StyleBase() { + this.identity = getClass(); + } - private final List removals = new ArrayList(); + protected 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 @@ -175,9 +203,9 @@ public abstract class StyleBase implements Style { */ 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(); } @@ -283,9 +311,7 @@ public abstract class StyleBase implements Style { 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); @@ -308,7 +334,7 @@ public abstract class StyleBase implements Style { listener = new GroupListener(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); @@ -390,7 +416,7 @@ public abstract class StyleBase implements Style { 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! @@ -425,19 +451,13 @@ public abstract class StyleBase implements Style { 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); } @@ -480,7 +500,7 @@ public abstract class StyleBase implements Style { } private ObserverGroupListener getListener(Resource runtime, Group group) { - return listeners.get(Pair.make(runtime, group)); + return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group)); } } diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java new file mode 100644 index 000000000..ca97fea78 --- /dev/null +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/StyleBaseData.java @@ -0,0 +1,86 @@ +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 values = new ConcurrentHashMap<>(); + + private Map listeners = new HashMap<>(); + + private final Map> 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 getValue(Tuple t) { + return (T) values.get(t); + } + + public synchronized void removeItem(Style s, Resource r) { + List 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 rs = removals.remove(s); + if (rs == null) + return; + + DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP); + + for (Resource item : rs) { + s.cleanupStyleForItem(evaluationContext, map, item); + } + } + +} diff --git a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java index 54972155d..997ace1d6 100644 --- a/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java +++ b/bundles/org.simantics.diagram/src/org/simantics/diagram/profile/TextGridStyle.java @@ -38,17 +38,15 @@ public abstract class TextGridStyle extends StyleBase { 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; } @@ -175,29 +173,32 @@ public abstract class TextGridStyle extends StyleBase { // 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); @@ -361,18 +362,45 @@ public abstract class TextGridStyle extends StyleBase { @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(); + } + } -- 2.47.1