mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 10:44:16 +00:00
45a8e33562
- Introduced WorkerMetricsEvent and SetWorkerDebugEvent to facilitate communication between the main thread and worker for performance monitoring. - Enhanced ClientGameRunner to emit worker metrics and handle debug configuration updates. - Updated PerformanceOverlay to display worker metrics and allow toggling of debug settings. - Refactored Canvas2DRendererProxy and TerritoryRendererProxy to improve rendering performance and manage render cooldowns. - Added profiling capabilities in Worker.worker.ts to track event loop lag, simulation delays, and message handling metrics.
376 lines
9.2 KiB
TypeScript
376 lines
9.2 KiB
TypeScript
import {
|
|
PlayerActions,
|
|
PlayerBorderTiles,
|
|
PlayerID,
|
|
PlayerProfile,
|
|
} from "../game/Game";
|
|
import { TileRef } from "../game/GameMap";
|
|
import { GameUpdateViewData } from "../game/GameUpdates";
|
|
import { ClientID, GameStartInfo, Turn } from "../Schemas";
|
|
|
|
export type WorkerMessageType =
|
|
| "heartbeat"
|
|
| "init"
|
|
| "initialized"
|
|
| "turn"
|
|
| "game_update"
|
|
| "tile_context"
|
|
| "tile_context_result"
|
|
| "player_actions"
|
|
| "player_actions_result"
|
|
| "player_profile"
|
|
| "player_profile_result"
|
|
| "player_border_tiles"
|
|
| "player_border_tiles_result"
|
|
| "attack_average_position"
|
|
| "attack_average_position_result"
|
|
| "transport_ship_spawn"
|
|
| "transport_ship_spawn_result"
|
|
| "init_renderer"
|
|
| "renderer_ready"
|
|
| "set_patterns_enabled"
|
|
| "set_palette"
|
|
| "set_view_size"
|
|
| "set_view_transform"
|
|
| "set_alternative_view"
|
|
| "set_highlighted_owner"
|
|
| "set_shader_settings"
|
|
| "mark_tile"
|
|
| "mark_all_dirty"
|
|
| "refresh_palette"
|
|
| "refresh_terrain"
|
|
| "tick_renderer"
|
|
| "render_frame"
|
|
| "render_done"
|
|
| "set_worker_debug"
|
|
| "worker_metrics"
|
|
| "renderer_metrics";
|
|
|
|
// Base interface for all messages
|
|
interface BaseWorkerMessage {
|
|
type: WorkerMessageType;
|
|
id?: string;
|
|
/**
|
|
* Cross-thread timestamp (Date.now()) set by the sender when enqueuing the
|
|
* message. Used for queue latency debugging.
|
|
*/
|
|
sentAtWallMs?: number;
|
|
}
|
|
|
|
export interface HeartbeatMessage extends BaseWorkerMessage {
|
|
type: "heartbeat";
|
|
}
|
|
|
|
// Messages from main thread to worker
|
|
export interface InitMessage extends BaseWorkerMessage {
|
|
type: "init";
|
|
gameStartInfo: GameStartInfo;
|
|
clientID: ClientID;
|
|
}
|
|
|
|
export interface TurnMessage extends BaseWorkerMessage {
|
|
type: "turn";
|
|
turn: Turn;
|
|
}
|
|
|
|
// Messages from worker to main thread
|
|
export interface InitializedMessage extends BaseWorkerMessage {
|
|
type: "initialized";
|
|
}
|
|
|
|
export interface GameUpdateMessage extends BaseWorkerMessage {
|
|
type: "game_update";
|
|
gameUpdate: GameUpdateViewData;
|
|
}
|
|
|
|
export interface TileContext {
|
|
hasOwner: boolean;
|
|
ownerSmallId: number | null;
|
|
ownerId: PlayerID | null;
|
|
hasFallout: boolean;
|
|
isDefended: boolean;
|
|
}
|
|
|
|
export interface TileContextMessage extends BaseWorkerMessage {
|
|
type: "tile_context";
|
|
tile: TileRef;
|
|
}
|
|
|
|
export interface TileContextResultMessage extends BaseWorkerMessage {
|
|
type: "tile_context_result";
|
|
result: TileContext;
|
|
}
|
|
|
|
export interface PlayerActionsMessage extends BaseWorkerMessage {
|
|
type: "player_actions";
|
|
playerID: PlayerID;
|
|
x?: number;
|
|
y?: number;
|
|
}
|
|
|
|
export interface PlayerActionsResultMessage extends BaseWorkerMessage {
|
|
type: "player_actions_result";
|
|
result: PlayerActions;
|
|
}
|
|
|
|
export interface PlayerProfileMessage extends BaseWorkerMessage {
|
|
type: "player_profile";
|
|
playerID: number;
|
|
}
|
|
|
|
export interface PlayerProfileResultMessage extends BaseWorkerMessage {
|
|
type: "player_profile_result";
|
|
result: PlayerProfile;
|
|
}
|
|
|
|
export interface PlayerBorderTilesMessage extends BaseWorkerMessage {
|
|
type: "player_border_tiles";
|
|
playerID: PlayerID;
|
|
}
|
|
|
|
export interface PlayerBorderTilesResultMessage extends BaseWorkerMessage {
|
|
type: "player_border_tiles_result";
|
|
result: PlayerBorderTiles;
|
|
}
|
|
|
|
export interface AttackAveragePositionMessage extends BaseWorkerMessage {
|
|
type: "attack_average_position";
|
|
playerID: number;
|
|
attackID: string;
|
|
}
|
|
|
|
export interface AttackAveragePositionResultMessage extends BaseWorkerMessage {
|
|
type: "attack_average_position_result";
|
|
x: number | null;
|
|
y: number | null;
|
|
}
|
|
|
|
export interface TransportShipSpawnMessage extends BaseWorkerMessage {
|
|
type: "transport_ship_spawn";
|
|
playerID: PlayerID;
|
|
targetTile: TileRef;
|
|
}
|
|
|
|
export interface TransportShipSpawnResultMessage extends BaseWorkerMessage {
|
|
type: "transport_ship_spawn_result";
|
|
result: TileRef | false;
|
|
}
|
|
|
|
// Renderer messages from main thread to worker
|
|
export interface InitRendererMessage extends BaseWorkerMessage {
|
|
type: "init_renderer";
|
|
offscreenCanvas: OffscreenCanvas;
|
|
darkMode: boolean; // Whether to use dark theme
|
|
backend?: "webgpu" | "canvas2d";
|
|
}
|
|
|
|
export interface SetPatternsEnabledMessage extends BaseWorkerMessage {
|
|
type: "set_patterns_enabled";
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface SetPaletteMessage extends BaseWorkerMessage {
|
|
type: "set_palette";
|
|
paletteWidth: number;
|
|
maxSmallId: number;
|
|
row0: Uint8Array;
|
|
row1: Uint8Array;
|
|
}
|
|
|
|
export interface SetViewSizeMessage extends BaseWorkerMessage {
|
|
type: "set_view_size";
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export interface SetViewTransformMessage extends BaseWorkerMessage {
|
|
type: "set_view_transform";
|
|
scale: number;
|
|
offsetX: number;
|
|
offsetY: number;
|
|
}
|
|
|
|
export interface SetAlternativeViewMessage extends BaseWorkerMessage {
|
|
type: "set_alternative_view";
|
|
enabled: boolean;
|
|
}
|
|
|
|
export interface SetHighlightedOwnerMessage extends BaseWorkerMessage {
|
|
type: "set_highlighted_owner";
|
|
ownerSmallId: number | null;
|
|
}
|
|
|
|
export interface SetShaderSettingsMessage extends BaseWorkerMessage {
|
|
type: "set_shader_settings";
|
|
territoryShader?: string;
|
|
territoryShaderParams0?: number[];
|
|
territoryShaderParams1?: number[];
|
|
terrainShader?: string;
|
|
terrainShaderParams0?: number[];
|
|
terrainShaderParams1?: number[];
|
|
preSmoothing?: {
|
|
enabled: boolean;
|
|
shaderPath: string;
|
|
params0: number[];
|
|
};
|
|
postSmoothing?: {
|
|
enabled: boolean;
|
|
shaderPath: string;
|
|
params0: number[];
|
|
};
|
|
}
|
|
|
|
export interface MarkTileMessage extends BaseWorkerMessage {
|
|
type: "mark_tile";
|
|
tile: TileRef;
|
|
}
|
|
|
|
export interface MarkAllDirtyMessage extends BaseWorkerMessage {
|
|
type: "mark_all_dirty";
|
|
}
|
|
|
|
export interface RefreshPaletteMessage extends BaseWorkerMessage {
|
|
type: "refresh_palette";
|
|
}
|
|
|
|
export interface RefreshTerrainMessage extends BaseWorkerMessage {
|
|
type: "refresh_terrain";
|
|
}
|
|
|
|
export interface TickRendererMessage extends BaseWorkerMessage {
|
|
type: "tick_renderer";
|
|
}
|
|
|
|
export interface ViewSize {
|
|
width: number;
|
|
height: number;
|
|
}
|
|
|
|
export interface ViewTransform {
|
|
scale: number;
|
|
offsetX: number;
|
|
offsetY: number;
|
|
}
|
|
|
|
export interface RenderFrameMessage extends BaseWorkerMessage {
|
|
type: "render_frame";
|
|
/**
|
|
* Optional per-frame view state. This allows the main thread to coalesce
|
|
* high-frequency camera updates into the existing render message.
|
|
*/
|
|
viewSize?: ViewSize;
|
|
viewTransform?: ViewTransform;
|
|
}
|
|
|
|
// Renderer messages from worker to main thread
|
|
export interface RenderDoneMessage extends BaseWorkerMessage {
|
|
type: "render_done";
|
|
/**
|
|
* Timestamp (performance.now()) in the worker right before starting work.
|
|
*/
|
|
startedAt?: number;
|
|
/**
|
|
* Timestamp (performance.now()) in the worker right after finishing work.
|
|
*/
|
|
endedAt?: number;
|
|
/**
|
|
* Echo of RenderFrameMessage.sentAtWallMs (if provided) so callers can
|
|
* compute queue/processing latency without storing state.
|
|
*/
|
|
sentAtWallMs?: number;
|
|
/**
|
|
* Timestamps (Date.now()) in the worker. Use these for cross-thread latency
|
|
* (Firefox may use a different time origin for performance.now()).
|
|
*/
|
|
startedAtWallMs?: number;
|
|
endedAtWallMs?: number;
|
|
|
|
/**
|
|
* Optional breakdown from the worker's renderAsync implementation.
|
|
* All values are milliseconds.
|
|
*/
|
|
renderWaitPrevGpuMs?: number;
|
|
renderCpuMs?: number;
|
|
renderGetTextureMs?: number;
|
|
renderGpuWaitMs?: number;
|
|
renderWaitPrevGpuTimedOut?: boolean;
|
|
renderGpuWaitTimedOut?: boolean;
|
|
}
|
|
|
|
export interface RendererReadyMessage extends BaseWorkerMessage {
|
|
type: "renderer_ready";
|
|
ok: boolean;
|
|
error?: string;
|
|
}
|
|
|
|
export interface RendererMetricsMessage extends BaseWorkerMessage {
|
|
type: "renderer_metrics";
|
|
computeMs: number;
|
|
}
|
|
|
|
export interface SetWorkerDebugMessage extends BaseWorkerMessage {
|
|
type: "set_worker_debug";
|
|
enabled: boolean;
|
|
intervalMs?: number;
|
|
includeTrace?: boolean;
|
|
}
|
|
|
|
export interface WorkerMetricsMessage extends BaseWorkerMessage {
|
|
type: "worker_metrics";
|
|
intervalMs: number;
|
|
eventLoopLagMsAvg: number;
|
|
eventLoopLagMsMax: number;
|
|
simPumpDelayMsAvg: number;
|
|
simPumpDelayMsMax: number;
|
|
simPumpExecMsAvg: number;
|
|
simPumpExecMsMax: number;
|
|
msgCounts: Record<string, number>;
|
|
msgHandlerMsAvg: Record<string, number>;
|
|
msgHandlerMsMax: Record<string, number>;
|
|
msgQueueMsAvg: Record<string, number>;
|
|
msgQueueMsMax: Record<string, number>;
|
|
trace?: string[];
|
|
}
|
|
|
|
// Union types for type safety
|
|
export type MainThreadMessage =
|
|
| HeartbeatMessage
|
|
| InitMessage
|
|
| TurnMessage
|
|
| TileContextMessage
|
|
| PlayerActionsMessage
|
|
| PlayerProfileMessage
|
|
| PlayerBorderTilesMessage
|
|
| AttackAveragePositionMessage
|
|
| TransportShipSpawnMessage
|
|
| InitRendererMessage
|
|
| SetPatternsEnabledMessage
|
|
| SetPaletteMessage
|
|
| SetViewSizeMessage
|
|
| SetViewTransformMessage
|
|
| SetAlternativeViewMessage
|
|
| SetHighlightedOwnerMessage
|
|
| SetShaderSettingsMessage
|
|
| MarkTileMessage
|
|
| MarkAllDirtyMessage
|
|
| RefreshPaletteMessage
|
|
| RefreshTerrainMessage
|
|
| TickRendererMessage
|
|
| SetWorkerDebugMessage
|
|
| RenderFrameMessage;
|
|
|
|
// Message send from worker
|
|
export type WorkerMessage =
|
|
| InitializedMessage
|
|
| GameUpdateMessage
|
|
| TileContextResultMessage
|
|
| PlayerActionsResultMessage
|
|
| PlayerProfileResultMessage
|
|
| PlayerBorderTilesResultMessage
|
|
| AttackAveragePositionResultMessage
|
|
| TransportShipSpawnResultMessage
|
|
| RenderDoneMessage
|
|
| RendererReadyMessage
|
|
| RendererMetricsMessage
|
|
| WorkerMetricsMessage;
|