running/stopped event

This commit is contained in:
2019-06-18 11:39:07 +02:00
parent dc42c474a1
commit 4a37bb0cb3
8 changed files with 657 additions and 13 deletions

View File

@@ -1,10 +1,14 @@
import * as nodes from './nodes';
import {MultiSubject} from './helpers/listener';
export default class Graph {
constructor() {
this.nodes = [];
this.__nodesActive = 0;
this.__nodesActiveDebounce = null;
this.subject = new MultiSubject(['running', 'stopped']);
}
serialize() {
@@ -17,6 +21,19 @@ export default class Graph {
static deserialize(nodes) {
const graph = new Graph();
graph.nodes = createNodes(nodes);
for (let {node} of graph.nodes) {
node.subject.on('running', (isRunning) => {
graph.__nodesActive += isRunning ? 1 : -1;
clearTimeout(graph.__nodesActiveDebounce);
graph.__nodesActiveDebounce = setTimeout(() => {
if (graph.__nodesActive > 0) {
graph.subject.next('running');
} else {
graph.subject.next('stopped');
}
}, 16);
});
}
return graph;
}

69
src/helpers/listener.js Normal file
View File

@@ -0,0 +1,69 @@
export class Subject {
constructor() {
this.__listeners = [];
}
next(val) {
for (let listener of this.__listeners) {
listener(val);
}
}
once() {
return new Promise((resolve) => {
const done = (val) => {
resolve(val);
this.off(done);
};
this.on(done);
})
}
on(fn) {
this.__listeners.push(fn);
}
off(fn) {
this.__listeners = this.__listeners.filter((listener) => listener !== fn);
}
destroy() {
this.__listeners = [];
}
}
export class MultiSubject {
constructor(types) {
this.__subjects = {};
for (let type of types) {
this.__subjects[type] = new Subject();
}
}
next(type, val) {
this.__subjects[type].next(val);
}
once(type) {
return this.__subjects[type].once();
}
on(type, fn) {
return this.__subjects[type].on(fn);
}
off(type, fn) {
this.__subjects[type].off(fn);
}
destroy() {
for (let type of Object.keys(this.__subjects)) {
this.__subjects[type].destroy();
}
}
}

View File

@@ -130,6 +130,10 @@ export default class Compose extends Canvas2d {
if (!width || !height) {
return;
}
if (!this.bg && !this.fg) {
return;
}
canvas.width = width;
canvas.height = height;

View File

@@ -1,5 +1,6 @@
import {Inputs, Outputs} from './io';
import uuidv4 from 'uuid/v4';
import {MultiSubject} from '../helpers/listener';
export default class Node {
@@ -12,13 +13,18 @@ export default class Node {
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.__scheduledUpdate = true;
this.__currentUpdate = this.__currentUpdate
.then(() => {
this._running = true;
})
.then(async () => {
const startTag =`graphfx-update-start:${this.uid}`;
const endTag = `graphfx-update-end:${this.uid}`
@@ -27,6 +33,13 @@ export default class Node {
await this._update();
performance.mark(endTag)
performance.measure(`GraphFX<${this.name}>`, startTag, endTag)
})
.then(() => {
this._running = false;
})
.catch((err) => {
this._running = false;
throw err;
});
}
}
@@ -35,6 +48,17 @@ export default class Node {
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
*/

View File

@@ -4,7 +4,7 @@ import WebGL from './WebGl';
export default class Channels extends WebGL {
constructor() {
super('Greyscale by channel', {
super('Channels', {
red: {
type: 'Number',
default: 1,

View File

@@ -153,17 +153,8 @@ export default class WebGL extends Node {
_passes() {
return [
(gl, program, image) => {
console.log('pass1')
this._setParams(gl, program);
},
(gl, program, image) => {
console.log('pass2')
this._setParams(gl, program);
},
(gl, program, image) => {
console.log('pass3')
this._setParams(gl, program);
}
]
}
@@ -186,7 +177,9 @@ export default class WebGL extends Node {
async _update() {
const image = this.in.image.value;
if (!image) return;
if (!image) {
return;
}
if (image.acquire) {
image.acquire();
}