@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
105 lines (81 loc) • 2.35 kB
JavaScript
import { current_time_in_seconds } from "../../core/time/current_time_in_seconds.js";
/**
*
* @type {number}
*/
let global_count = 0;
/**
* Fires a given function every frame. Typical usage is to create an instance, invoke {@link #startup} and once no longer required - invoke {@link #shutdown}
* Wraps {@link requestAnimationFrame}
*/
export class FrameRunner {
/**
*
* @type {boolean}
*/
#running = false;
/**
*
* @type {number}
*/
#animationFrameId = -1;
/**
*
* @param {function(time_delta_sectonds?:number, current_time_seconds?:number):*} action
*/
constructor(action) {
/**
*
* @type {Function}
*/
this.action = action;
}
/**
* Begins animation loop. Does nothing and returns false if already running.
* @returns {boolean}
*/
startup() {
if (this.#running) {
return false;
}
// console.warn(`FrameFunner.started[${global_count}]`);
global_count++;
this.#running = true;
let last_time_stamp = current_time_in_seconds();
const cycle = () => {
if (!this.#running) {
//not supposed to be running, bail
return;
}
const current_time = current_time_in_seconds();
const time_delta = current_time - last_time_stamp;
last_time_stamp = current_time;
this.action(time_delta, current_time);
this.#animationFrameId = requestAnimationFrame(cycle);
}
this.#animationFrameId = requestAnimationFrame(cycle);
return true;
}
/**
* Stops animation loop. Does nothing and returns false if not currently running.
* @returns {boolean}
*/
shutdown() {
if (!this.#running) {
return false;
}
global_count--;
// console.warn(`FrameFunner.stopped[${global_count}]`);
this.#running = false;
cancelAnimationFrame(this.#animationFrameId);
this.#animationFrameId = -1;
return true;
}
/**
*
* @returns {boolean}
*/
isRunning() {
return this.#running;
}
}