X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.diagram%2Fsrc%2Forg%2Fsimantics%2Fdiagram%2Fprofile%2FStyleBase.java;h=fee1e8546d7e96e07bf13a21f53b98f26afac6c4;hp=ee203616da950f31d0fa1f1abbfae793de988f2d;hb=HEAD;hpb=e25e99231e398b1133a39e1d786928cfd842b446 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 ee203616d..fee1e8546 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; @@ -32,8 +27,10 @@ import org.simantics.db.layer0.variable.Variable; import org.simantics.db.procedure.Listener; import org.simantics.db.request.Read; import org.simantics.diagram.stubs.DiagramResource; +import org.simantics.g2d.canvas.Hints; import org.simantics.g2d.canvas.ICanvasContext; import org.simantics.g2d.diagram.IDiagram; +import org.simantics.g2d.diagram.handler.DataElementMap; import org.simantics.g2d.element.IElement; import org.simantics.scenegraph.INode; import org.simantics.scenegraph.profile.DataNodeMap; @@ -44,10 +41,8 @@ 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; -import org.simantics.utils.threads.AWTThread; /** * For most style implementations it should be enough to override the following @@ -73,14 +68,58 @@ import org.simantics.utils.threads.AWTThread; */ public abstract class StyleBase implements Style { - protected final Map values = new ConcurrentHashMap(); + private Object identity; + private double priority; -// private Map listeners = new ConcurrentHashMap(); + public StyleBase(Object identity) { + this.identity = identity; + } + + public StyleBase() { + this.identity = getClass(); + } + + @SuppressWarnings("unchecked") + protected T getIdentity() { + return (T)identity; + } - private Map, ObserverGroupListener> listeners = new HashMap, ObserverGroupListener>(); + public void setPriority(double priority) { + this.priority = priority; + } + + public double getPriority() { + return priority; + } + @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; + } - private final List removals = new ArrayList(); + protected Resource getResource() { + return getIdentity(); + } /** * For caching this simple base request that is done in every @@ -176,10 +215,10 @@ 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); - observer.update(); + StyleBaseData.getInstance().putValue(new Tuple3(this, runtimeDiagram, object), result); + observer.update(this, object); } /** @@ -204,7 +243,7 @@ public abstract class StyleBase implements Style { final INode node = map.getNode(item); if (node == null) { - evaluationContext.update(); + evaluationContext.update(this, item); // TODO: continue or return? return; } @@ -213,7 +252,6 @@ public abstract class StyleBase implements Style { System.out.println(StyleBase.this + ": applying style for item " + item + " and element " + node + " with result " + value); applyStyleForNode(evaluationContext, node, value); - } /** @@ -284,9 +322,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); @@ -298,7 +334,7 @@ public abstract class StyleBase implements Style { * @see org.simantics.diagram.profile.Style#activate(org.simantics.db.RequestProcessor, org.simantics.db.Resource, org.simantics.db.layer0.variable.Variable, org.simantics.diagram.profile.Group, org.simantics.diagram.profile.Observer) */ @Override - public final void activate(RequestProcessor backend, final Resource runtimeDiagram, final Resource entry, final Group group, final EvaluationContext observer) { + public final void activate(RequestProcessor backend, final Resource runtimeDiagram, final Resource entry, final Group group, final EvaluationContext observer) throws DatabaseException { ObserverGroupListener listener = getListener(runtimeDiagram, group); @@ -309,7 +345,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); @@ -391,7 +427,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! @@ -400,7 +436,8 @@ public abstract class StyleBase implements Style { cleanupItems(observer, diagram, listener.getItems().toArray()); diagram = null; } - observer.update(); + + //observer.update(); TODO: Check if this is required! } } @@ -410,7 +447,6 @@ public abstract class StyleBase implements Style { */ @Override public final void apply(Resource entry, Group group, final EvaluationContext evaluationContext) { - ICanvasContext context = evaluationContext.getConstant(ProfileKeys.CANVAS); assert context.getThreadAccess().currentThreadAccess(); @@ -426,24 +462,45 @@ 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); + + IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM); + assert diagram != null; + DataElementMap emap = diagram.getDiagramClass().getSingleItem(DataElementMap.class); + 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); + + IElement element = emap.getElement(diagram, item); + if (element != null) + element.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY); } } + @Override + public final void apply2(Object item, final EvaluationContext evaluationContext) { + final DataNodeMap map = evaluationContext.getConstant(ProfileKeys.NODE_MAP); + + StyleBaseData data = StyleBaseData.getInstance(); + + data.applyRemovals(evaluationContext, this); + + Result value = data.getValue(new Tuple3(this, evaluationContext.getResource(), item)); + applyStyleForItem(evaluationContext, map, item, value); + + IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM); + assert diagram != null; + DataElementMap emap = diagram.getDiagramClass().getSingleItem(DataElementMap.class); + IElement element = emap.getElement(diagram, item); + if (element != null) + element.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY); + } + /** * This is ran when this profile entry gets deactivated after being first * active. It allows cleaning up scene graph left-overs for the listened set @@ -473,15 +530,23 @@ public abstract class StyleBase implements Style { if (DebugPolicy.DEBUG_PROFILE_STYLE_ACTIVATION) System.out.println(this + ".cleanupItems(" + evaluationContext + ", " + diagram + ", " + Arrays.toString(items)); + IDiagram diagram = evaluationContext.getConstant(ProfileKeys.DIAGRAM); + assert diagram != null; + DataElementMap emap = diagram.getDiagramClass().getSingleItem(DataElementMap.class); + for (Object item : items) { cleanupStyleForItem(evaluationContext, map, item); + + IElement element = emap.getElement(diagram, item); + if (element != null) + element.setHint(Hints.KEY_DIRTY, Hints.VALUE_SG_DIRTY); } } }); } private ObserverGroupListener getListener(Resource runtime, Group group) { - return listeners.get(Pair.make(runtime, group)); + return StyleBaseData.getInstance().getListener(new Tuple3(this, runtime, group)); } }