mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-23 04:15:40 +00:00
37315e5fa5
Store only TileRef instead of packed tile+state values
80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
import { TileRef } from "../game/GameMap";
|
|
|
|
export interface SharedTileRingBuffers {
|
|
header: SharedArrayBuffer;
|
|
data: SharedArrayBuffer;
|
|
}
|
|
|
|
export interface SharedTileRingViews {
|
|
header: Int32Array;
|
|
buffer: Uint32Array;
|
|
capacity: number;
|
|
}
|
|
|
|
// Header indices
|
|
export const TILE_RING_HEADER_WRITE_INDEX = 0;
|
|
export const TILE_RING_HEADER_READ_INDEX = 1;
|
|
export const TILE_RING_HEADER_OVERFLOW = 2;
|
|
|
|
export function createSharedTileRingBuffers(
|
|
capacity: number,
|
|
): SharedTileRingBuffers {
|
|
const header = new SharedArrayBuffer(3 * Int32Array.BYTES_PER_ELEMENT);
|
|
const data = new SharedArrayBuffer(capacity * Uint32Array.BYTES_PER_ELEMENT);
|
|
return { header, data };
|
|
}
|
|
|
|
export function createSharedTileRingViews(
|
|
buffers: SharedTileRingBuffers,
|
|
): SharedTileRingViews {
|
|
const header = new Int32Array(buffers.header);
|
|
const buffer = new Uint32Array(buffers.data);
|
|
return {
|
|
header,
|
|
buffer,
|
|
capacity: buffer.length,
|
|
};
|
|
}
|
|
|
|
export function pushTileUpdate(
|
|
views: SharedTileRingViews,
|
|
value: TileRef,
|
|
): void {
|
|
const { header, buffer, capacity } = views;
|
|
|
|
const write = Atomics.load(header, TILE_RING_HEADER_WRITE_INDEX);
|
|
const read = Atomics.load(header, TILE_RING_HEADER_READ_INDEX);
|
|
const nextWrite = (write + 1) % capacity;
|
|
|
|
// If the buffer is full, advance read (drop oldest) and mark overflow.
|
|
if (nextWrite === read) {
|
|
Atomics.store(header, TILE_RING_HEADER_OVERFLOW, 1);
|
|
const nextRead = (read + 1) % capacity;
|
|
Atomics.store(header, TILE_RING_HEADER_READ_INDEX, nextRead);
|
|
}
|
|
|
|
buffer[write] = value;
|
|
Atomics.store(header, TILE_RING_HEADER_WRITE_INDEX, nextWrite);
|
|
}
|
|
|
|
export function drainTileUpdates(
|
|
views: SharedTileRingViews,
|
|
maxItems: number,
|
|
out: TileRef[],
|
|
): void {
|
|
const { header, buffer, capacity } = views;
|
|
|
|
let read = Atomics.load(header, TILE_RING_HEADER_READ_INDEX);
|
|
const write = Atomics.load(header, TILE_RING_HEADER_WRITE_INDEX);
|
|
|
|
let count = 0;
|
|
|
|
while (read !== write && count < maxItems) {
|
|
out.push(buffer[read]);
|
|
read = (read + 1) % capacity;
|
|
count++;
|
|
}
|
|
|
|
Atomics.store(header, TILE_RING_HEADER_READ_INDEX, read);
|
|
}
|