@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
131 lines (130 loc) • 4.25 kB
JavaScript
"use strict";
import { ContainableClassMap } from "./../../containers/utils/ContainableMap";
import { ContainerClassMap } from "../../containers/utils/ContainerMap";
export class TypedContainerController {
constructor(node) {
this.node = node;
this._callbacks = [];
this._callbacksTmp = [];
this._container = this._createContainer();
}
container() {
return this._container;
}
_createContainer() {
const ContainerClass = ContainerClassMap[this.node.context()];
return new ContainerClass(this.node);
}
_createContainerWithContent() {
const container = this._createContainer();
const ContentClass = ContainableClassMap[this.node.context()];
const content = new ContentClass();
container.set_content(content);
return container;
}
firstNonBypassedNode() {
var _a, _b;
if ((_b = (_a = this.node.flags) == null ? void 0 : _a.bypass) == null ? void 0 : _b.active()) {
const inputNode = this.node.io.inputs.input(0);
return inputNode;
} else {
return this.node;
}
}
containerUnlessBypassed() {
var _a, _b;
if ((_b = (_a = this.node.flags) == null ? void 0 : _a.bypass) == null ? void 0 : _b.active()) {
this.node.states.error.clear();
const inputNode = this.node.io.inputs.input(0);
if (inputNode) {
return inputNode.containerController.containerUnlessBypassed();
} else {
return this._createContainerWithContent();
}
} else {
return this.container();
}
}
async compute() {
var _a, _b;
if (this.node.disposed()) {
console.warn(".compute() requested from a disposed node", this.node);
}
if ((_b = (_a = this.node.flags) == null ? void 0 : _a.bypass) == null ? void 0 : _b.active()) {
this.node.states.error.clear();
const inputNode = this.node.io.inputs.input(0);
if (inputNode) {
const container = await this.requestInputContainer(0) || this._container;
this.node.cookController.endCook();
return container;
} else {
return this._createContainerWithContent();
}
}
if (this.node.isDirty()) {
return new Promise((resolve, reject) => {
var _a2, _b2;
this._callbacks.push(resolve);
if ((_b2 = (_a2 = this.node.flags) == null ? void 0 : _a2.bypass) == null ? void 0 : _b2.active()) {
throw "we should not be here";
}
this.node.cookController.cookMain();
});
}
return this._container;
}
// async requestContainerTEST(): Promise<ContainerMap[NC]> {
// if (this.node.flags?.bypass?.active()) {
// const container = await this.requestInputContainer(0);
// return container || this._container;
// }
// if (this.node.isDirty()) {
// await this.node.cookController.cook_main();
// }
// return this._container;
// }
// TODO: should I merge this into the method above?
// private process_container_request() {
// if (this.node.flags?.bypass?.active()) {
// const input_index = 0;
// this.requestInputContainer(input_index).then((container) => {
// this.node.removeDirtyState();
// if (container) {
// this.notify_requesters(container);
// } else {
// this.node.states.error.set('input invalid');
// }
// });
// } else {
// if (this.node.isDirty()) {
// this.node.cookController.cook_main();
// } else {
// this.notify_requesters();
// }
// }
// }
async requestInputContainer(inputIndex) {
const inputNode = this.node.io.inputs.input(inputIndex);
if (inputNode) {
return await inputNode.compute();
} else {
this.node.states.error.set(`input ${inputIndex} required`);
this.notifyRequesters();
return null;
}
}
notifyRequesters(container) {
this._callbacksTmp = this._callbacks.slice();
this._callbacks.splice(0, this._callbacks.length);
if (!container) {
container = this.node.containerController.container();
}
let callback;
while (callback = this._callbacksTmp.pop()) {
callback(container);
}
this.node.scene().cookController.removeNode(this.node);
}
}
export class BaseContainerController extends TypedContainerController {
}