import Phaser from 'phaser'; import { effect } from '@preact/signals-core'; import type { GameHost } from 'boardgame-core'; import { DisposableBag, type IDisposable } from '../utils'; type CleanupFn = void | (() => void); export interface GameHostSceneOptions> { gameHost: GameHost; } export abstract class GameHostScene> extends Phaser.Scene implements IDisposable { protected disposables = new DisposableBag(); private _gameHost!: GameHost; public get gameHost(): GameHost { return this._gameHost; } addInterruption(promise: Promise){ this.gameHost?.addInterruption(promise); } addTweenInterruption(tween: Phaser.Tweens.Tween){ this.addInterruption(new Promise( resolve => tween.once('complete', resolve) )); } init(data: GameHostSceneOptions): void { this._gameHost = data.gameHost; } create(): void { this.events.on('shutdown', this.dispose, this); } dispose(): void { this.disposables.dispose(); } /** 获取当前状态的只读快照 */ public get state(): TState { return this.gameHost.context.value; } public addDisposable(disposable: IDisposable){ this.disposables.add(disposable); } /** 注册响应式监听(场景关闭时自动清理) */ public addEffect(fn: () => CleanupFn): void { this.disposables.add(effect(fn)); } }