refactor: update GameHost to use generic state and result types
Decouple GameHost from GameState and GameResult types by introducing generic parameters for TState and TResult. This improves type safety and flexibility when defining GameModules.
This commit is contained in:
parent
5c1ef232fd
commit
fb3c98b1ef
|
|
@ -1,29 +1,28 @@
|
||||||
import { ReadonlySignal, Signal } from "@preact/signals-core";
|
|
||||||
import { createPromptContext } from "@/utils/command";
|
import { createPromptContext } from "@/utils/command";
|
||||||
import { createGameContext, IGameContext } from "./game";
|
|
||||||
import { PromptContext } from "@/utils/command/command-prompt";
|
import { PromptContext } from "@/utils/command/command-prompt";
|
||||||
|
import { ReadonlySignal, Signal } from "@preact/signals-core";
|
||||||
|
import { createGameContext, IGameContext } from "./game";
|
||||||
|
|
||||||
export type GameHostStatus = "created" | "running" | "disposed";
|
export type GameHostStatus = "created" | "running" | "disposed";
|
||||||
|
|
||||||
export class GameHost<TModule extends GameModule> {
|
export class GameHost<
|
||||||
readonly state: ReadonlySignal<GameState<TModule>>;
|
TState extends Record<string, unknown>,
|
||||||
|
TResult = unknown,
|
||||||
|
TModule extends GameModule<TState, TResult> = GameModule<TState, TResult>,
|
||||||
|
> {
|
||||||
|
readonly state: ReadonlySignal<TState>;
|
||||||
readonly status: ReadonlySignal<GameHostStatus>;
|
readonly status: ReadonlySignal<GameHostStatus>;
|
||||||
readonly prompts: PromptContext;
|
readonly prompts: PromptContext;
|
||||||
|
|
||||||
private _context: IGameContext<GameState<TModule>>;
|
private _context: IGameContext<TState>;
|
||||||
private _start: (
|
private _start: (ctx: IGameContext<TState>) => Promise<TResult>;
|
||||||
ctx: IGameContext<GameState<TModule>>,
|
|
||||||
) => Promise<GameResult<TModule>>;
|
|
||||||
private _status: Signal<GameHostStatus>;
|
private _status: Signal<GameHostStatus>;
|
||||||
private _createInitialState: () => GameState<TModule>;
|
private _createInitialState: () => TState;
|
||||||
private _eventListeners: Map<"start" | "dispose", Set<() => void>>;
|
private _eventListeners: Map<"start" | "dispose", Set<() => void>>;
|
||||||
private _isDisposed = false;
|
private _isDisposed = false;
|
||||||
|
|
||||||
constructor(public readonly gameModule: TModule) {
|
constructor(public readonly gameModule: TModule) {
|
||||||
const { createInitialState, start } = gameModule as unknown as GameModule<
|
const { createInitialState, start } = gameModule;
|
||||||
GameState<TModule>,
|
|
||||||
GameResult<TModule>
|
|
||||||
>;
|
|
||||||
this._createInitialState = createInitialState;
|
this._createInitialState = createInitialState;
|
||||||
this._eventListeners = new Map();
|
this._eventListeners = new Map();
|
||||||
|
|
||||||
|
|
@ -53,7 +52,7 @@ export class GameHost<TModule extends GameModule> {
|
||||||
this._context._state.clearInterruptions();
|
this._context._state.clearInterruptions();
|
||||||
}
|
}
|
||||||
|
|
||||||
start(seed?: number): Promise<GameResult<TModule>> {
|
start(seed?: number): Promise<TResult> {
|
||||||
if (this._isDisposed) {
|
if (this._isDisposed) {
|
||||||
throw new Error("GameHost is disposed");
|
throw new Error("GameHost is disposed");
|
||||||
}
|
}
|
||||||
|
|
@ -115,15 +114,11 @@ export type GameModule<
|
||||||
createInitialState: () => TState;
|
createInitialState: () => TState;
|
||||||
start: (ctx: IGameContext<TState>) => Promise<TResult>;
|
start: (ctx: IGameContext<TState>) => Promise<TResult>;
|
||||||
};
|
};
|
||||||
export type GameState<TModule extends GameModule> = ReturnType<
|
|
||||||
TModule["createInitialState"]
|
|
||||||
>;
|
|
||||||
export type GameResult<TModule extends GameModule> = Awaited<
|
|
||||||
ReturnType<TModule["start"]>
|
|
||||||
>;
|
|
||||||
|
|
||||||
export function createGameHost<TModule extends GameModule>(
|
export function createGameHost<
|
||||||
gameModule: TModule,
|
TState extends Record<string, unknown> = Record<string, unknown>,
|
||||||
): GameHost<TModule> {
|
TResult = unknown,
|
||||||
|
TModule extends GameModule<TState, TResult> = GameModule<TState, TResult>,
|
||||||
|
>(gameModule: TModule): GameHost<TState, TResult, TModule> {
|
||||||
return new GameHost(gameModule);
|
return new GameHost(gameModule);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,7 @@
|
||||||
export type { IGameContext } from "./core/game";
|
export type { IGameContext } from "./core/game";
|
||||||
export { createPromptDef } from "./core/game";
|
export { createPromptDef } from "./core/game";
|
||||||
|
|
||||||
export type {
|
export type { GameHost, GameHostStatus, GameModule } from "./core/game-host";
|
||||||
GameHost,
|
|
||||||
GameHostStatus,
|
|
||||||
GameModule,
|
|
||||||
GameState,
|
|
||||||
GameResult,
|
|
||||||
} from "./core/game-host";
|
|
||||||
export { createGameHost } from "./core/game-host";
|
export { createGameHost } from "./core/game-host";
|
||||||
|
|
||||||
export type { Part } from "./core/part";
|
export type { Part } from "./core/part";
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue