UNPKG

polygonjs-engine

Version:

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

154 lines (136 loc) 4.72 kB
import {DisplayNodeControllerCallbacks, DisplayNodeController} from '../../../utils/DisplayNodeController'; import {SubnetOutputSopNode} from '../../SubnetOutput'; import {CoreGraphNode} from '../../../../../core/graph/CoreGraphNode'; import {TypedSopNode, BaseSopNodeType} from '../../_Base'; import {NodeContext} from '../../../../poly/NodeContext'; import {GeoNodeChildrenMap} from '../../../../poly/registers/nodes/Sop'; import {NodeParamsConfig} from '../../../utils/params/ParamsConfig'; import {CoreGroup} from '../../../../../core/geometry/Group'; import {ParamsInitData} from '../../../utils/io/IOController'; import {Constructor, valueof} from '../../../../../types/GlobalTypes'; export class SubnetSopNodeLike<T extends NodeParamsConfig> extends TypedSopNode<T> { initializeBaseNode() { super.initializeBaseNode(); this.children_display_controller.initializeNode(); // the inputs will be evaluated by the child input nodes this.cookController.disallow_inputs_evaluation(); } // display_node and children_display controllers public readonly children_display_controller: SopSubnetChildrenDisplayController = new SopSubnetChildrenDisplayController( this ); public readonly display_node_controller: DisplayNodeController = new DisplayNodeController( this, this.children_display_controller.display_node_controller_callbacks() ); // protected _children_controller_context = NodeContext.SOP; createNode<S extends keyof GeoNodeChildrenMap>( node_class: S, params_init_value_overrides?: ParamsInitData ): GeoNodeChildrenMap[S]; createNode<K extends valueof<GeoNodeChildrenMap>>( node_class: Constructor<K>, params_init_value_overrides?: ParamsInitData ): K; createNode<K extends valueof<GeoNodeChildrenMap>>( node_class: Constructor<K>, params_init_value_overrides?: ParamsInitData ): K { return super.createNode(node_class, params_init_value_overrides) as K; } children() { return super.children() as BaseSopNodeType[]; } nodesByType<K extends keyof GeoNodeChildrenMap>(type: K): GeoNodeChildrenMap[K][] { return super.nodesByType(type) as GeoNodeChildrenMap[K][]; } async cook(input_contents: CoreGroup[]) { const child_output_node = this.children_display_controller.output_node(); if (child_output_node) { const container = await child_output_node.requestContainer(); const core_content = container.coreContent(); if (core_content) { this.setCoreGroup(core_content); } else { if (child_output_node.states.error.active()) { this.states.error.set(child_output_node.states.error.message()); } else { this.setObjects([]); } } } else { this.states.error.set('no output node found inside subnet'); } } } export class SopSubnetChildrenDisplayController { private _output_node_needs_update: boolean = true; private _output_node: SubnetOutputSopNode | undefined; private _graph_node: CoreGraphNode | undefined; constructor(private node: SubnetSopNodeLike<any>) {} dispose() { this._graph_node?.dispose(); } display_node_controller_callbacks(): DisplayNodeControllerCallbacks { return { on_display_node_remove: () => { this.node.setDirty(); }, on_display_node_set: () => { this.node.setDirty(); }, on_display_node_update: () => { this.node.setDirty(); }, }; } output_node() { if (this._output_node_needs_update) { this._update_output_node(); } return this._output_node; } initializeNode() { const display_flag = this.node.flags?.display; if (display_flag) { display_flag.add_hook(() => { if (display_flag.active()) { this.node.setDirty(); } }); } this.node.lifecycle.add_on_child_add_hook(() => { this._output_node_needs_update = true; this.node.setDirty(); }); this.node.lifecycle.add_on_child_remove_hook(() => { this._output_node_needs_update = true; this.node.setDirty(); }); } private _update_output_node() { const found_node = this.node.nodesByType(SubnetOutputSopNode.type())[0]; if ( this._output_node == null || found_node == null || this._output_node.graphNodeId() != found_node.graphNodeId() ) { if (this._graph_node && this._output_node) { this._graph_node.removeGraphInput(this._output_node); } this._output_node = found_node; if (this._output_node) { this._graph_node = this._graph_node || this._create_graph_node(); this._graph_node.addGraphInput(this._output_node); } } } private _create_graph_node() { const graph_node = new CoreGraphNode(this.node.scene(), 'subnet_children_display_controller'); graph_node.addPostDirtyHook('subnet_children_display_controller', () => { this.node.setDirty(); }); return graph_node; } }