]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.diagram/src/org/simantics/diagram/adapter/DefinedElementFactory.java
Merge branch 'feature/funcwrite'
[simantics/platform.git] / bundles / org.simantics.diagram / src / org / simantics / diagram / adapter / DefinedElementFactory.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.diagram.adapter;
13
14 import java.awt.Shape;
15 import java.awt.geom.AffineTransform;
16 import java.util.Collections;
17 import java.util.concurrent.ConcurrentLinkedQueue;
18 import java.util.concurrent.atomic.AtomicInteger;
19
20 import org.simantics.databoard.Bindings;
21 import org.simantics.db.AsyncReadGraph;
22 import org.simantics.db.Resource;
23 import org.simantics.db.common.procedure.adapter.ProcedureAdapter;
24 import org.simantics.db.common.procedure.adapter.TransientCacheAsyncListener;
25 import org.simantics.db.common.procedure.guarded.GuardedAsyncProcedureWrapper;
26 import org.simantics.db.common.request.BinaryAsyncRead;
27 import org.simantics.db.common.request.SafeName;
28 import org.simantics.db.procedure.AsyncMultiProcedure;
29 import org.simantics.db.procedure.AsyncProcedure;
30 import org.simantics.diagram.content.ResourceTerminal;
31 import org.simantics.diagram.stubs.DiagramResource;
32 import org.simantics.diagram.stubs.G2DResource;
33 import org.simantics.diagram.synchronization.SynchronizationHints;
34 import org.simantics.diagram.synchronization.graph.TransformSynchronizer;
35 import org.simantics.g2d.canvas.ICanvasContext;
36 import org.simantics.g2d.diagram.IDiagram;
37 import org.simantics.g2d.element.ElementClass;
38 import org.simantics.g2d.element.ElementUtils;
39 import org.simantics.g2d.element.IElement;
40 import org.simantics.g2d.element.handler.impl.DefaultTransform;
41 import org.simantics.g2d.element.handler.impl.ObjectTerminal;
42 import org.simantics.g2d.element.handler.impl.SimpleElementLayers;
43 import org.simantics.g2d.element.handler.impl.StaticObjectAdapter;
44 import org.simantics.g2d.element.handler.impl.StaticSymbolImageInitializer;
45 import org.simantics.g2d.element.handler.impl.StaticSymbolImpl;
46 import org.simantics.g2d.element.handler.impl.Terminals;
47 import org.simantics.g2d.element.handler.impl.TextImpl;
48 import org.simantics.g2d.elementclass.ImageClass;
49 import org.simantics.g2d.elementclass.PlainElementPropertySetter;
50 import org.simantics.g2d.tooltip.TerminalTooltipProvider;
51 import org.simantics.g2d.tooltip.TooltipParticipant;
52 import org.simantics.g2d.utils.geom.DirectionSet;
53 import org.simantics.structural.stubs.StructuralResource2;
54 import org.simantics.utils.Container;
55
56 /**
57  * @author Tuukka Lehtonen
58  * 
59  * TODO: not merged https://www.simulationsite.net/trac/simantics/changeset/14463/2d/trunk/org.simantics.diagram/src/org/simantics/diagram/adapter/GraphToDiagramSynchronizer.java
60  */
61 public class DefinedElementFactory extends ElementFactoryAdapter {
62
63     protected static class ShapeContainer implements Container<Shape> {
64
65         private IElement element;
66         private Shape shape = null;
67
68         public ShapeContainer(IElement element) {
69             this.element = element;
70         }
71
72         @Override
73         public Shape get() {
74             if(shape == null) {
75                 shape = ElementUtils.getElementShapeOrBounds(element);
76                 element = null;
77             }
78             return shape;
79         }
80
81     }
82
83
84     static class ClassRequest extends BinaryAsyncRead<Resource, ICanvasContext, ElementClass> {
85
86         final private IDiagram diagram;
87
88         public ClassRequest(Resource elementType, ICanvasContext canvas, IDiagram diagram) {
89             super(elementType, canvas);
90             this.diagram = diagram;
91         }
92
93         @Override
94         public void perform(AsyncReadGraph graph, AsyncProcedure<ElementClass> procedure) {
95
96             createzz(graph, parameter2, diagram, parameter, procedure);
97
98         }
99
100     }
101
102     @Override
103     public void create(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
104             final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
105
106         graph.asyncRequest(new ClassRequest(elementType, canvas, diagram), new TransientCacheAsyncListener<ElementClass>() {
107
108             @Override
109             public void exception(AsyncReadGraph graph, Throwable t) {
110                 t.printStackTrace();
111                 procedure.exception(graph, t);
112             }
113
114             @Override
115             public void execute(AsyncReadGraph graph, ElementClass result) {
116                 procedure.execute(graph, result);
117             }
118
119         });
120
121     }
122
123     public static void createzz(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram,
124             final Resource elementType, final AsyncProcedure<ElementClass> procedure) {
125
126         final StructuralResource2 sr = graph.getService(StructuralResource2.class);
127         final G2DResource g2d = graph.getService(G2DResource.class);
128         final DiagramResource dr = graph.getService(DiagramResource.class);
129
130         graph.forSingleObject(elementType, sr.IsDefinedBy, new AsyncProcedure<Resource>() {
131
132             @Override
133             public void exception(AsyncReadGraph graph, Throwable throwable) {
134              
135                 graph.asyncRequest(new SafeName(elementType), new ProcedureAdapter<String>() {
136                     @Override
137                     public void execute(String result) {
138                         System.out.println("DefinedElement '" + result + " ' does not have a single IsDefinedBy relation");
139                     }
140                 });
141              
142                 procedure.exception(graph, throwable);
143                 
144             }
145
146             @Override
147             public void execute(AsyncReadGraph graph, final Resource definingResource) {
148
149                 graph.asyncRequest(new NodeRequest(canvas, diagram, definingResource, null), new TransientCacheAsyncListener<IElement>() {
150
151                     @Override
152                     public void exception(AsyncReadGraph graph, Throwable throwable) {
153                         throwable.printStackTrace();
154                     }
155
156                     @Override
157                     public void execute(AsyncReadGraph graph, final IElement e) {
158
159                         final CompositeImage img = new CompositeImage(Collections.singletonList(e));
160                         final ConcurrentLinkedQueue<ObjectTerminal> terminals = new ConcurrentLinkedQueue<ObjectTerminal>();
161                         final AtomicInteger ready = new AtomicInteger(1);
162
163                         graph.forOrderedSet(definingResource, new AsyncMultiProcedure<Resource>() {
164
165                             @Override
166                             public void exception(AsyncReadGraph graph, Throwable throwable) {
167                                 throwable.printStackTrace();
168                             }
169
170                             @Override
171                             public void execute(AsyncReadGraph graph, final Resource r) {
172
173                                 ready.incrementAndGet();
174
175                                 graph.forIsInstanceOf(r, dr.Terminal, new AsyncProcedure<Boolean>() {
176
177                                     @Override
178                                     public void exception(AsyncReadGraph graph, Throwable throwable) {
179                                         throwable.printStackTrace();
180                                     }
181
182                                     public void execute(AsyncReadGraph graph, Boolean isTerminal) {
183
184                                         if (isTerminal) {
185                                             graph.asyncRequest(new NodeRequest(canvas, diagram, r, null), new TransientCacheAsyncListener<IElement>() {
186                                                 @Override
187                                                 public void exception(AsyncReadGraph graph, Throwable throwable) {
188                                                     throwable.printStackTrace();
189                                                 }
190
191                                                 @Override
192                                                 public void execute(AsyncReadGraph graph, final IElement t) {
193                                                     graph.forPossibleRelatedValue(r, g2d.HasTransform, Bindings.DOUBLE_ARRAY, new AsyncProcedure<double[]>() {
194                                                         @Override
195                                                         public void exception(AsyncReadGraph graph, Throwable throwable) {
196                                                             throwable.printStackTrace();
197                                                         }
198
199                                                         @Override
200                                                         public void execute(AsyncReadGraph graph, double[] mat) {
201                                                             AffineTransform tr = mat != null ? new AffineTransform(mat) : new AffineTransform();
202                                                             terminals.add(new ResourceTerminal(r, tr, DirectionSet.ANY, new ShapeContainer(t)));
203
204                                                             worked(graph);
205                                                         }
206                                                     });
207                                                 }
208                                             });
209                                         } else {
210                                             worked(graph);
211                                         }
212
213                                     }
214
215                                 });
216
217                             }
218
219                             @Override
220                             public void finished(AsyncReadGraph graph) {
221                                 worked(graph);
222                             }
223
224                             void worked(AsyncReadGraph graph) {
225                                 if (ready.decrementAndGet() == 0) {
226                                     String id = "DefinedElement: " + elementType.getResourceId();
227                                     procedure.execute(graph, ElementClass.compile(
228                                             TextImpl.INSTANCE,
229                                             new StaticObjectAdapter(elementType),
230                                             DefaultTransform.INSTANCE,
231                                             StaticSymbolImageInitializer.INSTANCE,
232                                             new StaticSymbolImpl(img),
233                                             DefinedElementHandler.INSTANCE,
234                                             new DefinedElementTerminals(terminals),
235                                             SimpleElementLayers.INSTANCE,
236                                             PlainElementPropertySetter.INSTANCE
237                                             ).setId(id));
238                                 }
239                             }
240                         });
241
242                     }
243
244                 });
245
246             }
247
248         });
249
250     }
251
252     @Override
253     public void load(AsyncReadGraph graph, final ICanvasContext canvas, final IDiagram diagram, final Resource element, final IElement e, final AsyncProcedure<IElement> procedure) {
254         e.setHint(SynchronizationHints.HINT_SYNCHRONIZER, TransformSynchronizer.INSTANCE);
255         // FIXME : this just adds test tooltip to the element.
256         //e.setHint(TooltipParticipant.TOOLTIP_KEY, DefinedElementTooltipProvider.INSTANCE);
257         // This is needed for terminal tooltips.
258         e.setHint(TooltipParticipant.TOOLTIP_KEY, TerminalTooltipProvider.INSTANCE);
259
260         GuardedAsyncProcedureWrapper<IElement> guard = new GuardedAsyncProcedureWrapper<IElement>(procedure, 1);
261         ElementFactoryUtil.readTransform(graph, element, e, guard);
262
263 //        graph.asyncRequest(new SafeName(resource), new ProcedureAdapter<String>() {
264 //            @Override
265 //            public void execute(String result) {
266 //                System.out.println("DefinedElementFactory.load: "  + result);
267 //            }
268 //        });
269     }
270
271 }