@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
131 lines (130 loc) • 4.51 kB
JavaScript
"use strict";
import { CoreGraphNode } from "../../../core/graph/CoreGraphNode";
const DEFAULT_DISPLAY_NODE_CONTROLLER_OPTIONS = {
dependsOnDisplayNode: true
};
function _warnNotInitialized(node) {
console.error("displayNodeController not initialized", node);
}
function _warnAlreadyInitialized(node) {
console.error("displayNodeController already initialed", node);
}
export class DisplayNodeController {
// 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(node, callbacks, options = DEFAULT_DISPLAY_NODE_CONTROLLER_OPTIONS) {
this.node = node;
this.options = options;
this._initialized = false;
this._displayNode = void 0;
this._displayNodeOverride = void 0;
this._graphNode = new CoreGraphNode(node.scene(), `DisplayNodeController-${node.name()}`);
this._onDisplayNodeRemoveCallback = callbacks.onDisplayNodeRemove;
this._onDisplayNodeSetCallback = callbacks.onDisplayNodeSet;
this._onDisplayNodeUpdateCallback = callbacks.onDisplayNodeUpdate;
}
dispose() {
this._graphNode.dispose();
}
displayNode() {
return this._displayNodeOverride || this._displayNode;
}
firstNonBypassedDisplayNode() {
var _a;
return (_a = this.displayNode()) == null ? void 0 : _a.containerController.firstNonBypassedNode();
}
initializeNode() {
if (this._initialized) {
_warnAlreadyInitialized(this.node);
return;
}
this._initialized = true;
this.node.lifecycle.onChildAdd((childNode) => {
var _a, _b;
if (!this._displayNode) {
(_b = (_a = childNode.flags) == null ? void 0 : _a.display) == null ? void 0 : _b.set(true);
}
});
this.node.lifecycle.onChildRemove((childNode) => {
var _a, _b;
if (childNode.graphNodeId() == ((_a = this._displayNode) == null ? void 0 : _a.graphNodeId())) {
const children = this.node.children();
for (let i = children.length - 1; i >= 0; i--) {
const child = children[i];
const displayFlag = (_b = child.flags) == null ? void 0 : _b.display;
if (displayFlag) {
displayFlag.set(true);
return;
}
}
this.setDisplayNode(void 0);
}
});
this._graphNode.dirtyController.addPostDirtyHook("_requestDisplayNodeContainer", () => {
if (this._onDisplayNodeUpdateCallback) {
this._onDisplayNodeUpdateCallback();
}
});
}
setDisplayNodeOverride(newDisplayNodeOverride) {
if (!this._initialized) {
_warnNotInitialized(this.node);
}
const currentDisplayNode = this._displayNodeOverride;
if (currentDisplayNode != newDisplayNodeOverride) {
const oldDisplayNode = currentDisplayNode;
if (oldDisplayNode) {
if (this.options.dependsOnDisplayNode) {
this._graphNode.removeGraphInput(oldDisplayNode);
}
if (this._onDisplayNodeRemoveCallback) {
this._onDisplayNodeRemoveCallback();
}
}
this._displayNodeOverride = newDisplayNodeOverride;
if (newDisplayNodeOverride) {
if (this.options.dependsOnDisplayNode) {
this._graphNode.addGraphInput(newDisplayNodeOverride);
}
if (this._onDisplayNodeSetCallback) {
this._onDisplayNodeSetCallback();
}
} else {
if (this._displayNode) {
this._commitDisplayNode(this._displayNode);
}
}
}
}
setDisplayNode(newDisplayNode) {
if (!this._initialized) {
_warnNotInitialized(this.node);
}
const currentDisplayNode = this._displayNode;
if (currentDisplayNode != newDisplayNode) {
const oldDisplayNode = currentDisplayNode;
if (oldDisplayNode) {
oldDisplayNode.flags.display.set(false);
if (this.options.dependsOnDisplayNode) {
this._graphNode.removeGraphInput(oldDisplayNode);
}
if (this._onDisplayNodeRemoveCallback) {
this._onDisplayNodeRemoveCallback();
}
}
this._displayNode = newDisplayNode;
if (newDisplayNode) {
this._commitDisplayNode(newDisplayNode);
}
}
}
_commitDisplayNode(newDisplayNode) {
if (this.options.dependsOnDisplayNode) {
this._graphNode.addGraphInput(newDisplayNode);
}
if (this._onDisplayNodeSetCallback) {
this._onDisplayNodeSetCallback();
}
}
}