UNPKG

narraleaf-react

Version:

A React visual novel player framework

193 lines (192 loc) 7.87 kB
import { CalledActionResult } from "../nlcore/gameTypes"; import { Awaitable, EventDispatcher, IdManager, Lock, Values } from "../../util/data"; import { MenuData } from "../nlcore/elements/menu"; import { Scene } from "../nlcore/elements/scene"; import { Sound } from "../nlcore/elements/sound"; import * as Howler from "howler"; import { SrcManager } from "../nlcore/action/srcManager"; import { LogicAction } from "../nlcore/action/logicAction"; import { Storable } from "../nlcore/elements/persistent/storable"; import { Game } from "../nlcore/game"; import { Clickable, MenuElement, TextElement } from "./gameState.type"; import { Sentence } from "../nlcore/elements/character/sentence"; import { Logger } from "../../util/logger"; import { Story } from "../nlcore/elements/story"; import { LiveGame } from "../nlcore/game/liveGame"; import { Chosen, ExposedKeys, ExposedState, ExposedStateType } from "./type"; import { AudioManager, AudioManagerDataRaw } from "./lib/AudioManager"; import { Layer } from "../nlcore/elements/layer"; import { GameStateGuard } from "./guard"; import { LiveGameEventToken } from "../nlcore/types"; import * as htmlToImage from "html-to-image"; import { Video, VideoStateRaw } from "../nlcore/elements/video"; import { Timelines } from "./Tasks"; import { Notification, NotificationManager } from "./lib/notification"; import { ActionHistoryManager } from "../../game/nlcore/action/actionHistory"; import { GameHistoryManager } from "../../game/nlcore/action/gameHistory"; type Legacy_PlayerStateElement = { texts: Clickable<TextElement>[]; menus: Clickable<MenuElement, Chosen>[]; displayable: LogicAction.DisplayableElements[]; }; type ScheduleHandle = { retry: () => void; onCleanup: (fn: VoidFunction) => void; }; export type PlayerState = { sounds: Sound[]; videos: Video[]; srcManagers: SrcManager[]; elements: PlayerStateElement[]; }; export type PlayerStateElement = { scene: Scene; /**@deprecated */ ele?: Legacy_PlayerStateElement; layers: Map<Layer, LogicAction.DisplayableElements[]>; texts: Clickable<TextElement>[]; menus: Clickable<MenuElement, Chosen>[]; }; export type PlayerStateData = { scenes: { sceneId: string; elements: { /**@deprecated */ displayable?: string[]; /** * { [layerName]: [displayableId][] } */ layers: Record<string, string[]>; }; }[]; audio: AudioManagerDataRaw; videos: [videoId: string, videoState: VideoStateRaw][]; }; interface StageUtils { update: () => void; forceUpdate: () => void; forceRemount: () => void; next: () => void; } type GameStateEvents = { "event:state.end": []; "event:state.player.skip": [force?: boolean]; "event:state.player.requestFlush": []; "event.state.onExpose": [unknown, ExposedState[ExposedStateType]]; "event:state.onRender": []; "event:state:flushPreloadedScenes": []; }; /** * Core game state management class * Manages all game-related states including sounds, videos, elements and their lifecycle */ export declare class GameState { static EventTypes: { [K in keyof GameStateEvents]: K; }; private state; currentHandling: CalledActionResult | null; stage: StageUtils; game: Game; playerCurrent: HTMLDivElement | null; mainContentNode: HTMLDivElement | null; exposedState: Map<Values<ExposedKeys>, object>; guard: GameStateGuard; timelines: Timelines; preloadingScene: Scene | null; flushDep: number; rollLock: Lock; readonly notificationMgr: NotificationManager; readonly events: EventDispatcher<GameStateEvents>; readonly logger: Logger; readonly audioManager: AudioManager; readonly htmlToImage: typeof htmlToImage; readonly idManager: IdManager; readonly actionHistory: ActionHistoryManager; readonly gameHistory: GameHistoryManager; pageRouter: null; constructor(game: Game, stage: StageUtils); get deps(): number; addVideo(video: Video): this; removeVideo(video: Video): this; isVideoAdded(video: Video): boolean; getVideos(): Video[]; findElementByScene(scene: Scene): PlayerStateElement | null; findElementByDisplayable(displayable: LogicAction.DisplayableElements, layer?: Layer | null): PlayerStateElement | null; getLiveGame(): LiveGame; removeElement(element: PlayerStateElement): this; preloadScene(arg: Scene | Story): this; getPreloadingScene(): Scene | null; addElement(element: PlayerStateElement): this; addScene(scene: Scene): this; flush(): this; popScene(): this; removeScene(scene: Scene): this; getSceneElements(): PlayerStateElement[]; getLastScene(): Scene | null; sceneExists(scene?: Scene): boolean; isSceneActive(scene: Scene): boolean; wait(ms: number): Promise<void>; schedule(callback: (scheduleHandle: ScheduleHandle) => void, ms: number): () => void; notify(notification: Notification): void; handle(action: PlayerAction): this; createDialog(id: string, sentence: Sentence, afterClick?: () => void, scene?: Scene): LiveGameEventToken & { text: string; }; createMenu(menu: MenuData, afterChoose?: (choice: Chosen) => void, scene?: Scene): LiveGameEventToken & { prompt: null | string; }; createDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this; disposeDisplayable(displayable: LogicAction.DisplayableElements, scene?: Scene | null, layer?: Layer | null): this; forceReset(): void; getHowl(): typeof Howler.Howl; registerSrcManager(srcManager: SrcManager): this; offSrcManager(srcManager: SrcManager): this; getStorable(): Storable; getSceneByName(name: string): Scene | null; getStory(): Story; setInterval(callback: () => void, delay: number): NodeJS.Timeout; clearInterval(interval: NodeJS.Timeout): void; setTimeout(callback: () => void, delay: number): NodeJS.Timeout; clearTimeout(timeout: NodeJS.Timeout): void; forceAnimation(): Awaitable; /** * Mounts a new state to the game state manager * @param key - Unique identifier for the state * @param state - State object to be mounted * @returns Object containing unmount function */ mountState<T extends ExposedStateType>(key: ExposedKeys[T], state: ExposedState[T]): { unMount: () => void; }; unMountState(key: Values<ExposedKeys>): this; initVideo(video: Video): this; isStateMounted(key: Values<ExposedKeys>): boolean; getExposedState<T extends ExposedStateType>(key: ExposedKeys[T]): ExposedState[T] | null; getExposedStateForce<T extends ExposedStateType>(key: ExposedKeys[T]): ExposedState[T]; getExposedStateAsync<T extends ExposedStateType>(key: ExposedKeys[T], onExpose: (state: ExposedState[T]) => void): LiveGameEventToken; /** * Dispose of the game state * * This is an irreversible action; once disposed of, the game state can't be used again. * * Don't call this method directly */ dispose(): void; /** * Converts current game state to serializable data format * @returns PlayerStateData object containing all state information */ toData(): PlayerStateData; loadData(data: PlayerStateData, elementMap: Map<string, LogicAction.GameElement>): void; getLastSceneIfNot(scene: Scene | null | void): Scene; createElementSnapshot(element: PlayerStateElement): PlayerStateElementSnapshot; fromElementSnapshot(snapshot: PlayerStateElementSnapshot): PlayerStateElement; private removeElements; private resetLayers; private createWaitableAction; private sceneNotFound; private layerNotFound; private constructLayerMap; } export {};