Tell On timer how late its frame is, so time minus late is exact (#224)
A timer can only fire on a frame. It fires on the first frame past each due time, so Time.time at that moment is the due time plus up to one frame. On a display that is not exactly 60 Hz this delay creeps up by a millisecond every few seconds and falls back to zero once it reaches a whole frame. The issue saw 82.009 after 82 ticks. The timer itself does not drift, it keeps the remainder when it fires. - On timer gets a number output late. It is what is left of the timer's clock after taking one interval, so time - late is exactly the due time. - When one long frame catches up several ticks, each gets its own late. The first one was due longest ago and is the latest. Tests: - New unit test in behavior-events: late 0.125 after a frame past 1.0 s, 0 on the dot, 1.5 and 0.5 for two ticks caught up in one frame. - Counter-check: late taken before the interval is subtracted fails exactly that test. Original restored with cmp. - ./check.sh: 156 files, 2300 tests, CHECK EXIT 0 (was 2299). - No e2e change. The e2e modules only wire the exec of On timer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
aef1eba917
commit
6fecb2e841
3 files changed
+25
-4
No files matched your search
@@ -262,6 +262,24 @@ describe('On timer', () => {
|
||||
expect(world.log).toEqual(['tick', 'tick', 'tick', 'tick']);
|
||||
});
|
||||
|
||||
it('late is how far the firing frame is past the due time, so time minus late is exact', () => {
|
||||
const f = scene();
|
||||
const edit = graphEditor(f, f.behavior);
|
||||
const timer = edit.addNode('OnTimer', { interval: 1 });
|
||||
const log = edit.addNode('Log', {});
|
||||
edit.connect(timer, 'exec', log, 'exec');
|
||||
edit.connect(timer, 'late', log, 'message');
|
||||
const { world, frame } = startWorld(f, { behaviors: true });
|
||||
|
||||
frame(0.75);
|
||||
frame(0.375); // 1.125 s: due at 1.0
|
||||
expect(world.log).toEqual(['0.125']);
|
||||
frame(0.875); // 2.0 s: due exactly now
|
||||
expect(world.log).toEqual(['0.125', '0']);
|
||||
frame(2.5); // 4.5 s: catches up 3.0 and 4.0, the first one longer ago
|
||||
expect(world.log).toEqual(['0.125', '0', '1.5', '0.5']);
|
||||
});
|
||||
|
||||
it('two timers keep separate clocks', () => {
|
||||
const f = scene();
|
||||
logOn(f, 'OnTimer', { interval: 1 }, 'slow');
|
||||
|
||||
Reference in new issue
Block a user