refactor: update api

This commit is contained in:
2026-04-02 12:48:29 +08:00
parent 846badc081
commit 004d49c36f
4 changed files with 128 additions and 66 deletions
+30 -14
View File
@@ -11,37 +11,53 @@ import {
} from "../utils/command";
import {AsyncQueue} from "../utils/async-queue";
export interface IGameContext {
export interface IGameContext<TState extends {} = {}> {
parts: ReturnType<typeof createEntityCollection<Part>>;
regions: ReturnType<typeof createEntityCollection<Region>>;
commands: CommandRunnerContextExport<IGameContext>;
commands: CommandRunnerContextExport<IGameContext<TState>>;
prompts: AsyncQueue<PromptEvent>;
}
/**
* creates a game context.
* expects a command registry already registered with commands.
* @param commandRegistry
*/
export function createGameContext(commandRegistry: CommandRegistry<IGameContext>) {
export function createGameContext<TState extends {} = {}>(
commandRegistry: CommandRegistry<IGameContext<TState>>,
initialState?: TState | (() => TState)
): IGameContext<TState> {
const parts = createEntityCollection<Part>();
const regions = createEntityCollection<Region>();
const ctx: IGameContext = {
const prompts = new AsyncQueue<PromptEvent>();
const state: TState = typeof initialState === 'function' ? (initialState as (() => TState))() : (initialState ?? {} as TState);
const ctx = {
parts,
regions,
prompts,
commands: null!,
prompts: new AsyncQueue(),
};
state,
} as IGameContext<TState>
ctx.commands = createCommandRunnerContext(commandRegistry, ctx);
ctx.commands.on('prompt', (prompt: PromptEvent) => ctx.prompts.push(prompt));
return ctx;
}
export function createGameCommand<TResult>(
/**
* so that we can do `import * as tictactoe from './tic-tac-toe.ts';\n\n createGameContextFromModule(tictactoe);`
* @param module
*/
export function createGameContextFromModule<TState extends {} = {}>(
module: {
registry: CommandRegistry<IGameContext<TState>>,
createInitialState: () => TState
},
): IGameContext<TState> {
return createGameContext(module.registry, module.createInitialState);
}
export function createGameCommand<TState extends {} = {}, TResult = unknown>(
schema: CommandSchema | string,
run: (this: CommandRunnerContext<IGameContext>, command: Command) => Promise<TResult>
): CommandRunner<IGameContext, TResult> {
run: (this: CommandRunnerContext<IGameContext<TState>>, command: Command) => Promise<TResult>
): CommandRunner<IGameContext<TState>, TResult> {
return {
schema: typeof schema === 'string' ? parseCommandSchema(schema) : schema,
run,