@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
154 lines (144 loc) • 4.62 kB
text/typescript
import {BaseNodeType} from '../_Base';
type NodeLifeCycleControllerCallback = () => void;
type NodeLifeCycleControllerCallbackWithChildNode = (childNode: BaseNodeType) => void;
export class NodeLifeCycleController {
protected _creationCompleted = false;
protected _onChildAddCallbacks: NodeLifeCycleControllerCallbackWithChildNode[] | undefined;
private _onChildRemoveCallbacks: NodeLifeCycleControllerCallbackWithChildNode[] | undefined;
// _on_creation_completed_hooks are used in the importer, once the node has been created, added and params are set
// private _on_creation_completed_hooks: Callback[] | undefined;
private _onAfterCreatedCallbacks: NodeLifeCycleControllerCallback[] | undefined;
private _onAfterAddedCallbacks: NodeLifeCycleControllerCallback[] | undefined;
private _onBeforeDeletedCallbacks: NodeLifeCycleControllerCallback[] | undefined;
private _onAfterDeletedCallbacks: NodeLifeCycleControllerCallback[] | undefined;
constructor(protected node: BaseNodeType) {}
dispose() {
this._onChildAddCallbacks = undefined;
this._onChildRemoveCallbacks = undefined;
this._onAfterCreatedCallbacks = undefined;
this._onAfterAddedCallbacks = undefined;
this._onBeforeDeletedCallbacks = undefined;
this._onAfterDeletedCallbacks = undefined;
}
setCreationCompleted() {
if (!this._creationCompleted) {
this._creationCompleted = true;
// this.run_on_creation_completed_hooks();
}
}
creationCompleted() {
return this.node.scene().loadingController.loaded() && this._creationCompleted;
}
//
//
// ON CREATION COMPLETED
//
//
// add_on_creation_completed_hook(callback: Callback) {
// this._on_creation_completed_hooks = this._on_creation_completed_hooks || [];
// this._on_creation_completed_hooks.push(callback);
// }
// private run_on_creation_completed_hooks() {
// if (this._on_creation_completed_hooks) {
// console.log('run_on_creation_completed_hooks', this.node.name);
// }
// this.execute_hooks(this._on_creation_completed_hooks);
// }
//
//
// ON CHILD ADD
//
//
onChildAdd(callback: NodeLifeCycleControllerCallbackWithChildNode) {
this._onChildAddCallbacks = this._onChildAddCallbacks || [];
this._onChildAddCallbacks.push(callback);
}
runOnChildAddCallbacks(node: BaseNodeType) {
this._runCallbacksWithChildNode(this._onChildAddCallbacks, node);
}
//
//
// ON CHILD REMOVE
//
//
onChildRemove(callback: NodeLifeCycleControllerCallbackWithChildNode) {
this._onChildRemoveCallbacks = this._onChildRemoveCallbacks || [];
this._onChildRemoveCallbacks.push(callback);
}
runOnChildRemoveCallbacks(node: BaseNodeType) {
this._runCallbacksWithChildNode(this._onChildRemoveCallbacks, node);
}
//
//
// ON CREATE
//
//
onAfterCreated(callback: NodeLifeCycleControllerCallback) {
this._onAfterCreatedCallbacks = this._onAfterCreatedCallbacks || [];
this._onAfterCreatedCallbacks.push(callback);
}
runOnAfterCreatedCallbacks() {
this._runCallbacks(this._onAfterCreatedCallbacks);
}
//
//
// ON ADD
//
//
onAfterAdded(callback: NodeLifeCycleControllerCallback) {
this._onAfterAddedCallbacks = this._onAfterAddedCallbacks || [];
this._onAfterAddedCallbacks.push(callback);
}
runOnAfterAddedCallbacks() {
this._runCallbacks(this._onAfterAddedCallbacks);
}
//
//
// ON DELETE
//
//
onBeforeDeleted(callback: NodeLifeCycleControllerCallback) {
this._onBeforeDeletedCallbacks = this._onBeforeDeletedCallbacks || [];
this._onBeforeDeletedCallbacks.push(callback);
}
runOnBeforeDeleteCallbacks() {
this._runCallbacks(this._onBeforeDeletedCallbacks);
}
// TODO: onAfterDeleted is not very different than methods in .dispose
// so this should probably be removed/refactored
onAfterDeleted(callback: NodeLifeCycleControllerCallback) {
this._onAfterDeletedCallbacks = this._onAfterDeletedCallbacks || [];
this._onAfterDeletedCallbacks.push(callback);
}
runOnDeleteCallbacks() {
this._runCallbacks(this._onAfterDeletedCallbacks);
}
//
//
// UTILS
//
//
protected _runCallbacks(hooks: NodeLifeCycleControllerCallback[] | undefined) {
if (!hooks) {
return;
}
let hook: NodeLifeCycleControllerCallback | undefined;
// do not flush, as this MAY BE needed multiple times
for (hook of hooks) {
hook();
}
}
protected _runCallbacksWithChildNode(
hooks: NodeLifeCycleControllerCallbackWithChildNode[] | undefined,
childNode: BaseNodeType
) {
if (!hooks) {
return;
}
let hook: NodeLifeCycleControllerCallbackWithChildNode | undefined;
// do not flush, as this is needed multiple times
for (hook of hooks) {
hook(childNode);
}
}
}