mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 10:34:16 +00:00
Implement tile state change handling in Game and Worker components
- Added an optional `onTileStateChanged` hook in the Game interface - Refactored GameImpl to utilize the new hook for reporting tile state changes instead of emitting GameUpdateType.Tile updates. - Updated Worker.worker.ts to integrate the new tile state change handling
This commit is contained in:
@@ -108,8 +108,8 @@ export class TerritoryLayer implements Layer {
|
||||
this.syncPaletteMaybe(now);
|
||||
|
||||
// Renderer tick and dirty-tile marking are driven in the worker from
|
||||
// simulation-derived tile updates (tileUpdateSink). The main thread only
|
||||
// drives render frames + view transforms.
|
||||
// simulation-derived tile mutations (onTileStateChanged). The main thread
|
||||
// only drives render frames + view transforms.
|
||||
|
||||
FrameProfiler.end("TerritoryLayer:tick", tickProfile);
|
||||
}
|
||||
|
||||
@@ -733,6 +733,12 @@ export interface Game extends GameMap {
|
||||
callback: (neighbor: TileRef) => void,
|
||||
): void;
|
||||
|
||||
/**
|
||||
* Optional hook for tile state changes. When set, tile mutations should call
|
||||
* this instead of emitting GameUpdateType.Tile updates.
|
||||
*/
|
||||
onTileStateChanged?: (tile: TileRef) => void;
|
||||
|
||||
// Player Management
|
||||
player(id: PlayerID): Player;
|
||||
players(): Player[];
|
||||
|
||||
+18
-13
@@ -84,6 +84,7 @@ export class GameImpl implements Game {
|
||||
|
||||
private updates: GameUpdates = createGameUpdatesMap();
|
||||
private unitGrid: UnitGrid;
|
||||
public onTileStateChanged?: (tile: TileRef) => void;
|
||||
|
||||
private playerTeams: Team[];
|
||||
private botTeam: Team = ColoredTeams.Bot;
|
||||
@@ -234,6 +235,17 @@ export class GameImpl implements Game {
|
||||
(this.updates[update.type] as GameUpdate[]).push(update);
|
||||
}
|
||||
|
||||
private reportTileStateChanged(tile: TileRef): void {
|
||||
if (this.onTileStateChanged) {
|
||||
this.onTileStateChanged(tile);
|
||||
return;
|
||||
}
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
}
|
||||
|
||||
nextUnitID(): number {
|
||||
const old = this._nextUnitID;
|
||||
this._nextUnitID++;
|
||||
@@ -248,10 +260,7 @@ export class GameImpl implements Game {
|
||||
return;
|
||||
}
|
||||
this._map.setFallout(tile, value);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.reportTileStateChanged(tile);
|
||||
}
|
||||
|
||||
units(...types: UnitType[]): Unit[] {
|
||||
@@ -594,10 +603,7 @@ export class GameImpl implements Game {
|
||||
owner._lastTileChange = this._ticks;
|
||||
this.updateBorders(tile);
|
||||
this._map.setFallout(tile, false);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.reportTileStateChanged(tile);
|
||||
}
|
||||
|
||||
relinquish(tile: TileRef) {
|
||||
@@ -615,10 +621,7 @@ export class GameImpl implements Game {
|
||||
|
||||
this._map.setOwnerID(tile, 0);
|
||||
this.updateBorders(tile);
|
||||
this.addUpdate({
|
||||
type: GameUpdateType.Tile,
|
||||
update: this.toTileUpdate(tile),
|
||||
});
|
||||
this.reportTileStateChanged(tile);
|
||||
}
|
||||
|
||||
private updateBorders(tile: TileRef) {
|
||||
@@ -951,7 +954,8 @@ export class GameImpl implements Game {
|
||||
return this._map.hasOwner(ref);
|
||||
}
|
||||
setOwnerID(ref: TileRef, playerId: number): void {
|
||||
return this._map.setOwnerID(ref, playerId);
|
||||
this._map.setOwnerID(ref, playerId);
|
||||
this.reportTileStateChanged(ref);
|
||||
}
|
||||
hasFallout(ref: TileRef): boolean {
|
||||
return this._map.hasFallout(ref);
|
||||
@@ -961,6 +965,7 @@ export class GameImpl implements Game {
|
||||
}
|
||||
setDefended(ref: TileRef, value: boolean): void {
|
||||
this._map.setDefended(ref, value);
|
||||
this.reportTileStateChanged(ref);
|
||||
}
|
||||
isBorder(ref: TileRef): boolean {
|
||||
return this._map.isBorder(ref);
|
||||
|
||||
@@ -4,7 +4,6 @@ import { PastelTheme } from "../configuration/PastelTheme";
|
||||
import { PastelThemeDark } from "../configuration/PastelThemeDark";
|
||||
import { FetchGameMapLoader } from "../game/FetchGameMapLoader";
|
||||
import { PlayerID } from "../game/Game";
|
||||
import { TileRef } from "../game/GameMap";
|
||||
import {
|
||||
AllianceExpiredUpdate,
|
||||
AllianceRequestReplyUpdate,
|
||||
@@ -575,9 +574,9 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
// Capacity is bounded; on overflow we fall back to markAllDirty().
|
||||
dirtyTiles = new DirtyTileQueue(numTiles, Math.max(4096, numTiles));
|
||||
dirtyTilesOverflow = false;
|
||||
renderTileState = new Uint16Array(gr.game.tileStateView());
|
||||
renderTileState = gr.game.tileStateView();
|
||||
|
||||
gr.tileUpdateSink = (packedUpdate) => {
|
||||
gr.game.onTileStateChanged = (tile) => {
|
||||
if (!dirtyTiles) {
|
||||
return;
|
||||
}
|
||||
@@ -585,11 +584,6 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const tile = Number(packedUpdate >> 16n) as TileRef;
|
||||
const state = Number(packedUpdate & 0xffffn);
|
||||
if (renderTileState) {
|
||||
renderTileState[tile] = state;
|
||||
}
|
||||
const mark = (t: any) => {
|
||||
if (!dirtyTiles!.mark(t)) {
|
||||
dirtyTilesOverflow = true;
|
||||
@@ -798,7 +792,7 @@ ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
|
||||
? new WorkerCanvas2DRenderer()
|
||||
: new WorkerTerritoryRenderer();
|
||||
|
||||
renderTileState ??= new Uint16Array(gr.game.tileStateView());
|
||||
renderTileState ??= gr.game.tileStateView();
|
||||
await renderer.init(
|
||||
message.offscreenCanvas,
|
||||
gr,
|
||||
|
||||
Reference in New Issue
Block a user