UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

102 lines (83 loc) 2.22 kB
import Signal from "../../../core/events/signal/Signal.js"; /** * Value container, allows reference counting through {@link #onReleased} signal * Intended for usage with reference-managing systems * @example * const ref: Reference<Texture> = texture_system.get(some_id); * // do work with texture * ref.release(); // we're done with the resource, texture_system will be notified * // now ref.getValue() === null, reference is no longer valid * @template T */ export class Reference { /** * * @type {Signal<this,T>} * @private */ #onReleased = new Signal(); /** * Actual value being held * @type {T} * @private */ #value = null; /** * Whether a value is bound or not. Will be true if value is != null * @type {boolean} * @private */ #is_bound = false; get bound() { return this.#is_bound; } /** * * @returns {Signal<this,T>} */ get onReleased() { return this.#onReleased; } /** * * @param {T} value */ bind(value) { if (value === this.#value) { return; } if (this.#is_bound) { throw new Error(`Reference is already bound, must release before binding to a new value`); } this.#value = value; this.#is_bound = true; } /** * * @returns {T} */ getValue() { return this.#value; } /** * Release value being referenced. After this the held value is set to null * This method is idempotent, calling it multiple times is safe */ release() { if (!this.#is_bound) { // not bound return; } const v = this.#value; // prevent further usage of the reference this.#value = null; this.#is_bound = false; this.#onReleased.send2(this, v); } } /** * Special NULL reference that can be used to indicate lack of reference * @readonly * @type {Readonly<Reference>} */ Reference.NULL = Object.freeze(new Reference());