@dcl/ecs 7.24.1 → 7.24.2-27639923169.commit-aed4ecf
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -20,47 +20,59 @@
|
|
|
20
20
|
export function createTimers(targetEngine) {
|
|
21
21
|
const timers = new Map();
|
|
22
22
|
let timerIdCounter = 0;
|
|
23
|
+
// While a timer's callback is running this holds the time already consumed this
|
|
24
|
+
// frame before that timer's logical fire instant (`elapsedMs - residualMs`);
|
|
25
|
+
// `null` otherwise. A timer armed from within the callback is seeded with the
|
|
26
|
+
// negative of this, so its delay is measured from the parent's fire instant
|
|
27
|
+
// rather than from the start of the frame.
|
|
28
|
+
let armContext = null;
|
|
23
29
|
function system(dt) {
|
|
30
|
+
const elapsedMs = 1000 * dt;
|
|
24
31
|
for (const [timerId, timerData] of timers) {
|
|
25
|
-
timerData.accumulatedTime +=
|
|
32
|
+
timerData.accumulatedTime += elapsedMs;
|
|
26
33
|
if (timerData.accumulatedTime < timerData.interval) {
|
|
27
34
|
continue;
|
|
28
35
|
}
|
|
36
|
+
// Time elapsed past this timer's logical fire instant this frame.
|
|
37
|
+
const residualMs = timerData.recurrent
|
|
38
|
+
? timerData.accumulatedTime % timerData.interval
|
|
39
|
+
: timerData.accumulatedTime - timerData.interval;
|
|
29
40
|
if (timerData.recurrent) {
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
timerData.accumulatedTime -= fullIntervals * timerData.interval;
|
|
41
|
+
// Collapse any missed periods into a single callback, keep the remainder.
|
|
42
|
+
timerData.accumulatedTime = residualMs;
|
|
33
43
|
}
|
|
34
44
|
else {
|
|
35
45
|
timers.delete(timerId);
|
|
36
46
|
}
|
|
47
|
+
armContext = { accruedMs: elapsedMs - residualMs };
|
|
37
48
|
timerData.callback();
|
|
49
|
+
armContext = null;
|
|
38
50
|
}
|
|
39
51
|
}
|
|
40
52
|
targetEngine.addSystem(system, Number.MAX_SAFE_INTEGER, '@dcl/ecs/timers');
|
|
53
|
+
function addTimer(callback, interval, recurrent) {
|
|
54
|
+
const timerId = timerIdCounter++;
|
|
55
|
+
let accumulatedTime = 0;
|
|
56
|
+
if (armContext) {
|
|
57
|
+
// Armed from inside a firing callback: this timer is appended to the map
|
|
58
|
+
// being iterated, so the loop will still add this frame's elapsed to it.
|
|
59
|
+
// Inherit the residual so that `+= elapsedMs` nets to the true time
|
|
60
|
+
// elapsed since the parent fired (phase-accurate). Each successive arming
|
|
61
|
+
// starts one interval lower, so a re-arming chain terminates this frame.
|
|
62
|
+
accumulatedTime = -armContext.accruedMs;
|
|
63
|
+
}
|
|
64
|
+
timers.set(timerId, { callback, interval, recurrent, accumulatedTime });
|
|
65
|
+
return timerId;
|
|
66
|
+
}
|
|
41
67
|
return {
|
|
42
68
|
setTimeout(callback, ms) {
|
|
43
|
-
|
|
44
|
-
timers.set(timerId, {
|
|
45
|
-
callback,
|
|
46
|
-
interval: ms,
|
|
47
|
-
recurrent: false,
|
|
48
|
-
accumulatedTime: 0
|
|
49
|
-
});
|
|
50
|
-
return timerId;
|
|
69
|
+
return addTimer(callback, ms, false);
|
|
51
70
|
},
|
|
52
71
|
clearTimeout(timerId) {
|
|
53
72
|
timers.delete(timerId);
|
|
54
73
|
},
|
|
55
74
|
setInterval(callback, ms) {
|
|
56
|
-
|
|
57
|
-
timers.set(timerId, {
|
|
58
|
-
callback,
|
|
59
|
-
interval: ms,
|
|
60
|
-
recurrent: true,
|
|
61
|
-
accumulatedTime: 0
|
|
62
|
-
});
|
|
63
|
-
return timerId;
|
|
75
|
+
return addTimer(callback, ms, true);
|
|
64
76
|
},
|
|
65
77
|
clearInterval(timerId) {
|
|
66
78
|
timers.delete(timerId);
|
|
@@ -23,47 +23,59 @@ exports.createTimers = void 0;
|
|
|
23
23
|
function createTimers(targetEngine) {
|
|
24
24
|
const timers = new Map();
|
|
25
25
|
let timerIdCounter = 0;
|
|
26
|
+
// While a timer's callback is running this holds the time already consumed this
|
|
27
|
+
// frame before that timer's logical fire instant (`elapsedMs - residualMs`);
|
|
28
|
+
// `null` otherwise. A timer armed from within the callback is seeded with the
|
|
29
|
+
// negative of this, so its delay is measured from the parent's fire instant
|
|
30
|
+
// rather than from the start of the frame.
|
|
31
|
+
let armContext = null;
|
|
26
32
|
function system(dt) {
|
|
33
|
+
const elapsedMs = 1000 * dt;
|
|
27
34
|
for (const [timerId, timerData] of timers) {
|
|
28
|
-
timerData.accumulatedTime +=
|
|
35
|
+
timerData.accumulatedTime += elapsedMs;
|
|
29
36
|
if (timerData.accumulatedTime < timerData.interval) {
|
|
30
37
|
continue;
|
|
31
38
|
}
|
|
39
|
+
// Time elapsed past this timer's logical fire instant this frame.
|
|
40
|
+
const residualMs = timerData.recurrent
|
|
41
|
+
? timerData.accumulatedTime % timerData.interval
|
|
42
|
+
: timerData.accumulatedTime - timerData.interval;
|
|
32
43
|
if (timerData.recurrent) {
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
timerData.accumulatedTime -= fullIntervals * timerData.interval;
|
|
44
|
+
// Collapse any missed periods into a single callback, keep the remainder.
|
|
45
|
+
timerData.accumulatedTime = residualMs;
|
|
36
46
|
}
|
|
37
47
|
else {
|
|
38
48
|
timers.delete(timerId);
|
|
39
49
|
}
|
|
50
|
+
armContext = { accruedMs: elapsedMs - residualMs };
|
|
40
51
|
timerData.callback();
|
|
52
|
+
armContext = null;
|
|
41
53
|
}
|
|
42
54
|
}
|
|
43
55
|
targetEngine.addSystem(system, Number.MAX_SAFE_INTEGER, '@dcl/ecs/timers');
|
|
56
|
+
function addTimer(callback, interval, recurrent) {
|
|
57
|
+
const timerId = timerIdCounter++;
|
|
58
|
+
let accumulatedTime = 0;
|
|
59
|
+
if (armContext) {
|
|
60
|
+
// Armed from inside a firing callback: this timer is appended to the map
|
|
61
|
+
// being iterated, so the loop will still add this frame's elapsed to it.
|
|
62
|
+
// Inherit the residual so that `+= elapsedMs` nets to the true time
|
|
63
|
+
// elapsed since the parent fired (phase-accurate). Each successive arming
|
|
64
|
+
// starts one interval lower, so a re-arming chain terminates this frame.
|
|
65
|
+
accumulatedTime = -armContext.accruedMs;
|
|
66
|
+
}
|
|
67
|
+
timers.set(timerId, { callback, interval, recurrent, accumulatedTime });
|
|
68
|
+
return timerId;
|
|
69
|
+
}
|
|
44
70
|
return {
|
|
45
71
|
setTimeout(callback, ms) {
|
|
46
|
-
|
|
47
|
-
timers.set(timerId, {
|
|
48
|
-
callback,
|
|
49
|
-
interval: ms,
|
|
50
|
-
recurrent: false,
|
|
51
|
-
accumulatedTime: 0
|
|
52
|
-
});
|
|
53
|
-
return timerId;
|
|
72
|
+
return addTimer(callback, ms, false);
|
|
54
73
|
},
|
|
55
74
|
clearTimeout(timerId) {
|
|
56
75
|
timers.delete(timerId);
|
|
57
76
|
},
|
|
58
77
|
setInterval(callback, ms) {
|
|
59
|
-
|
|
60
|
-
timers.set(timerId, {
|
|
61
|
-
callback,
|
|
62
|
-
interval: ms,
|
|
63
|
-
recurrent: true,
|
|
64
|
-
accumulatedTime: 0
|
|
65
|
-
});
|
|
66
|
-
return timerId;
|
|
78
|
+
return addTimer(callback, ms, true);
|
|
67
79
|
},
|
|
68
80
|
clearInterval(timerId) {
|
|
69
81
|
timers.delete(timerId);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dcl/ecs",
|
|
3
3
|
"description": "Decentraland ECS",
|
|
4
|
-
"version": "7.24.
|
|
4
|
+
"version": "7.24.2-27639923169.commit-aed4ecf",
|
|
5
5
|
"author": "DCL",
|
|
6
6
|
"bugs": "https://github.com/decentraland/ecs/issues",
|
|
7
7
|
"files": [
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
"dependencies": {},
|
|
35
35
|
"types": "./dist/index.d.ts",
|
|
36
36
|
"typings": "./dist/index.d.ts",
|
|
37
|
-
"commit": "
|
|
37
|
+
"commit": "aed4ecf2b3b170d28dc5b68f38a7f84699aee0e9"
|
|
38
38
|
}
|