Merge branch 'development' of https://gitlab.lrz.de/lrr-tum/students/eragp-misim...
[Mograsim.git] / plugins / net.mograsim.logic.core / src / net / mograsim / logic / core / timeline / PauseableTimeFunction.java
index 4a99310..94dd552 100644 (file)
@@ -1,18 +1,24 @@
 package net.mograsim.logic.core.timeline;
 
-import java.util.function.LongSupplier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
 
-public class PauseableTimeFunction implements LongSupplier
+import net.mograsim.logic.core.timeline.Timeline.TimeFunction;
+
+public class PauseableTimeFunction implements TimeFunction
 {
        private boolean paused = false;
        private long unpausedSysTime = 0, lastPausedInternalTime = 0;
        private double speedFactor = 1;
 
+       private final List<Consumer<Double>> simulTimeToRealTimeFactorChangedListeners = new ArrayList<>();
+
        public void pause()
        {
                if (!paused)
                {
-                       lastPausedInternalTime = getAsLong();
+                       lastPausedInternalTime = getTime();
                        paused = true;
                }
        }
@@ -22,34 +28,51 @@ public class PauseableTimeFunction implements LongSupplier
                if (paused)
                {
                        paused = false;
-                       unpausedSysTime = System.currentTimeMillis();
+                       unpausedSysTime = System.nanoTime() / 1000;
                }
        }
 
        @Override
-       public long getAsLong()
+       public long getTime()
        {
                return (long) (paused ? lastPausedInternalTime
-                               : lastPausedInternalTime + (System.currentTimeMillis() - unpausedSysTime) * speedFactor);
+                               : lastPausedInternalTime + (System.nanoTime() / 1000 - unpausedSysTime) * speedFactor);
        }
 
-       public long simulTimeDeltaToRealTimeMillis(long simulTime)
+       @Override
+       public void setTime(long time)
        {
-               return paused ? -1 : (long) (simulTime / speedFactor);
+               lastPausedInternalTime = time;
+               unpausedSysTime = System.nanoTime() / 1000;
+       }
+
+       public double getSimulTimeToRealTimeFactor()
+       {
+               return 1 / 1000d / speedFactor;
        }
 
        public void setSpeedFactor(double factor)
        {
                if (factor <= 0)
-                       throw new IllegalArgumentException("time factor can't be smaller than 1");
+                       throw new IllegalArgumentException("time factor can't be less than or equal to 0");
                if (!paused)
                {
                        pause();
                        unpause();
                }
                this.speedFactor = factor;
+               callSimulTimeToRealTimeFactorChangedListeners(getSimulTimeToRealTimeFactor());
        }
 
+       //@formatter:off
+       public void    addSimulTimeToRealTimeFactorChangedListener(Consumer<Double> listener)
+               {simulTimeToRealTimeFactorChangedListeners.add   (listener);}
+       public void removeSimulTimeToRealTimeFactorChangedListener(Consumer<Double> listener)
+               {simulTimeToRealTimeFactorChangedListeners.remove(listener);}
+       private void  callSimulTimeToRealTimeFactorChangedListeners(double f)
+               {simulTimeToRealTimeFactorChangedListeners.forEach(l -> l.accept(f));}
+       //@formatter:on
+
        public boolean isPaused()
        {
                return paused;