Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

113
LINES

< > BotCompany Repo | #1025193 // FlexibleRateTimer

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (10945L/62K).

1  
// only executes one action at once. Keeps track of
2  
// optimal timestamps though, so actions may pile up.
3  
// (call pileUp(false) to change.)
4  
// Frequency may be set to 0 or even very close to zero
5  
// (both values effectively stop the timer).
6  
// persists frequency only
7  
// TODO: Events stacked up after coming out of hibernation? (Windows)
8  
sclass FlexibleRateTimer implements AutoCloseable {
9  
  double hertz;
10  
  transient Runnable action;
11  
  transient double timestamp;
12  
  transient DoLater doLater;
13  
  transient new Flag started;
14  
  transient volatile bool disposed;
15  
  transient long delay; // how much are we currently delayed
16  
  transient L<Runnable> onFrequencyChanged;
17  
  transient bool verbose;
18  
  
19  
  settable ISleeper sleeper = defaultSleeper();
20  
  
21  
  settable bool pileUp = true;
22  
23  
  // below actualMinHertz, we stop the timer
24  
  static double minHertz = 0, actualMinHertz = 1e-8, maxHertz = 1000;
25  
  
26  
  *() {}
27  
  *(double *hertz) {}
28  
  *(double *hertz, Runnable *action) {}
29  
  
30  
  void start {
31  
    if (!started.raise()) ret;
32  
    if (verbose) print("Starting timer with " + hertz + " Hz");
33  
    vmBus_timerStarted(this);
34  
    _kaboom();
35  
  }
36  
  
37  
  // This method reschedules the next timer firing
38  
  // (i.e. disposes of the internal timer and optionally
39  
  // creates a new one).
40  
  synchronized void _kaboom() pcall {
41  
    if (verbose) print(disposed ? "Timer kaboom (disposed)" : "Timer kaboom");
42  
    if (disposed) ret;
43  
    dispose doLater;
44  
    if (hertz <= actualMinHertz) ret with timestamp = 0;
45  
    if (timestamp == 0) timestamp = sysNow();
46  
    timestamp += 1000/getFrequency();
47  
    if (!pileUp)
48  
      timestamp = max(sysNow(), timestamp);
49  
    long _timestamp = lround(timestamp);
50  
    doLater = new DoLater(_timestamp, r {
51  
      delay = sysNow()-_timestamp;
52  
      if (verbose) print("Timer action");
53  
      pcallF(action);
54  
      _kaboom();
55  
    });
56  
    doLater.sleeper(sleeper);
57  
    if (verbose) print("Timer scheduled for: " + (_timestamp-sysNow()));
58  
    doLater.enable();
59  
  }
60  
  
61  
  void cancel { close(); }
62  
  
63  
  public synchronized void close {
64  
    set disposed;
65  
    dispose doLater;
66  
  }
67  
  
68  
  void setRunnableAndStart(Runnable action) {
69  
    this.action = action;
70  
    start();
71  
  }
72  
  
73  
  // takes effect _after_ next trigger
74  
  void setFrequency(double hertz) {
75  
    synchronized(this) {
76  
      if (disposed) ret;
77  
      hertz = clamp(hertz, minHertz, maxHertz);
78  
      if (hertz == this.hertz) ret;
79  
      this.hertz = hertz;
80  
    }
81  
    pcallFAll(onFrequencyChanged);
82  
  }
83  
  
84  
  // reschedule next action
85  
  void setFrequencyImmediately(double hertz) {
86  
    synchronized(this) {
87  
      if (disposed) ret;
88  
      hertz = clamp(hertz, minHertz, maxHertz);
89  
      if (hertz == this.hertz) ret;
90  
      double oldHertz = this.hertz;
91  
      this.hertz = hertz;
92  
      if (!started.isUp()) ret;
93  
      if (verbose) print("Timer setFreq doLater=" + doLater);
94  
      bool b = doLater == null || doLater.cancel();
95  
      if (verbose) print("Timer cancel result: " + b + " (" + oldHertz + " -> " + hertz + ")");
96  
      timestamp = sysNow();
97  
      if (b) _kaboom();
98  
    }
99  
    pcallFAll(onFrequencyChanged);
100  
  }
101  
  
102  
  synchronized double getFrequency() { ret hertz; }
103  
  
104  
  long currentDelay() { ret delay; }
105  
  
106  
  synchronized void onFrequencyChanged(Runnable r) {
107  
    onFrequencyChanged = addOrCreate(onFrequencyChanged,  r);
108  
  }
109  
  
110  
  void onFrequencyChangedAndNow(Runnable r) {
111  
    onFrequencyChanged(runAndReturn(r));
112  
  }
113  
}

download  show line numbers  debug dex  old transpilations   

Travelled to 7 computer(s): bhatertpkbcr, ekrmjmnbrukm, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1025193
Snippet name: FlexibleRateTimer
Eternal ID of this version: #1025193/32
Text MD5: 386d9381848552d01bb333629cd72473
Transpilation MD5: 4d120ce7ca0886eebec5c5854be65252
Author: stefan
Category: javax
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2022-11-28 20:55:58
Source code size: 3487 bytes / 113 lines
Pitched / IR pitched: No / No
Views / Downloads: 347 / 949
Version history: 31 change(s)
Referenced in: [show references]