import java.util.HashSet;\r
import java.util.Map;\r
import java.util.Set;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
\r
import org.eclipse.swt.SWT;\r
import org.eclipse.swt.layout.FillLayout;\r
\r
public void run()\r
{\r
+ AtomicBoolean running = new AtomicBoolean(true);\r
+ Thread simulationThread = new Thread(() ->\r
+ {\r
+ while(running.get())\r
+ {\r
+ //always execute to keep timeline from "hanging behind" for too long\r
+ Simulation.TIMELINE.executeUpTo(System.currentTimeMillis(), System.currentTimeMillis() + 10);\r
+ long sleepTime;\r
+ if(Simulation.TIMELINE.hasNext())\r
+ {\r
+ sleepTime = Simulation.TIMELINE.nextEventTime() - System.currentTimeMillis();\r
+ } else\r
+ sleepTime = 100;\r
+ try\r
+ {\r
+ if(sleepTime > 0)\r
+ Thread.sleep(sleepTime);\r
+ } catch(InterruptedException e)\r
+ {} //it is normal execution flow to be interrupted\r
+ }\r
+ });\r
+ simulationThread.start();\r
+ Simulation.TIMELINE.addEventAddedListener(event ->\r
+ {\r
+ if(event.getTiming() >= System.currentTimeMillis() / (double) 1)\r
+ simulationThread.interrupt();\r
+ });\r
+\r
shell.open();\r
while(!shell.isDisposed())\r
if(!display.readAndDispatch())\r
display.sleep();\r
+ running.set(false);\r
+ simulationThread.interrupt();\r
}\r
\r
public static void main(String[] args)\r