UNPKG

polygonjs-engine

Version:

node-based webgl 3D engine https://polygonjs.com

95 lines (85 loc) 3.28 kB
import {BaseNodeClassWithDisplayFlag, BaseNodeType} from '../_Base'; import {CoreGraphNode} from '../../../core/graph/CoreGraphNode'; type DisplayControllerCallback = () => void; export interface DisplayNodeControllerCallbacks { on_display_node_remove: DisplayControllerCallback; on_display_node_set: DisplayControllerCallback; on_display_node_update: DisplayControllerCallback; } /* handles callbacks when the children's display flag is updated */ export class DisplayNodeController { private _initialized: boolean = false; private _graph_node: CoreGraphNode; private _display_node: BaseNodeClassWithDisplayFlag | undefined = undefined; private _on_display_node_remove_callback: DisplayControllerCallback | undefined; private _on_display_node_set_callback: DisplayControllerCallback | undefined; private _on_display_node_update_callback: DisplayControllerCallback | undefined; // TODO: the node could be a different than BaseNodeType // at least there should be a way to infer that it is a node // with children that have a display flag. This would avoid all the flags?.display?... below constructor(protected node: BaseNodeType, callbacks: DisplayNodeControllerCallbacks) { this._graph_node = new CoreGraphNode(node.scene(), 'DisplayNodeController'); (this._graph_node as any).node = node; this._on_display_node_remove_callback = callbacks.on_display_node_remove; this._on_display_node_set_callback = callbacks.on_display_node_set; this._on_display_node_update_callback = callbacks.on_display_node_update; } dispose() { this._graph_node.dispose(); } get display_node() { return this._display_node; } initializeNode() { if (this._initialized) { console.error('display node controller already initialed', this.node); return; } this._initialized = true; this.node.lifecycle.add_on_child_add_hook((child_node) => { if (!this._display_node) { child_node.flags?.display?.set(true); } }); this.node.lifecycle.add_on_child_remove_hook((child_node) => { if (child_node.graphNodeId() == this._display_node?.graphNodeId()) { const children = this.node.children(); const last_child = children[children.length - 1]; if (last_child) { last_child.flags?.display?.set(true); } else { this.set_display_node(undefined); } } }); this._graph_node.dirtyController.addPostDirtyHook('_request_display_node_container', () => { if (this._on_display_node_update_callback) { this._on_display_node_update_callback(); } }); } async set_display_node(new_display_node: BaseNodeClassWithDisplayFlag | undefined) { if (!this._initialized) { console.error('display node controller not initialized', this.node); } if (this._display_node != new_display_node) { const old_display_node = this._display_node; if (old_display_node) { old_display_node.flags.display.set(false); this._graph_node.removeGraphInput(old_display_node); if (this._on_display_node_remove_callback) { this._on_display_node_remove_callback(); } } this._display_node = new_display_node; if (this._display_node) { this._graph_node.addGraphInput(this._display_node); if (this._on_display_node_set_callback) { this._on_display_node_set_callback(); } } } } }