UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

94 lines 3.41 kB
/** * Open-addressed hash set keyed by `uint32` network IDs. Backed by a single * `Uint32Array`; empty slots hold `0xFFFFFFFF`. Probing uses * {@link generate_next_linear_congruential_index} (the same scheme as * `core/collection/map/HashMap.js`). * * Designed for the per-tick "which entities changed this tick?" use case: * - `clear()` is one `fill(0xFFFFFFFF)` call (vectorisable, JIT-friendly). * - `add(network_id)` is O(1) expected with a load factor < 0.5. * - `compact_into(buffer)` writes each non-empty slot as a `varint` and * returns the count, suitable for appending to a `MutationLedger` slice. * * Capacity grows automatically when load factor exceeds 0.5 (doubles + rehashes, * O(N) amortised). Construction-time `capacity` is the *initial* size — * pick at least 2× your typical peak per-tick mutation count to avoid the * grow path on the hot loop. * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class ChangedEntitySet { /** * @param {{ capacity?: number }} [options] capacity is rounded up to a power of two; default 256 */ constructor({ capacity }?: { capacity?: number; }); /** @type {number} */ capacity: number; /** * Reallocate the backing array at `new_capacity` and re-insert every * present ID. Items are placed by their hash against the new mask, so * resize is the only correct way to change capacity (a flat copy would * leave entries at indices that no longer match `id & mask`). * * @param {number} new_capacity power of two; must be at least 2× current size */ resize(new_capacity: number): void; /** * Double the capacity. Called automatically by {@link add} when the load * factor would exceed `LOAD_FACTOR` after the next insert. */ grow(): void; /** * Add a network ID. No-op if already present. Grows the backing array * (and re-hashes) if adding this ID would exceed the load factor. * * @param {number} network_id non-negative integer < 0xFFFFFFFF */ add(network_id: number): void; /** * @param {number} network_id * @returns {boolean} */ has(network_id: number): boolean; /** * Reset every slot to empty. */ clear(): void; /** * Number of unique network IDs currently in the set. * @returns {number} */ size(): number; /** * Iterate every present network ID. Order is implementation-defined * (slot order, not insertion or sorted) — callers must not rely on it. * * @param {function(number): void} fn */ for_each(fn: (arg0: number) => void): void; /** * Append every present network ID into `buffer` as varints. Returns the * number of IDs written. Caller is responsible for any framing (count * prefix, length prefix, etc.). * * @param {BinaryBuffer} buffer * @returns {number} count written */ compact_into(buffer: BinaryBuffer): number; #private; } export namespace ChangedEntitySet { export { EMPTY }; } /** * Reserved sentinel for "empty slot." Network IDs are unsigned 32-bit; we * forbid `0xFFFFFFFF` as a usable ID (the slot table never allocates that * many slots, so this is safe in practice). * @type {number} */ declare const EMPTY: number; export {}; //# sourceMappingURL=ChangedEntitySet.d.ts.map