Merge branch 'development' of
[Mograsim.git] / LogicUI / src / era / mi / gui / LogicUIStandalone.java
1 package era.mi.gui;\r
2 \r
3 import java.util.concurrent.atomic.AtomicBoolean;\r
4 \r
5 import org.eclipse.swt.SWT;\r
6 import org.eclipse.swt.layout.FillLayout;\r
7 import org.eclipse.swt.widgets.Display;\r
8 import org.eclipse.swt.widgets.Shell;\r
9 \r
10 import era.mi.gui.model.ViewModel;\r
11 import era.mi.gui.modeladapter.LogicModelParameters;\r
12 import era.mi.gui.modeladapter.ViewLogicModelAdapter;\r
13 import era.mi.logic.timeline.Timeline;\r
14 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasOverlay;\r
15 import net.haspamelodica.swt.helper.zoomablecanvas.helper.ZoomableCanvasUserInput;\r
16 \r
17 /**\r
18  * Standalone simulation visualizer.\r
19  * \r
20  * @author Daniel Kirschten\r
21  */\r
22 public class LogicUIStandalone\r
23 {\r
24         private ViewModel model;\r
25         private Timeline timeline;\r
26 \r
27         private final Display display;\r
28         private final Shell shell;\r
29         private final LogicUICanvas ui;\r
30 \r
31         public LogicUIStandalone(ViewModel model)\r
32         {\r
33                 this.model = model;\r
34                 display = new Display();\r
35                 shell = new Shell(display);\r
36                 shell.setLayout(new FillLayout());\r
37                 ui = new LogicUICanvas(shell, SWT.NONE, model);\r
38 \r
39                 ZoomableCanvasUserInput userInput = new ZoomableCanvasUserInput(ui);\r
40                 userInput.buttonDrag = 3;\r
41                 userInput.buttonZoom = 2;\r
42                 userInput.enableUserInput();\r
43                 new ZoomableCanvasOverlay(ui, null).enableScale();\r
44 \r
45                 // TODO don't do this here\r
46                 LogicModelParameters params = new LogicModelParameters();\r
47                 params.gateProcessTime = 50;\r
48                 params.wireTravelTime = 10;\r
49                 timeline = ViewLogicModelAdapter.convert(model, params);\r
50         }\r
51 \r
52         public LogicUICanvas getLogicUICanvas()\r
53         {\r
54                 return ui;\r
55         }\r
56 \r
57         /**\r
58          * Start the simulation timeline, and open the UI shell. Returns when the shell is closed.\r
59          */\r
60         public void run()\r
61         {\r
62                 AtomicBoolean running = new AtomicBoolean(true);\r
63                 Thread simulationThread = new Thread(() ->\r
64                 {\r
65                         while (running.get())\r
66                         {\r
67                                 // always execute to keep timeline from "hanging behind" for too long\r
68                                 timeline.executeUntil(timeline.laterThan(System.currentTimeMillis()), System.currentTimeMillis() + 10);\r
69                                 long sleepTime;\r
70                                 if (timeline.hasNext())\r
71                                         sleepTime = timeline.nextEventTime() - System.currentTimeMillis();\r
72                                 else\r
73                                         sleepTime = 10;\r
74                                 try\r
75                                 {\r
76                                         if (sleepTime > 0)\r
77                                                 Thread.sleep(sleepTime);\r
78                                 }\r
79                                 catch (InterruptedException e)\r
80                                 {\r
81                                 } // it is normal execution flow to be interrupted\r
82                         }\r
83                 });\r
84                 simulationThread.start();\r
85                 timeline.addEventAddedListener(event ->\r
86                 {\r
87                         if (event.getTiming() <= System.currentTimeMillis())\r
88                                 simulationThread.interrupt();\r
89                 });\r
90 \r
91                 shell.open();\r
92                 while (!shell.isDisposed())\r
93                         if (!display.readAndDispatch())\r
94                                 display.sleep();\r
95                 running.set(false);\r
96 //              simulationThread.interrupt();\r
97         }\r
98 }