From 6c8d6e0790905e5eb15ac800b486b15179f9317d Mon Sep 17 00:00:00 2001 From: hypercross Date: Sat, 4 Apr 2026 00:59:40 +0800 Subject: [PATCH] refactor: add promptEnd event --- src/core/game-host.ts | 19 +++----------- src/utils/command/command-registry.ts | 36 ++++++++++++++++++++------- src/utils/command/command-runner.ts | 2 ++ 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/core/game-host.ts b/src/core/game-host.ts index d469089..bf371de 100644 --- a/src/core/game-host.ts +++ b/src/core/game-host.ts @@ -60,25 +60,14 @@ export class GameHost> { this._activePromptSchema.value = activePrompt?.schema ?? null; }; - // Wrap _tryCommit to update schema after commit - const originalTryCommit = this.commands._tryCommit.bind(this.commands); - (this.commands as any)._tryCommit = (input: string) => { - const result = originalTryCommit(input); - updateSchema(); - return result; - }; - - // Wrap _cancel to update schema after cancel - const originalCancel = this.commands._cancel.bind(this.commands); - (this.commands as any)._cancel = (reason?: string) => { - originalCancel(reason); - updateSchema(); - }; - this.commands.on('prompt', () => { updateSchema(); }); + this.commands.on('promptEnd', () => { + updateSchema(); + }); + updateSchema(); } diff --git a/src/utils/command/command-registry.ts b/src/utils/command/command-registry.ts index e543283..2b3d62a 100644 --- a/src/utils/command/command-registry.ts +++ b/src/utils/command/command-registry.ts @@ -1,5 +1,5 @@ import type { Command, CommandSchema } from './types'; -import type {CommandResult, CommandRunner, CommandRunnerContext, PromptEvent} from './command-runner'; +import type {CommandResult, CommandRunner, CommandRunnerContext, CommandRunnerEvents, PromptEvent} from './command-runner'; import { parseCommand } from './command-parse'; import { applyCommandSchema } from './command-validate'; import { parseCommandSchema } from './schema-parse'; @@ -39,7 +39,8 @@ export function getCommand( return registry.get(name); } -type Listener = (e: PromptEvent) => void; +type PromptListener = (e: PromptEvent) => void; +type PromptEndListener = () => void; export type CommandRunnerContextExport = CommandRunnerContext & { registry: CommandRegistry; @@ -54,14 +55,29 @@ export function createCommandRunnerContext( registry: CommandRegistry, context: TContext ): CommandRunnerContextExport { - const listeners = new Set(); + const promptListeners = new Set(); + const promptEndListeners = new Set(); - const on = (_event: 'prompt', listener: Listener) => { - listeners.add(listener); + const emitPromptEnd = () => { + for (const listener of promptEndListeners) { + listener(); + } }; - const off = (_event: 'prompt', listener: Listener) => { - listeners.delete(listener); + const on = (_event: T, listener: (e: CommandRunnerEvents[T]) => void) => { + if (_event === 'prompt') { + promptListeners.add(listener as PromptListener); + } else { + promptEndListeners.add(listener as PromptEndListener); + } + }; + + const off = (_event: T, listener: (e: CommandRunnerEvents[T]) => void) => { + if (_event === 'prompt') { + promptListeners.delete(listener as PromptListener); + } else { + promptEndListeners.delete(listener as PromptEndListener); + } }; let activePrompt: PromptEvent | null = null; @@ -71,6 +87,7 @@ export function createCommandRunnerContext( const result = activePrompt.tryCommit(commandOrInput); if (result === null) { activePrompt = null; + emitPromptEnd(); } return result; } @@ -81,6 +98,7 @@ export function createCommandRunnerContext( if (activePrompt) { activePrompt.cancel(reason); activePrompt = null; + emitPromptEnd(); } }; @@ -106,7 +124,7 @@ export function createCommandRunnerContext( }; activePrompt = { schema: resolvedSchema, tryCommit, cancel }; const event: PromptEvent = { schema: resolvedSchema, tryCommit, cancel }; - for (const listener of listeners) { + for (const listener of promptListeners) { listener(event); } }); @@ -136,7 +154,7 @@ export function createCommandRunnerContext( get(){ if (!promptQueue) { promptQueue = new AsyncQueue(); - listeners.add(async (event) => { + promptListeners.add(async (event) => { promptQueue.push(event); }); } diff --git a/src/utils/command/command-runner.ts b/src/utils/command/command-runner.ts index aa34363..77c1d44 100644 --- a/src/utils/command/command-runner.ts +++ b/src/utils/command/command-runner.ts @@ -17,6 +17,8 @@ export type PromptEvent = { export type CommandRunnerEvents = { prompt: PromptEvent; + /** 当 prompt 结束(tryCommit 成功或 cancel)时触发 */ + promptEnd: void; }; export type CommandResult = {