119 lines
3.1 KiB
JavaScript
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}>`;
|
|
}
|
|
};
|
|
|