@dcl/ecs
Version:
Decentraland ECS
70 lines (69 loc) • 2.13 kB
JavaScript
/**
* Creates a timer system bound to a specific engine instance.
*
* @param targetEngine - The engine instance to bind timers to
* @returns A Timers object with setTimeout, clearTimeout, setInterval, and clearInterval methods
*
* @example
* ```ts
* import { Engine } from '@dcl/sdk/ecs'
* import { createTimers } from '@dcl/sdk/ecs'
*
* const engine = Engine()
* const timers = createTimers(engine)
*
* timers.setTimeout(() => console.log('done'), 1000)
* ```
*
* @public
*/
export function createTimers(targetEngine) {
const timers = new Map();
let timerIdCounter = 0;
function system(dt) {
for (const [timerId, timerData] of timers) {
timerData.accumulatedTime += 1000 * dt;
if (timerData.accumulatedTime < timerData.interval) {
continue;
}
if (timerData.recurrent) {
// For intervals, subtract full interval periods to handle accumulated time
const fullIntervals = Math.floor(timerData.accumulatedTime / timerData.interval);
timerData.accumulatedTime -= fullIntervals * timerData.interval;
}
else {
timers.delete(timerId);
}
timerData.callback();
}
}
targetEngine.addSystem(system, Number.MAX_SAFE_INTEGER, '@dcl/ecs/timers');
return {
setTimeout(callback, ms) {
const timerId = timerIdCounter++;
timers.set(timerId, {
callback,
interval: ms,
recurrent: false,
accumulatedTime: 0
});
return timerId;
},
clearTimeout(timerId) {
timers.delete(timerId);
},
setInterval(callback, ms) {
const timerId = timerIdCounter++;
timers.set(timerId, {
callback,
interval: ms,
recurrent: true,
accumulatedTime: 0
});
return timerId;
},
clearInterval(timerId) {
timers.delete(timerId);
}
};
}