From 1b2cb79cec1d587f4a529f8d1e862efeee3e965c Mon Sep 17 00:00:00 2001 From: Fabian Stemmler Date: Sat, 5 Oct 2019 16:58:52 +0200 Subject: [PATCH] Fixed 2 Simulation bugs Pausing the timeline now stops the execution of events during executeUntil() -> suspending the DebugTarget on a rising edge of the clock now has an immediate effect The Simulation can no longer lag behind the TimeFunction, as the TimeFunction is now set back in such an event --- .../logic/core/timeline/Timeline.java | 27 ++++++++++++------- .../mograsim/logic/model/LogicExecuter.java | 7 ++++- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java b/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java index 5fcb111e..12cf5bd1 100644 --- a/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java +++ b/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/Timeline.java @@ -16,7 +16,7 @@ public class Timeline { private PriorityQueue events; private TimeFunction time; - private long lastTimeUpdated = 0; + private long processedUntil = 0; private long eventCounter = 0; private final List> eventAddedListener; @@ -27,13 +27,13 @@ public class Timeline @Override public void setTime(long time) { - lastTimeUpdated = time; + processedUntil = time; } @Override public long getTime() { - return lastTimeUpdated; + return processedUntil; } }; public final TimeFunction realTimeExec = new TimeFunction() @@ -119,7 +119,7 @@ public class Timeline { if (events.isEmpty()) { - lastTimeUpdated = getSimulationTime(); + processedUntil = getSimulationTime(); return ExecutionResult.NOTHING_DONE; } working(); @@ -131,19 +131,18 @@ public class Timeline { event = events.remove(); } - lastTimeUpdated = event.getTiming(); + processedUntil = event.getTiming(); event.run(); // Don't check after every run checkStop = (checkStop + 1) % 10; if (checkStop == 0 && System.currentTimeMillis() >= stopMillis) { notWorking(); - lastTimeUpdated = getSimulationTime(); return ExecutionResult.EXEC_OUT_OF_TIME; } } notWorking(); - lastTimeUpdated = getSimulationTime(); + processedUntil = getSimulationTime(); return hasNext() ? ExecutionResult.EXEC_UNTIL_EMPTY : ExecutionResult.EXEC_UNTIL_CONDITION; } @@ -165,7 +164,7 @@ public class Timeline */ public long getSimulationTime() { - return isWorking() ? lastTimeUpdated : time.getTime(); + return isWorking() ? processedUntil : time.getTime(); } /** @@ -189,7 +188,7 @@ public class Timeline { events.clear(); } - lastTimeUpdated = time.getTime(); + processedUntil = time.getTime(); } /** @@ -288,7 +287,7 @@ public class Timeline { eventsString = events.toString(); } - return String.format("Simulation time: %s, Last update: %d, Events: %s", getSimulationTime(), lastTimeUpdated, eventsString); + return String.format("Simulation time: %s, Last update: %d, Events: %s", getSimulationTime(), processedUntil, eventsString); } public static enum ExecutionResult @@ -302,4 +301,12 @@ public class Timeline void setTime(long time); } + + /** + * Sets the time of the {@link TimeFunction} to the timestamp of the latest processed event + */ + public void synchTime() + { + time.setTime(processedUntil); + } } \ No newline at end of file diff --git a/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicExecuter.java b/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicExecuter.java index 1eff4112..52adeba0 100644 --- a/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicExecuter.java +++ b/plugins/net.mograsim.logic.model/src/net/mograsim/logic/model/LogicExecuter.java @@ -5,6 +5,7 @@ import java.util.concurrent.atomic.AtomicLong; import net.mograsim.logic.core.timeline.PauseableTimeFunction; import net.mograsim.logic.core.timeline.Timeline; +import net.mograsim.logic.core.timeline.Timeline.ExecutionResult; //TODO maybe move to logic core? public class LogicExecuter @@ -42,7 +43,11 @@ public class LogicExecuter while (shouldBeRunningLive.get()) { long current = tf.getTime(); - timeline.executeUntil(timeline.laterThan(current), System.currentTimeMillis() + 10); + // The tf.isPaused() condition is justified, because timeline.getSimulationTime() returns the timestamp of the last + // processed event during executeUntil() + if (timeline.executeUntil(() -> timeline.laterThan(current).getAsBoolean() || tf.isPaused(), + System.currentTimeMillis() + 10) == ExecutionResult.EXEC_OUT_OF_TIME) + timeline.synchTime(); // TODO: should this also be called if tf.isPaused() condition is met? long nextEventTime = timeline.nextEventTime(); long sleepTime; if (timeline.hasNext()) -- 2.17.1