1 package net.mograsim.logic.model;
3 import java.util.concurrent.atomic.AtomicBoolean;
4 import java.util.concurrent.atomic.AtomicLong;
6 import net.mograsim.logic.core.timeline.Timeline;
8 //TODO maybe move to logic core?
9 public class LogicExecuter
11 // TODO replace with CoreModel 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();
36 while (shouldBeRunningLive.get())
38 // always execute to keep timeline from "hanging behind" for too long
39 long current = System.currentTimeMillis();
40 timeline.executeUntil(timeline.laterThan(current), current + 10);
42 if (timeline.hasNext())
43 sleepTime = timeline.nextEventTime() - current;
48 nextExecSimulTime.set(current + sleepTime);
50 Thread.sleep(sleepTime);
52 catch (@SuppressWarnings("unused") InterruptedException e)
53 {// do nothing; it is normal execution flow to be interrupted
59 isRunningLive.set(false);
60 synchronized (isRunningLive)
62 isRunningLive.notify();
66 timeline.addEventAddedListener(event ->
68 if (isRunningLive.get())
69 if (Timeline.timeCmp(event.getTiming(), nextExecSimulTime.get()) < 0)
70 simulationThread.interrupt();
74 public void executeNextStep()
76 timeline.executeNext();
79 public synchronized void startLiveExecution()
81 if (shouldBeRunningLive.get())
83 shouldBeRunningLive.set(true);
84 simulationThread.start();
85 waitForIsRunning(true);
88 public synchronized void stopLiveExecution()
90 if (!shouldBeRunningLive.get())
92 shouldBeRunningLive.set(false);
93 simulationThread.interrupt();
94 waitForIsRunning(false);
97 private void waitForIsRunning(boolean expectedState)
99 while (isRunningLive.get() ^ expectedState)
102 synchronized (isRunningLive)
104 isRunningLive.wait();
107 catch (@SuppressWarnings("unused") InterruptedException e)
108 {// no need to do anything