/**
* MapStore
* 塗り状態グリッドと差分更新キューを保持して提供する
*/
import { domain } from "@repo/shared";
import { createInitialGridColors } from "./mapGrid.js";
import { paintCellIfChanged } from "./mapPainting.js";
type MapGridSize = {
gridCols: number;
gridRows: number;
};
/** ルーム内マップの塗り状態と更新差分を管理するストア */
export class MapStore {
// 全マスの現在の色(teamId)を保持
private gridColors: number[];
// 次回の送信ループで送る差分リスト
private pendingUpdates: domain.game.gridMap.CellUpdate[];
constructor(size?: MapGridSize) {
// 初期状態は -1 (無色) などで初期化
this.gridColors = createInitialGridColors(size);
this.pendingUpdates = [];
}
/**
* マスを塗り,色が変化した場合のみ差分キューに追加する
* @returns 色が実際に変わった場合 true
*/
public paintCell(index: number, teamId: number): boolean {
return paintCellIfChanged({
gridColors: this.gridColors,
pendingUpdates: this.pendingUpdates,
index,
teamId,
});
}
/**
* 溜まっている差分を取得し,キューをクリアする(ループ送信時に使用)
* 参照をそのまま返却し新しい空配列で差し替えることでコピーを回避する
*/
public getAndClearUpdates(): domain.game.gridMap.CellUpdate[] {
const updates = this.pendingUpdates;
this.pendingUpdates = [];
return updates;
}
/** 現在のマップ塗り状態を読み取り専用参照として返す(コピーなし) */
public getGridColorsSnapshot(): readonly number[] {
return this.gridColors;
}
}