refactor: reformat code and fix type signatures in GameHost
Reformat `src/core/game-host.ts` to use double quotes and consistent spacing. Update `createGameHost` to correctly propagate the `TResult` generic from `GameModule`.
This commit is contained in:
parent
8142fbfa60
commit
1e1d04777f
|
|
@ -1,14 +1,18 @@
|
||||||
import { ReadonlySignal, Signal } from '@preact/signals-core';
|
import { ReadonlySignal, Signal } from "@preact/signals-core";
|
||||||
|
import { CommandSchema, CommandRegistry, PromptEvent } from "@/utils/command";
|
||||||
import {
|
import {
|
||||||
CommandSchema,
|
createGameCommandRegistry,
|
||||||
CommandRegistry,
|
createGameContext,
|
||||||
PromptEvent,
|
IGameContext,
|
||||||
} from '@/utils/command';
|
PromptDef,
|
||||||
import {createGameCommandRegistry, createGameContext, IGameContext, PromptDef} from './game';
|
} from "./game";
|
||||||
|
|
||||||
export type GameHostStatus = 'created' | 'running' | 'disposed';
|
export type GameHostStatus = "created" | "running" | "disposed";
|
||||||
|
|
||||||
export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
export class GameHost<
|
||||||
|
TState extends Record<string, unknown>,
|
||||||
|
TResult = unknown,
|
||||||
|
> {
|
||||||
readonly state: ReadonlySignal<TState>;
|
readonly state: ReadonlySignal<TState>;
|
||||||
readonly status: ReadonlySignal<GameHostStatus>;
|
readonly status: ReadonlySignal<GameHostStatus>;
|
||||||
readonly activePromptSchema: ReadonlySignal<CommandSchema | null>;
|
readonly activePromptSchema: ReadonlySignal<CommandSchema | null>;
|
||||||
|
|
@ -22,13 +26,13 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
private _activePromptPlayer: Signal<string | null>;
|
private _activePromptPlayer: Signal<string | null>;
|
||||||
private _activePromptHint: Signal<string | null>;
|
private _activePromptHint: Signal<string | null>;
|
||||||
private _createInitialState: () => TState;
|
private _createInitialState: () => TState;
|
||||||
private _eventListeners: Map<'start' | 'dispose', Set<() => void>>;
|
private _eventListeners: Map<"start" | "dispose", Set<() => void>>;
|
||||||
private _isDisposed = false;
|
private _isDisposed = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
registry: CommandRegistry<IGameContext<TState>>,
|
registry: CommandRegistry<IGameContext<TState>>,
|
||||||
createInitialState: () => TState,
|
createInitialState: () => TState,
|
||||||
start: (ctx: IGameContext<TState>) => Promise<TResult>
|
start: (ctx: IGameContext<TState>) => Promise<TResult>,
|
||||||
) {
|
) {
|
||||||
this._createInitialState = createInitialState;
|
this._createInitialState = createInitialState;
|
||||||
this._eventListeners = new Map();
|
this._eventListeners = new Map();
|
||||||
|
|
@ -38,7 +42,7 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
this._start = start;
|
this._start = start;
|
||||||
this.state = this._context._state;
|
this.state = this._context._state;
|
||||||
|
|
||||||
this._status = new Signal<GameHostStatus>('created');
|
this._status = new Signal<GameHostStatus>("created");
|
||||||
this.status = this._status;
|
this.status = this._status;
|
||||||
|
|
||||||
this._activePromptSchema = new Signal<CommandSchema | null>(null);
|
this._activePromptSchema = new Signal<CommandSchema | null>(null);
|
||||||
|
|
@ -56,14 +60,14 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
private _setupPromptTracking() {
|
private _setupPromptTracking() {
|
||||||
let currentPromptEvent: PromptEvent | null = null;
|
let currentPromptEvent: PromptEvent | null = null;
|
||||||
|
|
||||||
this._context._commands.on('prompt', (e) => {
|
this._context._commands.on("prompt", (e) => {
|
||||||
currentPromptEvent = e as PromptEvent;
|
currentPromptEvent = e as PromptEvent;
|
||||||
this._activePromptSchema.value = currentPromptEvent.schema;
|
this._activePromptSchema.value = currentPromptEvent.schema;
|
||||||
this._activePromptPlayer.value = currentPromptEvent.currentPlayer;
|
this._activePromptPlayer.value = currentPromptEvent.currentPlayer;
|
||||||
this._activePromptHint.value = currentPromptEvent.hintText || null;
|
this._activePromptHint.value = currentPromptEvent.hintText || null;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._context._commands.on('promptEnd', () => {
|
this._context._commands.on("promptEnd", () => {
|
||||||
currentPromptEvent = null;
|
currentPromptEvent = null;
|
||||||
this._activePromptSchema.value = null;
|
this._activePromptSchema.value = null;
|
||||||
this._activePromptPlayer.value = null;
|
this._activePromptPlayer.value = null;
|
||||||
|
|
@ -78,17 +82,17 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
|
|
||||||
tryInput(input: string): string | null {
|
tryInput(input: string): string | null {
|
||||||
if (this._isDisposed) {
|
if (this._isDisposed) {
|
||||||
return 'GameHost is disposed';
|
return "GameHost is disposed";
|
||||||
}
|
}
|
||||||
return this._context._commands._tryCommit(input);
|
return this._context._commands._tryCommit(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
tryAnswerPrompt<TArgs extends any[]>(def: PromptDef<TArgs>, ...args: TArgs){
|
tryAnswerPrompt<TArgs extends any[]>(def: PromptDef<TArgs>, ...args: TArgs) {
|
||||||
return this._context._commands._tryCommit({
|
return this._context._commands._tryCommit({
|
||||||
name: def.schema.name,
|
name: def.schema.name,
|
||||||
params: args,
|
params: args,
|
||||||
options: {},
|
options: {},
|
||||||
flags: {}
|
flags: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -110,7 +114,7 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
|
|
||||||
start(seed?: number): Promise<TResult> {
|
start(seed?: number): Promise<TResult> {
|
||||||
if (this._isDisposed) {
|
if (this._isDisposed) {
|
||||||
throw new Error('GameHost is disposed');
|
throw new Error("GameHost is disposed");
|
||||||
}
|
}
|
||||||
|
|
||||||
this._context._commands._cancel();
|
this._context._commands._cancel();
|
||||||
|
|
@ -122,8 +126,8 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
this._context._rng.setSeed(seed);
|
this._context._rng.setSeed(seed);
|
||||||
const promise = this._start(this._context);
|
const promise = this._start(this._context);
|
||||||
|
|
||||||
this._status.value = 'running';
|
this._status.value = "running";
|
||||||
this._emitEvent('start');
|
this._emitEvent("start");
|
||||||
|
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
@ -135,14 +139,14 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
|
|
||||||
this._isDisposed = true;
|
this._isDisposed = true;
|
||||||
this._context._commands._cancel();
|
this._context._commands._cancel();
|
||||||
this._status.value = 'disposed';
|
this._status.value = "disposed";
|
||||||
|
|
||||||
// Emit dispose event BEFORE clearing listeners
|
// Emit dispose event BEFORE clearing listeners
|
||||||
this._emitEvent('dispose');
|
this._emitEvent("dispose");
|
||||||
this._eventListeners.clear();
|
this._eventListeners.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
on(event: 'start' | 'dispose', listener: () => void): () => void {
|
on(event: "start" | "dispose", listener: () => void): () => void {
|
||||||
if (!this._eventListeners.has(event)) {
|
if (!this._eventListeners.has(event)) {
|
||||||
this._eventListeners.set(event, new Set());
|
this._eventListeners.set(event, new Set());
|
||||||
}
|
}
|
||||||
|
|
@ -153,7 +157,7 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private _emitEvent(event: 'start' | 'dispose') {
|
private _emitEvent(event: "start" | "dispose") {
|
||||||
const listeners = this._eventListeners.get(event);
|
const listeners = this._eventListeners.get(event);
|
||||||
if (listeners) {
|
if (listeners) {
|
||||||
for (const listener of listeners) {
|
for (const listener of listeners) {
|
||||||
|
|
@ -163,18 +167,22 @@ export class GameHost<TState extends Record<string, unknown>, TResult=unknown> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type GameModule<TState extends Record<string, unknown>, TResult=unknown> = {
|
export type GameModule<
|
||||||
|
TState extends Record<string, unknown>,
|
||||||
|
TResult = unknown,
|
||||||
|
> = {
|
||||||
registry?: CommandRegistry<IGameContext<TState>>;
|
registry?: CommandRegistry<IGameContext<TState>>;
|
||||||
createInitialState: () => TState;
|
createInitialState: () => TState;
|
||||||
start: (ctx: IGameContext<TState>) => Promise<TResult>;
|
start: (ctx: IGameContext<TState>) => Promise<TResult>;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function createGameHost<TState extends Record<string, unknown>>(
|
export function createGameHost<
|
||||||
gameModule: GameModule<TState>
|
TState extends Record<string, unknown>,
|
||||||
): GameHost<TState> {
|
TResult = unknown,
|
||||||
|
>(gameModule: GameModule<TState, TResult>): GameHost<TState, TResult> {
|
||||||
return new GameHost(
|
return new GameHost(
|
||||||
gameModule.registry || createGameCommandRegistry(),
|
gameModule.registry || createGameCommandRegistry(),
|
||||||
gameModule.createInitialState,
|
gameModule.createInitialState,
|
||||||
gameModule.start
|
gameModule.start,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue