format codebase with prettier

This commit is contained in:
Evan
2025-02-01 12:05:11 -08:00
parent cd121a5cd4
commit 4ee37323f9
98 changed files with 12190 additions and 10233 deletions
+91 -87
View File
@@ -1,110 +1,114 @@
import { createGameRunner, GameRunner } from "../GameRunner";
import { GameUpdateViewData } from '../game/GameUpdates';
import { GameUpdateViewData } from "../game/GameUpdates";
import {
MainThreadMessage,
WorkerMessage,
InitializedMessage,
PlayerActionsResultMessage,
PlayerProfileResultMessage,
} from './WorkerMessages';
MainThreadMessage,
WorkerMessage,
InitializedMessage,
PlayerActionsResultMessage,
PlayerProfileResultMessage,
} from "./WorkerMessages";
const ctx: Worker = self as any;
let gameRunner: Promise<GameRunner> | null = null;
function gameUpdate(gu: GameUpdateViewData) {
sendMessage({
type: "game_update",
gameUpdate: gu
});
sendMessage({
type: "game_update",
gameUpdate: gu,
});
}
function sendMessage(message: WorkerMessage) {
ctx.postMessage(message);
ctx.postMessage(message);
}
ctx.addEventListener('message', async (e: MessageEvent<MainThreadMessage>) => {
const message = e.data;
ctx.addEventListener("message", async (e: MessageEvent<MainThreadMessage>) => {
const message = e.data;
switch (message.type) {
case 'heartbeat':
break
case 'init':
try {
gameRunner = createGameRunner(
message.gameID,
message.gameConfig,
gameUpdate
).then(gr => {
sendMessage({
type: 'initialized',
id: message.id
} as InitializedMessage);
return gr;
});
} catch (error) {
console.error('Failed to initialize game runner:', error);
throw error;
}
break;
switch (message.type) {
case "heartbeat":
break;
case "init":
try {
gameRunner = createGameRunner(
message.gameID,
message.gameConfig,
gameUpdate,
).then((gr) => {
sendMessage({
type: "initialized",
id: message.id,
} as InitializedMessage);
return gr;
});
} catch (error) {
console.error("Failed to initialize game runner:", error);
throw error;
}
break;
case 'turn':
if (!gameRunner) {
throw new Error('Game runner not initialized');
}
case "turn":
if (!gameRunner) {
throw new Error("Game runner not initialized");
}
try {
const gr = await gameRunner;
await gr.addTurn(message.turn);
} catch (error) {
console.error('Failed to process turn:', error);
throw error;
}
break;
try {
const gr = await gameRunner;
await gr.addTurn(message.turn);
} catch (error) {
console.error("Failed to process turn:", error);
throw error;
}
break;
case 'player_actions':
if (!gameRunner) {
throw new Error('Game runner not initialized');
}
case "player_actions":
if (!gameRunner) {
throw new Error("Game runner not initialized");
}
try {
const actions = (await gameRunner).playerActions(message.playerID, message.x, message.y)
sendMessage({
type: 'player_actions_result',
id: message.id,
result: actions
} as PlayerActionsResultMessage);
} catch (error) {
console.error('Failed to check borders:', error);
throw error;
}
break;
case 'player_profile':
if (!gameRunner) {
throw new Error('Game runner not initialized');
}
try {
const actions = (await gameRunner).playerActions(
message.playerID,
message.x,
message.y,
);
sendMessage({
type: "player_actions_result",
id: message.id,
result: actions,
} as PlayerActionsResultMessage);
} catch (error) {
console.error("Failed to check borders:", error);
throw error;
}
break;
case "player_profile":
if (!gameRunner) {
throw new Error("Game runner not initialized");
}
try {
const profile = (await gameRunner).playerProfile(message.playerID)
sendMessage({
type: 'player_profile_result',
id: message.id,
result: profile
} as PlayerProfileResultMessage);
} catch (error) {
console.error('Failed to check borders:', error);
throw error;
}
break;
default:
console.warn('Unknown message :', message);
}
try {
const profile = (await gameRunner).playerProfile(message.playerID);
sendMessage({
type: "player_profile_result",
id: message.id,
result: profile,
} as PlayerProfileResultMessage);
} catch (error) {
console.error("Failed to check borders:", error);
throw error;
}
break;
default:
console.warn("Unknown message :", message);
}
});
// Error handling
ctx.addEventListener('error', (error) => {
console.error('Worker error:', error);
ctx.addEventListener("error", (error) => {
console.error("Worker error:", error);
});
ctx.addEventListener('unhandledrejection', (event) => {
console.error('Unhandled promise rejection in worker:', event);
});
ctx.addEventListener("unhandledrejection", (event) => {
console.error("Unhandled promise rejection in worker:", event);
});
+144 -124
View File
@@ -1,150 +1,170 @@
import { PlayerActions, PlayerID, PlayerInfo, PlayerProfile } from "../game/Game";
import { ErrorUpdate, GameUpdateViewData } from '../game/GameUpdates';
import {
PlayerActions,
PlayerID,
PlayerInfo,
PlayerProfile,
} from "../game/Game";
import { ErrorUpdate, GameUpdateViewData } from "../game/GameUpdates";
import { GameConfig, GameID, Turn } from "../Schemas";
import { generateID } from "../Util";
import { WorkerMessage } from "./WorkerMessages";
export class WorkerClient {
private worker: Worker;
private isInitialized = false;
private messageHandlers: Map<string, (message: WorkerMessage) => void>;
private gameUpdateCallback?: (update: GameUpdateViewData | ErrorUpdate) => void;
private worker: Worker;
private isInitialized = false;
private messageHandlers: Map<string, (message: WorkerMessage) => void>;
private gameUpdateCallback?: (
update: GameUpdateViewData | ErrorUpdate,
) => void;
constructor(private gameID: GameID, private gameConfig: GameConfig) {
this.worker = new Worker(new URL('./Worker.worker.ts', import.meta.url));
this.messageHandlers = new Map();
constructor(
private gameID: GameID,
private gameConfig: GameConfig,
) {
this.worker = new Worker(new URL("./Worker.worker.ts", import.meta.url));
this.messageHandlers = new Map();
// Set up global message handler
this.worker.addEventListener('message', this.handleWorkerMessage.bind(this));
}
// Set up global message handler
this.worker.addEventListener(
"message",
this.handleWorkerMessage.bind(this),
);
}
private handleWorkerMessage(event: MessageEvent<WorkerMessage>) {
const message = event.data;
private handleWorkerMessage(event: MessageEvent<WorkerMessage>) {
const message = event.data;
switch (message.type) {
case 'game_update':
if (this.gameUpdateCallback && message.gameUpdate) {
this.gameUpdateCallback(message.gameUpdate);
}
break;
case 'initialized':
default:
if (message.id && this.messageHandlers.has(message.id)) {
const handler = this.messageHandlers.get(message.id)!;
handler(message);
this.messageHandlers.delete(message.id);
}
break;
switch (message.type) {
case "game_update":
if (this.gameUpdateCallback && message.gameUpdate) {
this.gameUpdateCallback(message.gameUpdate);
}
break;
case "initialized":
default:
if (message.id && this.messageHandlers.has(message.id)) {
const handler = this.messageHandlers.get(message.id)!;
handler(message);
this.messageHandlers.delete(message.id);
}
break;
}
}
initialize(): Promise<void> {
return new Promise((resolve, reject) => {
const messageId = generateID()
initialize(): Promise<void> {
return new Promise((resolve, reject) => {
const messageId = generateID();
this.messageHandlers.set(messageId, (message) => {
if (message.type === 'initialized') {
this.isInitialized = true;
resolve();
}
});
this.messageHandlers.set(messageId, (message) => {
if (message.type === "initialized") {
this.isInitialized = true;
resolve();
}
});
this.worker.postMessage({
type: 'init',
id: messageId,
gameID: this.gameID,
gameConfig: this.gameConfig
});
this.worker.postMessage({
type: "init",
id: messageId,
gameID: this.gameID,
gameConfig: this.gameConfig,
});
// Add timeout for initialization
setTimeout(() => {
if (!this.isInitialized) {
this.messageHandlers.delete(messageId);
reject(new Error('Worker initialization timeout'));
}
}, 5000); // 5 second timeout
});
}
start(gameUpdate: (gu: GameUpdateViewData | ErrorUpdate) => void) {
// Add timeout for initialization
setTimeout(() => {
if (!this.isInitialized) {
throw new Error('Failed to initialize pathfinder');
this.messageHandlers.delete(messageId);
reject(new Error("Worker initialization timeout"));
}
this.gameUpdateCallback = gameUpdate;
}, 5000); // 5 second timeout
});
}
start(gameUpdate: (gu: GameUpdateViewData | ErrorUpdate) => void) {
if (!this.isInitialized) {
throw new Error("Failed to initialize pathfinder");
}
this.gameUpdateCallback = gameUpdate;
}
sendTurn(turn: Turn) {
if (!this.isInitialized) {
throw new Error("Worker not initialized");
}
sendTurn(turn: Turn) {
if (!this.isInitialized) {
throw new Error('Worker not initialized');
this.worker.postMessage({
type: "turn",
turn,
});
}
sendHeartbeat() {
this.worker.postMessage({
type: "heartbeat",
});
}
playerProfile(playerID: number): Promise<PlayerProfile> {
return new Promise((resolve, reject) => {
if (!this.isInitialized) {
reject(new Error("Worker not initialized"));
return;
}
const messageId = generateID();
this.messageHandlers.set(messageId, (message) => {
if (
message.type === "player_profile_result" &&
message.result !== undefined
) {
resolve(message.result);
}
});
this.worker.postMessage({
type: 'turn',
turn
});
}
this.worker.postMessage({
type: "player_profile",
id: messageId,
playerID: playerID,
});
});
}
sendHeartbeat() {
this.worker.postMessage({
type: 'heartbeat'
});
}
playerInteraction(
playerID: PlayerID,
x: number,
y: number,
): Promise<PlayerActions> {
return new Promise((resolve, reject) => {
if (!this.isInitialized) {
reject(new Error("Worker not initialized"));
return;
}
playerProfile(playerID: number): Promise<PlayerProfile> {
return new Promise((resolve, reject) => {
if (!this.isInitialized) {
reject(new Error('Worker not initialized'));
return;
}
const messageId = generateID();
const messageId = generateID()
this.messageHandlers.set(messageId, (message) => {
if (
message.type === "player_actions_result" &&
message.result !== undefined
) {
resolve(message.result);
}
});
this.messageHandlers.set(messageId, (message) => {
if (message.type === 'player_profile_result' && message.result !== undefined) {
resolve(message.result);
}
});
this.worker.postMessage({
type: "player_actions",
id: messageId,
playerID: playerID,
x: x,
y: y,
});
});
}
this.worker.postMessage({
type: 'player_profile',
id: messageId,
playerID: playerID,
});
})
}
playerInteraction(playerID: PlayerID, x: number, y: number): Promise<PlayerActions> {
return new Promise((resolve, reject) => {
if (!this.isInitialized) {
reject(new Error('Worker not initialized'));
return;
}
const messageId = generateID()
this.messageHandlers.set(messageId, (message) => {
if (message.type === 'player_actions_result' && message.result !== undefined) {
resolve(message.result);
}
});
this.worker.postMessage({
type: 'player_actions',
id: messageId,
playerID: playerID,
x: x,
y: y
});
});
}
cleanup() {
this.worker.terminate();
this.messageHandlers.clear();
this.gameUpdateCallback = undefined;
}
}
cleanup() {
this.worker.terminate();
this.messageHandlers.clear();
this.gameUpdateCallback = undefined;
}
}
+42 -33
View File
@@ -1,74 +1,83 @@
import { GameUpdateViewData } from '../game/GameUpdates';
import { GameUpdateViewData } from "../game/GameUpdates";
import { GameConfig, GameID, Turn } from "../Schemas";
import { PlayerActions, PlayerID, PlayerProfile } from "../game/Game";
export type WorkerMessageType =
| 'heartbeat'
| 'init'
| 'initialized'
| 'turn'
| 'game_update'
| 'player_actions'
| 'player_actions_result'
| 'player_profile'
| 'player_profile_result'
| "heartbeat"
| "init"
| "initialized"
| "turn"
| "game_update"
| "player_actions"
| "player_actions_result"
| "player_profile"
| "player_profile_result";
// Base interface for all messages
interface BaseWorkerMessage {
type: WorkerMessageType;
id?: string;
type: WorkerMessageType;
id?: string;
}
export interface HeartbeatMessage extends BaseWorkerMessage {
type: 'heartbeat'
type: "heartbeat";
}
// Messages from main thread to worker
export interface InitMessage extends BaseWorkerMessage {
type: 'init';
gameID: GameID;
gameConfig: GameConfig;
type: "init";
gameID: GameID;
gameConfig: GameConfig;
}
export interface TurnMessage extends BaseWorkerMessage {
type: 'turn';
turn: Turn;
type: "turn";
turn: Turn;
}
// Messages from worker to main thread
export interface InitializedMessage extends BaseWorkerMessage {
type: 'initialized';
type: "initialized";
}
export interface GameUpdateMessage extends BaseWorkerMessage {
type: 'game_update';
gameUpdate: GameUpdateViewData;
type: "game_update";
gameUpdate: GameUpdateViewData;
}
export interface PlayerActionsMessage extends BaseWorkerMessage {
type: 'player_actions'
playerID: PlayerID
x: number,
y: number
type: "player_actions";
playerID: PlayerID;
x: number;
y: number;
}
export interface PlayerActionsResultMessage extends BaseWorkerMessage {
type: 'player_actions_result';
result: PlayerActions;
type: "player_actions_result";
result: PlayerActions;
}
export interface PlayerProfileMessage extends BaseWorkerMessage {
type: 'player_profile'
playerID: number
type: "player_profile";
playerID: number;
}
export interface PlayerProfileResultMessage extends BaseWorkerMessage {
type: 'player_profile_result'
result: PlayerProfile
type: "player_profile_result";
result: PlayerProfile;
}
// Union types for type safety
export type MainThreadMessage = HeartbeatMessage | InitMessage | TurnMessage | PlayerActionsMessage | PlayerProfileMessage
export type MainThreadMessage =
| HeartbeatMessage
| InitMessage
| TurnMessage
| PlayerActionsMessage
| PlayerProfileMessage;
// Message send from worker
export type WorkerMessage = InitializedMessage | GameUpdateMessage | PlayerActionsResultMessage | PlayerProfileResultMessage
export type WorkerMessage =
| InitializedMessage
| GameUpdateMessage
| PlayerActionsResultMessage
| PlayerProfileResultMessage;