PauseableTimeFunction now supports non-integral speed factors
[Mograsim.git] / plugins / net.mograsim.logic.core / src / net / mograsim / logic / core / timeline / PauseableTimeFunction.java
1 package net.mograsim.logic.core.timeline;
2
3 import java.util.function.LongSupplier;
4
5 public class PauseableTimeFunction implements LongSupplier
6 {
7         private boolean paused = false;
8         private long unpausedSysTime = 0, lastPausedInternalTime = 0;
9         private double speedFactor = 1;
10
11         public void pause()
12         {
13                 if (!paused)
14                 {
15                         lastPausedInternalTime = getAsLong();
16                         paused = true;
17                 }
18         }
19
20         public void unpause()
21         {
22                 if (paused)
23                 {
24                         paused = false;
25                         unpausedSysTime = System.currentTimeMillis();
26                 }
27         }
28
29         @Override
30         public long getAsLong()
31         {
32                 return (long) (paused ? lastPausedInternalTime
33                                 : lastPausedInternalTime + (System.currentTimeMillis() - unpausedSysTime) * speedFactor);
34         }
35
36         public long simulTimeDeltaToRealTimeMillis(long simulTime)
37         {
38                 return paused ? -1 : (long) (simulTime / speedFactor);
39         }
40
41         public void setSpeedFactor(double factor)
42         {
43                 if (factor <= 0)
44                         throw new IllegalArgumentException("time factor can't be smaller than 1");
45                 if (!paused)
46                 {
47                         pause();
48                         unpause();
49                 }
50                 this.speedFactor = factor;
51         }
52
53         public boolean isPaused()
54         {
55                 return paused;
56         }
57
58         public void toggle()
59         {
60                 if (paused)
61                         unpause();
62                 else
63                         pause();
64         }
65 }