import type { IGameContext, PromptEvent } from 'boardgame-core'; export interface PromptHandlerOptions { commands: IGameContext['commands']; onPrompt: (prompt: PromptEvent) => void; onCancel: (reason?: string) => void; } export class PromptHandler { private commands: IGameContext['commands']; private onPrompt: (prompt: PromptEvent) => void; private onCancel: (reason?: string) => void; private activePrompt: PromptEvent | null = null; private isListening = false; private pendingInput: string | null = null; constructor(options: PromptHandlerOptions) { this.commands = options.commands; this.onPrompt = options.onPrompt; this.onCancel = options.onCancel; } start(): void { this.isListening = true; this.listenForPrompt(); } private listenForPrompt(): void { if (!this.isListening) return; this.commands.promptQueue.pop() .then((promptEvent) => { this.activePrompt = promptEvent; // 如果有等待的输入,自动提交 if (this.pendingInput) { const input = this.pendingInput; this.pendingInput = null; const error = this.activePrompt.tryCommit(input); if (error === null) { this.activePrompt = null; this.listenForPrompt(); } else { // 提交失败,把 prompt 交给 UI 显示错误 this.onPrompt(promptEvent); } return; } this.onPrompt(promptEvent); }) .catch((reason) => { this.activePrompt = null; this.onCancel(reason?.message || 'Cancelled'); }); } /** * Submit an input string to the current prompt. * @returns null on success (input accepted), error string on validation failure */ submit(input: string): string | null { if (!this.activePrompt) { // 没有活跃 prompt,保存为待处理输入 this.pendingInput = input; return null; } const error = this.activePrompt.tryCommit(input); if (error === null) { this.activePrompt = null; this.listenForPrompt(); } return error; } cancel(reason?: string): void { if (this.activePrompt) { this.activePrompt.cancel(reason); this.activePrompt = null; } this.onCancel(reason); } stop(): void { this.isListening = false; if (this.activePrompt) { this.activePrompt.cancel('Handler stopped'); this.activePrompt = null; } } destroy(): void { this.stop(); } } export function createPromptHandler( options: PromptHandlerOptions, ): PromptHandler { return new PromptHandler(options); }