Process node worker on input change
See original GitHub issueHi Guys,
First of all, ReteJS great project. But I need some help, I already did some research myself but can’t figure this one out.
I have a basic flow of 3 components:
- OnSlide component: which triggers an action (event) when the user slides a GUI component, it also exposes a value between 0 and 100 which is the the sliders position.
- ColorRamp component: it converts a value to an index of a color gradient. So for example i have a gradient running from green to red. An input value of 50 would result in a yellow color output (hex color).
- SetColor component: Which takes an action, and color… and sets the background color of the UI component to the given color.

Everything is working except the color that the ColorRamp component gives is always the same. I noticed that the worker() function in the ColorRamp component is only called the first time.
What I want to accomplish is that the Color Ramp plugin always gives the correct color, so whenever the input “value” changes… it recalculates the correct color output.
The strange thing is that everything works flawless but only the first time onSlide triggers an event. In that scenario the worker() functions of all components are called. But after the first time… only the worker() function of the onSlide component gets called…
I’ve been debugging all night… can’t figure it out… it looks to me like the “thread” somewhere get’s lost in asyncToGenerator.
Thank you very much! Kind regards, Bastiaan
Components source code, in order of the signal flow:
OnSlide component (event generator):
import Rete from "rete";
import Sockets from "../sockets";
class OnSlideComponent extends Rete.Component {
constructor(item){
super('On Slide');
this.task = {
outputs: {act: 'option', currentValue: 'output'},
init(task){
item.shape.on('sliding', function(slideEventData) {
task.run(slideEventData.value);
task.reset();
});
}
}
}
builder(node) {
node.addOutput(new Rete.Output('act', 'Action', Sockets.actionSocket));
node.addOutput(new Rete.Output('currentValue', 'Value', Sockets.numberSocket));
}
worker(node, inputs, sliderValue) {
return {
currentValue: sliderValue
}
}
}
export default OnSlideComponent;
ColorRamp component (value to color):
import Rete from "rete";
import Sockets from "../sockets";
import NumberControl from "../controls/numbercontrol";
import Rainbow from "rainbowvis.js";
class ColorRampComponent extends Rete.Component {
constructor() {
super('Color ramp');
this.rainbow = new Rainbow();
this.task = {
outputs: {
actout: "option",
color: "output"
}
}
}
builder(node) {
var rangeMinInput = new Rete.Input('rangemin', 'Min.', Sockets.numberSocket);
rangeMinInput.addControl(new NumberControl("rangemin", node.data.midiChannel));
var rangeMaxInput = new Rete.Input('rangemax', 'Max.', Sockets.numberSocket);
rangeMaxInput.addControl(new NumberControl("rangemax", node.data.midiChannel));
var valueInput = new Rete.Input('value', 'Value', Sockets.numberSocket);
valueInput.addControl(new NumberControl("value", node.data.midiValue));
var colorOutput = new Rete.Output('color', 'Color', Sockets.colorSocket);
node
.addInput(new Rete.Input('act', 'Action', Sockets.actionSocket))
.addInput(rangeMinInput)
.addInput(rangeMaxInput)
.addInput(valueInput)
.addOutput(colorOutput)
.addOutput(new Rete.Output('actout', 'Action', Sockets.actionSocket));
}
worker(node, inputs, outputs) {
var value = inputs["value"] ? inputs["value"][0] : node.data.value;
var calculatedColor = "#" + this.component.rainbow.colourAt(value);
return {color: calculatedColor};
}
}
export default ColorRampComponent;
SetColorComponent (updates UI component):
import Rete from "rete";
import Sockets from "../sockets";
import Spectrum from "spectrum-colorpicker";
import "../../../node_modules/spectrum-colorpicker/spectrum.css";
import ColorPickerControl from "../controls/colorpickercontrol";
class SetColorComponent extends Rete.Component {
constructor(item) {
super('Set Color');
this.task = {
item: item, /* BW: There might be an easier way to pass objects to the worker function, but I don;t know it yet */
outputs: {}
}
}
builder(node) {
var ctrl = new ColorPickerControl("color", node.data.color);
var colorInput = new Rete.Input('color', 'Color', Sockets.colorSocket);
colorInput.addControl(ctrl);
node
.addInput(colorInput)
.addInput(new Rete.Input('act', 'Action', Sockets.actionSocket));
}
worker(node, inputs) {
var color = inputs["color"] ? inputs["color"][0] : node.data.color;
this.component.task.item.setColor(color);
}
}
export default SetColorComponent;
Modules versions: “rete”: “^1.4.3-rc.1”, “rete-connection-plugin”: “^0.9.0”, “rete-context-menu-plugin”: “^0.5.2”, “rete-keyboard-plugin”: “^0.1.2”, “rete-task-plugin”: “^0.3.0”, “rete-vue-render-plugin”: “^0.5.0”,
Issue Analytics
- State:
- Created 3 years ago
- Comments:7 (2 by maintainers)
How do you call
task.run()
? Every node caches their output data. By default it will reset output data after the tasks chain will be completedhttps://github.com/retejs/task-plugin/blob/47d6ca139ef42785869ebf2ea4b74800302ba9ce/src/task.js#L28
@defcon8 v0.2.0 caches data, thats why the
Render
node gets old data fromValue to Color
At the moment, I do not see a workaround for you except using 0.1.7, since in some cases caching is important. Perhaps for more complex things you might be better off using, for example, Rx.js instead of task plugin