@selenite/graph-editor
Version:
A graph editor for visual programming, based on rete and svelte.
122 lines (121 loc) • 4.01 kB
JavaScript
import { Node } from '../Node.svelte';
// import { notifications } from '@selenite/graph-editor';
import { getLeavesFromOutput } from '../utils';
export class TimeLoopNode extends Node {
currentTime;
constructor({ factory }) {
// super('Time Loop', { factory, height: 440, width: 200 });
super({ label: 'Time Loop', factory, height: 440, width: 200 });
// TODO: implement display progress
this.addInExec();
this.oldAddInData({
name: 'start',
displayName: 'Start',
socketLabel: 'Start',
type: 'number',
control: {
type: 'number',
options: {
initial: 0,
label: 'Start'
}
}
});
this.oldAddInData({
name: 'end',
displayName: 'End',
socketLabel: 'End',
type: 'number',
control: {
type: 'number',
options: {
initial: 2,
label: 'End'
}
}
});
this.oldAddInData({
name: 'step',
displayName: 'Step',
socketLabel: 'Step',
type: 'number',
control: {
type: 'number',
options: {
initial: 0.01,
label: 'Step'
}
}
});
this.oldAddInData({
name: 'displayProgress',
displayName: 'Display Progress',
type: 'boolean',
control: {
type: 'checkbox',
options: {
label: 'Display Progress',
initial: true
}
}
});
this.addOutExec('loop', 'Loop');
this.oldAddOutData({
name: 'time',
displayName: 'Time',
socketLabel: 'Time',
type: 'number'
});
this.addOutExec('done', 'Done', true);
this.pythonComponent.addVariables('t');
this.pythonComponent.addDynamicOutput('time');
this.pythonComponent.setDataCodeGetter('time', () => '$(t)');
this.pythonComponent.setCodeTemplateGetter(() => {
return `
$(t) = $(start)
while $(t) < $(end):
{{loop}}
$(t) += $(step)
{{done}}
`;
});
}
async execute(input, forward, forwardExec) {
const inputs = await this.fetchInputs();
const displayProgress = this.getData('displayProgress', inputs);
const start = this.getData('start', inputs);
const end = this.getData('end', inputs);
const step = this.getData('step', inputs);
if (start === undefined || end === undefined || step === undefined) {
forward('done');
super.execute(input, forward, forwardExec);
return;
}
this.currentTime = start;
let cycle = 0;
// console.log('leaves', leavesFromLoopExec);
while (this.currentTime <= end + 1e-9) {
// console.log('start', start, 'end', end, 'step', step);
if (displayProgress && cycle % 100 === 0) {
console.log(this.currentTime);
this.factory.notifications.show({
title: 'Time Loop',
message: `Time: ${this.currentTime}s`
});
}
this.getDataflowEngine().reset(this.id);
const leavesFromLoopExec = getLeavesFromOutput(this, 'loop');
const promises = this.getWaitPromises(leavesFromLoopExec);
forward('loop');
await Promise.all(promises);
cycle++;
this.currentTime = step * cycle + start;
}
// console.log(displayProgress, start, end, step);
forward('done');
super.execute(input, forward, forwardExec);
}
data(inputs) {
return { time: this.currentTime };
}
}