refactor: add promptEnd event
This commit is contained in:
parent
697d23e932
commit
6c8d6e0790
|
|
@ -60,25 +60,14 @@ export class GameHost<TState extends Record<string, unknown>> {
|
|||
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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<TContext>(
|
|||
return registry.get(name);
|
||||
}
|
||||
|
||||
type Listener = (e: PromptEvent) => void;
|
||||
type PromptListener = (e: PromptEvent) => void;
|
||||
type PromptEndListener = () => void;
|
||||
|
||||
export type CommandRunnerContextExport<TContext> = CommandRunnerContext<TContext> & {
|
||||
registry: CommandRegistry<TContext>;
|
||||
|
|
@ -54,14 +55,29 @@ export function createCommandRunnerContext<TContext>(
|
|||
registry: CommandRegistry<TContext>,
|
||||
context: TContext
|
||||
): CommandRunnerContextExport<TContext> {
|
||||
const listeners = new Set<Listener>();
|
||||
const promptListeners = new Set<PromptListener>();
|
||||
const promptEndListeners = new Set<PromptEndListener>();
|
||||
|
||||
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 = <T extends keyof CommandRunnerEvents>(_event: T, listener: (e: CommandRunnerEvents[T]) => void) => {
|
||||
if (_event === 'prompt') {
|
||||
promptListeners.add(listener as PromptListener);
|
||||
} else {
|
||||
promptEndListeners.add(listener as PromptEndListener);
|
||||
}
|
||||
};
|
||||
|
||||
const off = <T extends keyof CommandRunnerEvents>(_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<TContext>(
|
|||
const result = activePrompt.tryCommit(commandOrInput);
|
||||
if (result === null) {
|
||||
activePrompt = null;
|
||||
emitPromptEnd();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
@ -81,6 +98,7 @@ export function createCommandRunnerContext<TContext>(
|
|||
if (activePrompt) {
|
||||
activePrompt.cancel(reason);
|
||||
activePrompt = null;
|
||||
emitPromptEnd();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -106,7 +124,7 @@ export function createCommandRunnerContext<TContext>(
|
|||
};
|
||||
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<TContext>(
|
|||
get(){
|
||||
if (!promptQueue) {
|
||||
promptQueue = new AsyncQueue();
|
||||
listeners.add(async (event) => {
|
||||
promptListeners.add(async (event) => {
|
||||
promptQueue.push(event);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ export type PromptEvent = {
|
|||
|
||||
export type CommandRunnerEvents = {
|
||||
prompt: PromptEvent;
|
||||
/** 当 prompt 结束(tryCommit 成功或 cancel)时触发 */
|
||||
promptEnd: void;
|
||||
};
|
||||
|
||||
export type CommandResult<T=unknown> = {
|
||||
|
|
|
|||
Loading…
Reference in New Issue