]> gerrit.simantics Code Review - simantics/sysdyn.git/blob
a0c89f82dd2818e15859b727cf76a505bce46efa
[simantics/sysdyn.git] /
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2011 Association for Decentralized Information Management in\r
3  * Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.sysdyn.ui.listeners;\r
13 \r
14 import java.util.HashMap;\r
15 \r
16 import org.eclipse.ui.IEditorPart;\r
17 import org.eclipse.ui.IEditorReference;\r
18 import org.eclipse.ui.IWorkbench;\r
19 import org.eclipse.ui.IWorkbenchPage;\r
20 import org.eclipse.ui.IWorkbenchWindow;\r
21 import org.eclipse.ui.PlatformUI;\r
22 import org.simantics.db.Resource;\r
23 import org.simantics.db.WriteGraph;\r
24 import org.simantics.db.common.request.PossibleObjectWithType;\r
25 import org.simantics.db.common.request.WriteRequest;\r
26 import org.simantics.db.exception.DatabaseException;\r
27 import org.simantics.db.layer0.util.Simantics;\r
28 import org.simantics.db.service.VirtualGraphSupport;\r
29 import org.simantics.diagram.profile.Profiles;\r
30 import org.simantics.diagram.stubs.DiagramResource;\r
31 import org.simantics.layer0.Layer0;\r
32 import org.simantics.modeling.ui.diagramEditor.DiagramEditor;\r
33 import org.simantics.project.IProject;\r
34 import org.simantics.simulation.experiment.ExperimentState;\r
35 import org.simantics.simulation.experiment.IExperiment;\r
36 import org.simantics.simulation.experiment.IExperimentListener;\r
37 import org.simantics.simulation.ontology.SimulationResource;\r
38 import org.simantics.simulation.project.IExperimentManager;\r
39 import org.simantics.sysdyn.SysdynResource;\r
40 import org.simantics.sysdyn.manager.SysdynPlaybackExperiment;\r
41 import org.simantics.sysdyn.ui.editor.DiagramViewer;\r
42 import org.simantics.ui.SimanticsUI;\r
43 \r
44 /**\r
45  * Listener for playback simulations. This listener activates and reverts the playback\r
46  * profile when a playback simlation is activated or disposed.\r
47  * @author Teemu Lempinen\r
48  *\r
49  */\r
50 public class SysdynPlaybackExperimentListener implements IExperimentListener {\r
51 \r
52     private Resource model;\r
53     private Resource previousProfile;\r
54 \r
55     public SysdynPlaybackExperimentListener(SysdynPlaybackExperiment experiment) {\r
56         this.model = experiment.getModel();\r
57         activatePlaybackProfile();\r
58     }\r
59 \r
60     @Override\r
61     public void stateChanged(final ExperimentState state) {\r
62         switch(state) {\r
63             case DISPOSED:\r
64                 revertPlaybackProfiles();\r
65                 break;\r
66         }\r
67     }\r
68 \r
69     class DiagramInfo {\r
70         public String modelURI = null;\r
71         public Resource previousProfile = null;\r
72     }\r
73 \r
74     HashMap<Resource, DiagramInfo> previousRuntimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
75 \r
76     private void activatePlaybackProfile() {\r
77         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
78 \r
79             @Override\r
80             public void run() {\r
81                 previousRuntimeDiagramsAndModelUris.clear();\r
82                 previousRuntimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
83                 activatePlaybackProfileRequest(previousRuntimeDiagramsAndModelUris);\r
84             }\r
85         });\r
86     }\r
87     \r
88     private void revertPlaybackProfiles() {\r
89         \r
90         IProject project =  SimanticsUI.getProject();\r
91         if(project == null)\r
92             return;\r
93         IExperimentManager manager = SimanticsUI.getProject().getHint(IExperimentManager.KEY_EXPERIMENT_MANAGER);\r
94         IExperiment experiment = manager.getActiveExperiment();\r
95         \r
96         if(experiment != null && experiment instanceof SysdynPlaybackExperiment && this.model.equals(experiment.getModel()))\r
97                 return;\r
98         \r
99         PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {\r
100 \r
101             @Override\r
102             public void run() {\r
103                 final HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = getCurrentRuntimeDiagramInfos();\r
104 \r
105                 VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
106                 Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
107                     \r
108                     @Override\r
109                     public void perform(WriteGraph graph) throws DatabaseException {\r
110                         \r
111                         Resource model = SysdynPlaybackExperimentListener.this.model;\r
112                         if(model == null)\r
113                             return;\r
114                         \r
115                         Layer0 l0 = Layer0.getInstance(graph);\r
116                         SysdynResource sr = SysdynResource.getInstance(graph);\r
117                         \r
118                         Resource defaultProfile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.DefaultProfile));\r
119                         if(defaultProfile == null)\r
120                             return;\r
121                         \r
122                         setProfileForModel(graph, model, previousProfile == null ? defaultProfile : previousProfile);\r
123                         \r
124                         HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, runtimeDiagramsAndModelUris, model);\r
125                         for(Resource runtimeDiagram : infos.keySet()) {\r
126                             Resource previous = null;\r
127                             if(previousRuntimeDiagramsAndModelUris.containsKey(runtimeDiagram)) {\r
128                                 previous = previousRuntimeDiagramsAndModelUris.get(runtimeDiagram).previousProfile;\r
129                             }\r
130                             setProfileForDiagram(graph, runtimeDiagram, previous == null ? defaultProfile : previous);\r
131                         }\r
132                     }\r
133                 });\r
134                 \r
135             }\r
136         });\r
137     }\r
138     \r
139     /**\r
140      * Run in display thread.\r
141      * \r
142      * @return\r
143      */\r
144     private HashMap<Resource, DiagramInfo> getCurrentRuntimeDiagramInfos() {\r
145         HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
146         IWorkbench workBench =  PlatformUI.getWorkbench();\r
147         IWorkbenchWindow window = workBench.getActiveWorkbenchWindow();\r
148         IWorkbenchPage[] pages = window.getPages();\r
149         for(IWorkbenchPage page : pages) {\r
150             for(IEditorReference reference : page.getEditorReferences()) {\r
151                 IEditorPart iep = reference.getEditor(false);\r
152                 if(iep instanceof DiagramEditor) {\r
153                     DiagramEditor editor = (DiagramEditor) iep;\r
154                     if (editor.getViewer() instanceof DiagramViewer) {\r
155                         DiagramViewer viewer = (DiagramViewer) editor.getViewer();\r
156                         Resource runtime = viewer.getRuntime();\r
157                         String modelUri = viewer.getResourceInput2().getModelURI();\r
158                         DiagramInfo info = new DiagramInfo();\r
159                         info.modelURI = modelUri;\r
160                         runtimeDiagramsAndModelUris.put(runtime, info);\r
161                     }\r
162                 }\r
163             }\r
164         }\r
165         return runtimeDiagramsAndModelUris;\r
166     }\r
167     \r
168     \r
169     private HashMap<Resource, DiagramInfo> getRuntimesForModel(WriteGraph graph, HashMap<Resource, DiagramInfo> allInfos, Resource model) throws DatabaseException {\r
170         HashMap<Resource, DiagramInfo> runtimeDiagramsAndModelUris = new HashMap<Resource, DiagramInfo>(); \r
171         for(Resource runtimeDiagram : allInfos.keySet()) {\r
172             DiagramInfo di = allInfos.get(runtimeDiagram);\r
173             if(di == null)\r
174                 continue;\r
175             Resource m = graph.getPossibleResource(di.modelURI);\r
176             if(m == null || !model.equals(m))                    \r
177                 continue;\r
178             \r
179             runtimeDiagramsAndModelUris.put(runtimeDiagram, di);\r
180         }\r
181         return runtimeDiagramsAndModelUris;\r
182     }\r
183     \r
184     private void activatePlaybackProfileRequest(final HashMap<Resource, DiagramInfo> allDiagramInfos) {\r
185         VirtualGraphSupport support = Simantics.getSession().getService(VirtualGraphSupport.class);\r
186         Simantics.getSession().asyncRequest(new WriteRequest(support.getWorkspacePersistent("profiles")) {\r
187             \r
188             @Override\r
189             public void perform(WriteGraph graph) throws DatabaseException {\r
190                 \r
191                 Resource model = SysdynPlaybackExperimentListener.this.model;\r
192                 if(model == null)\r
193                     return;\r
194                 \r
195                 Resource profile = getSimulationPlaybackProfile(graph, model);\r
196                 if(profile == null)\r
197                     return;\r
198                 \r
199                 DiagramResource DIA = DiagramResource.getInstance(graph);\r
200 \r
201                 Resource current = graph.getPossibleObject(model, DIA.HasActiveProfile);\r
202                 previousProfile = current;\r
203 \r
204                 if(!profile.equals(current)) {\r
205                     setProfileForModel(graph, model, profile);\r
206                 }\r
207                 \r
208                 HashMap<Resource, DiagramInfo> infos = getRuntimesForModel(graph, allDiagramInfos, model);\r
209                 for(Resource runtimeDiagram : infos.keySet()) {\r
210                     DiagramInfo di = infos.get(runtimeDiagram);\r
211                     current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
212                     di.previousProfile = current;\r
213                     if(profile.equals(current)) \r
214                         continue;\r
215                     setProfileForDiagram(graph, runtimeDiagram, profile);\r
216                 }\r
217             }\r
218         });\r
219     }\r
220     \r
221     \r
222     private void setProfileForDiagram(WriteGraph graph, Resource runtimeDiagram, Resource profile) throws DatabaseException {\r
223         DiagramResource DIA = DiagramResource.getInstance(graph);\r
224 \r
225         Resource current = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile);\r
226         if(profile.equals(current)) return;\r
227         \r
228         if(current != null)\r
229             graph.deny(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, current);\r
230         graph.claim(runtimeDiagram, DIA.RuntimeDiagram_HasRuntimeProfile, null, profile);\r
231 \r
232         // Set this profile as the default profile for this diagram\r
233         Resource configuration = graph.getPossibleObject(runtimeDiagram, DIA.RuntimeDiagram_HasConfiguration);\r
234         graph.deny(configuration, DIA.HasActiveProfile);\r
235         graph.claim(configuration, DIA.HasActiveProfile, profile);\r
236     }\r
237     \r
238     private void setProfileForModel(WriteGraph graph, Resource model, Resource profile) throws DatabaseException {\r
239         DiagramResource DIA = DiagramResource.getInstance(graph);\r
240 \r
241         // Set this profile as the default profile for this model\r
242         graph.deny(model, DIA.HasActiveProfile);\r
243         graph.claim(model, DIA.HasActiveProfile, profile);\r
244     }\r
245     \r
246     private Resource getSimulationPlaybackProfile(WriteGraph graph, Resource model) throws DatabaseException {\r
247         Layer0 l0 = Layer0.getInstance(graph);\r
248         SysdynResource sr = SysdynResource.getInstance(graph);\r
249         SimulationResource SIMU = SimulationResource.getInstance(graph);\r
250         \r
251         Resource profile = graph.syncRequest(new PossibleObjectWithType(model, l0.ConsistsOf, sr.SimulationPlaybackProfile));\r
252         if(profile == null) {\r
253             profile = Profiles.createProfile(graph, "Simulation Playback", sr.Profiles_SimulationPlaybackColours);\r
254             graph.deny(profile, l0.InstanceOf);\r
255             graph.claim(profile, l0.InstanceOf, null, sr.SimulationPlaybackProfile);\r
256             graph.claim(model, l0.ConsistsOf, profile);\r
257         }\r
258 \r
259         if(!graph.hasStatement(profile, SIMU.IsActive)) {\r
260             graph.claim(profile, SIMU.IsActive, sr.Profiles_SimulationPlaybackColours);\r
261         }\r
262         \r
263         return profile;\r
264     }\r
265     \r
266 }\r