1 package mograsim.logic.ui;
3 import java.util.concurrent.atomic.AtomicBoolean;
4 import java.util.concurrent.atomic.AtomicLong;
6 import mograsim.logic.core.timeline.Timeline;
8 //TODO maybe move to logic core?
9 public class LogicExecuter
11 // TODO replace with LogicModel when it exists
12 private final Timeline timeline;
14 private final AtomicBoolean shouldBeRunningLive;
15 private final AtomicBoolean isRunningLive;
16 private final AtomicLong nextExecSimulTime;
17 private final Thread simulationThread;
19 public LogicExecuter(Timeline timeline)
21 this.timeline = timeline;
23 timeline.setTimeFunction(System::currentTimeMillis);
24 shouldBeRunningLive = new AtomicBoolean();
25 isRunningLive = new AtomicBoolean();
26 nextExecSimulTime = new AtomicLong();
27 simulationThread = new Thread(() ->
29 isRunningLive.set(true);
30 synchronized (isRunningLive)
32 isRunningLive.notify();
34 while (shouldBeRunningLive.get())
36 // always execute to keep timeline from "hanging behind" for too long
37 long current = System.currentTimeMillis();
38 timeline.executeUntil(timeline.laterThan(current), current + 10);
40 if (timeline.hasNext())
41 sleepTime = timeline.nextEventTime() - current;
46 nextExecSimulTime.set(current + sleepTime);
48 Thread.sleep(sleepTime);
50 catch (@SuppressWarnings("unused") InterruptedException e)
51 {// do nothing; it is normal execution flow to be interrupted
54 isRunningLive.set(false);
55 synchronized (isRunningLive)
57 isRunningLive.notify();
60 timeline.addEventAddedListener(event ->
62 if (isRunningLive.get())
63 if (Timeline.timeCmp(event.getTiming(), nextExecSimulTime.get()) < 0)
64 simulationThread.interrupt();
68 public void executeNextStep()
70 timeline.executeNext();
73 public synchronized void startLiveExecution()
75 if (shouldBeRunningLive.get())
77 shouldBeRunningLive.set(true);
78 simulationThread.start();
79 waitForIsRunning(true);
82 public synchronized void stopLiveExecution()
84 if (!shouldBeRunningLive.get())
86 shouldBeRunningLive.set(false);
87 simulationThread.interrupt();
88 waitForIsRunning(false);
91 private void waitForIsRunning(boolean expectedState)
93 while (isRunningLive.get() ^ expectedState)
96 synchronized (isRunningLive)
101 catch (@SuppressWarnings("unused") InterruptedException e)
102 {// no need to do anything