From fac8a9fce341bc42173af3cde70ef6aef00d7ee7 Mon Sep 17 00:00:00 2001 From: Daniel Kirschten Date: Thu, 26 Sep 2019 14:56:22 +0200 Subject: [PATCH] Fixed execution freezing when the next queued event has a long delta --- .../core/timeline/PauseableTimeFunction.java | 19 +++++++++++++++++-- .../mograsim/logic/model/LogicExecuter.java | 5 +++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/PauseableTimeFunction.java b/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/PauseableTimeFunction.java index ed95ec03..fc4aa13d 100644 --- a/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/PauseableTimeFunction.java +++ b/plugins/net.mograsim.logic.core/src/net/mograsim/logic/core/timeline/PauseableTimeFunction.java @@ -1,5 +1,8 @@ package net.mograsim.logic.core.timeline; +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; import java.util.function.LongSupplier; public class PauseableTimeFunction implements LongSupplier @@ -8,6 +11,8 @@ public class PauseableTimeFunction implements LongSupplier private long unpausedSysTime = 0, lastPausedInternalTime = 0; private double speedFactor = 1; + private final List> simulTimeToRealTimeFactorChangedListeners = new ArrayList<>(); + public void pause() { if (!paused) @@ -33,9 +38,9 @@ public class PauseableTimeFunction implements LongSupplier : lastPausedInternalTime + (System.nanoTime() / 1000 - unpausedSysTime) * speedFactor); } - public long simulTimeDeltaToRealTimeMillis(long simulTime) + public double getSimulTimeToRealTimeFactor() { - return paused ? -1 : (long) (simulTime / speedFactor / 1000); + return 1 / 1000 / speedFactor; } public void setSpeedFactor(double factor) @@ -48,8 +53,18 @@ public class PauseableTimeFunction implements LongSupplier unpause(); } this.speedFactor = factor; + callSimulTimeToRealTimeFactorChangedListeners(getSimulTimeToRealTimeFactor()); } + //@formatter:off + public void addSimulTimeToRealTimeFactorChangedListener(Consumer listener) + {simulTimeToRealTimeFactorChangedListeners.add (listener);} + public void removeSimulTimeToRealTimeFactorChangedListener(Consumer listener) + {simulTimeToRealTimeFactorChangedListeners.remove(listener);} + private void callSimulTimeToRealTimeFactorChangedListeners(double f) + {simulTimeToRealTimeFactorChangedListeners.forEach(l -> l.accept(f));} + //@formatter:on + public boolean isPaused() { return paused; 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 77a09352..c1061219 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 @@ -41,13 +41,12 @@ public class LogicExecuter { while (shouldBeRunningLive.get()) { - // always execute to keep timeline from "hanging behind" for too long long current = tf.getAsLong(); timeline.executeUntil(timeline.laterThan(current), System.currentTimeMillis() + 10); long nextEventTime = timeline.nextEventTime(); long sleepTime; if (timeline.hasNext()) - sleepTime = tf.simulTimeDeltaToRealTimeMillis(nextEventTime - current); + sleepTime = (long) ((nextEventTime - current) * tf.getSimulTimeToRealTimeFactor()); else sleepTime = 10000; try @@ -82,6 +81,8 @@ public class LogicExecuter if (Timeline.timeCmp(event.getTiming(), nextExecSimulTime.get()) < 0) simulationThread.interrupt(); }); + // not optimal; but we don't expect this to happen very often + tf.addSimulTimeToRealTimeFactorChangedListener(d -> simulationThread.interrupt()); } public void executeNextStep() -- 2.17.1