Files
graphfx/src/nodes/Node.js
2019-11-14 13:35:40 +01:00

119 lines
3.1 KiB
JavaScript

import {Inputs, Outputs} from './io';
import uuidv4 from 'uuid/v4';
import {MultiSubject} from '../helpers/listener';
export default class Node {
constructor(name, inputDefinition, outputDefiniton, options) {
this.name = name;
this.uid = uuidv4();
this.id = uuidv4();
this.__in = new Inputs(inputDefinition, this);
this.__out = new Outputs(outputDefiniton, this);
this.__in.update = (name) => this.__update([name]);
this.__scheduledUpdate = false;
this.__currentUpdate = Promise.resolve();
this.__running = false;
this._stopped = false;
this.subject = new MultiSubject(['running']);
}
__update(changes) {
if (!this.__scheduledUpdate && !this._stopped) {
this._running = true;
this.__scheduledUpdate = true;
this.__currentUpdate = this.__currentUpdate
.then(async () => {
const startTag =`graphfx-update-start:${this.uid}`;
const endTag = `graphfx-update-end:${this.uid}`
this.__scheduledUpdate = false;
performance.mark(startTag)
await this._update();
performance.mark(endTag)
performance.measure(`GraphFX<${this.name}>`, startTag, endTag)
})
.then(() => {
this._running = this.__scheduledUpdate;
})
.catch((err) => {
this._running = this.__scheduledUpdate;
throw err;
});
}
}
_update(){
throw new Error('_update method not implemented');
}
get _running() {
return this.__running;
}
set _running(val) {
if (this.__running !== val) {
this.__running = val;
this.subject.next('running', this.__running);
}
}
/**
* Input getters
*/
get in() {
return this.__in;
}
/**
* Output getters
*/
get out() {
return this.__out;
}
serialize() {
return {
id: this.id,
name: this.name,
options: {
in: this.in.serialize(),
out: this.out.serialize(),
},
}
}
async deserialize({id, options}) {
this.id = id || uuidv4();
}
async reconnect({options}, outputs) {
for (let name of Object.keys(options.in)) {
const {output} = options.in[name];
if (output) {
this.in[name].connect(outputs[output]);
}
}
for (let name of Object.keys(options.out)) {
await this.out[name].deserialize(options.out[name]);
}
for (let name of Object.keys(options.in)) {
await this.in[name].deserialize(options.in[name]);
}
}
destroy() {
this._stopped = true;
Promise.resolve()
.then(() => {
for (let input of this.in) {
input.disconnect();
}
})
}
toString() {
return `${this.name}<${this.id}>`;
}
};