UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

84 lines (75 loc) 2.3 kB
import { assert } from "../../../core/assert.js"; /** * Per-peer "last acknowledged frame" tracker. * * The replicator sends actions for frames `[Baseline.last_acked(peer) + 1, current]` * to each peer. When the peer's ack arrives (via the {@link Channel}), it * advances the baseline. * * Frame numbers are absolute uint32. At 60 Hz, 2^32 frames = 2.27 years — * we can ignore wraparound for practical sessions and use plain `>` comparison. * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class Baseline { #last_acked; constructor() { /** * peer_id -> last acked frame number * @type {Map<number, number>} * @private */ this.#last_acked = new Map(); } /** * Record that `peer_id` has acknowledged through `frame`. Monotonic: out-of-order * acks (for an older frame than already recorded) are ignored. * * @param {number} peer_id * @param {number} frame */ set_acked(peer_id, frame) { assert.isNonNegativeInteger(peer_id, 'peer_id'); assert.isNonNegativeInteger(frame, 'frame'); const current = this.#last_acked.get(peer_id); if (current === undefined || frame > current) { this.#last_acked.set(peer_id, frame); } } /** * Returns the most recent acknowledged frame for `peer_id`, or -1 if none. * * @param {number} peer_id * @returns {number} */ last_acked(peer_id) { assert.isNonNegativeInteger(peer_id, 'peer_id'); const v = this.#last_acked.get(peer_id); return v === undefined ? -1 : v; } /** * Forget tracking for `peer_id` (e.g. on disconnect). * * @param {number} peer_id */ forget(peer_id) { assert.isNonNegativeInteger(peer_id, 'peer_id'); this.#last_acked.delete(peer_id); } /** * Number of tracked peers. * @returns {number} */ peer_count() { return this.#last_acked.size; } /** * Iterate (peer_id, last_acked_frame) pairs. * @param {function(number, number): void} fn */ for_each(fn) { assert.isFunction(fn, 'fn'); this.#last_acked.forEach((frame, peer_id) => fn(peer_id, frame)); } }