/* * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ import { createEmptyVisualInkState } from '../data/visible-state' import { InkStorySaveState, VisualInkState } from '../types' import { InkStory } from '../inkTypes' type InkStoryBinding = { inkStory: InkStory visualInkState: VisualInkState } export class InkBindingManager { protected story: InkStoryBinding protected listeners: InkBindingListenerInterface[] = [] constructor(story: InkStory) { this.setInkStory(story) } addListener(listener: InkBindingListenerInterface) { this.listeners.push(listener) } removeListener(listener: InkBindingListenerInterface) { const index = this.listeners.indexOf(listener) if (index > -1) { this.listeners.splice(index, 1) } } setInkStory(story: InkStory) { this.story = { visualInkState: createEmptyVisualInkState(), inkStory: story, } for (let listener of this.listeners) { if (listener.setInkStory) { listener.setInkStory(story, this.story.visualInkState) } } } getInkStory() { return this.story.inkStory } getVisualInkState() { return this.story.visualInkState } /** * Saves the new visualInkState into the binding and updates all listeners. * @param visualInkState */ updateStoryVisualInkState(visualInkState: VisualInkState) { if (this.story.visualInkState === visualInkState) { return } this.story.visualInkState = visualInkState for (let listener of this.listeners) { if (listener.updateStoryVisualInkState) { listener.updateStoryVisualInkState(this.story.inkStory, visualInkState) } } } /** * Exports the current story to a save state JSON object. * @returns */ exportStory(): InkStorySaveState { const binding = this.story return { storyState: JSON.parse(binding.inkStory.state.ToJson()), visualInkState: { ...binding.visualInkState }, } } /** * Imports a save state JSON object and applies it to the current story. * @param saveState */ importStory(saveState: InkStorySaveState) { const binding = this.story binding.inkStory.state.LoadJsonObj(saveState.storyState) this.updateStoryVisualInkState(saveState.visualInkState) } } export type InkBindingListenerCallback = (story: InkStory, visualInkState: VisualInkState) => void export interface InkBindingListenerInterface { setInkStory?: InkBindingListenerCallback updateStoryVisualInkState?: InkBindingListenerCallback }