Skip to content

Instantly share code, notes, and snippets.

@chenbaiyujason
Last active April 6, 2023 07:22
Show Gist options
  • Select an option

  • Save chenbaiyujason/7ae29bfb34bd66259d96a49dbdfbb88b to your computer and use it in GitHub Desktop.

Select an option

Save chenbaiyujason/7ae29bfb34bd66259d96a49dbdfbb88b to your computer and use it in GitHub Desktop.
Rete.js (Events/Tasks)
<div id="rete" class="node-editor"></div>
<a target="_blank" href="https://github.com/retejs/rete"><img style="position: absolute; top: 0; right: 0; border: 0;" src="https://camo.githubusercontent.com/652c5b9acfaddf3a9c326fa6bde407b87f7be0f4/68747470733a2f2f73332e616d617a6f6e6177732e636f6d2f6769746875622f726962626f6e732f666f726b6d655f72696768745f6f72616e67655f6666373630302e706e67" alt="Fork me on GitHub" data-canonical-src="https://s3.amazonaws.com/github/ribbons/forkme_right_orange_ff7600.png"></a>
var actionSocket = new Rete.Socket('Action');
var dataSocket = new Rete.Socket('Data');
var eventHandlers = {
list: [],
clear() {
this.list.forEach(handler => {
document.removeEventListener('keydown', handler);
});
this.list = [];
},
add(name, handler) {
document.addEventListener(name, handler, false);
this.list.push(handler);
}
};
class MessageControl extends Rete.Control {
constructor(emitter, msg) {
super();
this.emitter = emitter;
this.template = '<input :value="msg" @input="change($event)"/>';
this.scope = {
msg,
change: this.change.bind(this)
};
}
change(e) {
this.scope.value = +e.target.value;
this.update();
}
update() {
this.putData('msg', this.scope.value)
this.emitter.trigger('process');
this._alight.scan();
}
mounted() {
this.scope.value = this.getData('msg') || 0;
this.update();
}
setValue(val) {
this.scope.value = val;
this._alight.scan()
}
}
class KeydownComponent extends Rete.Component {
constructor(){
super('Keydown event');
this.task = {
outputs: {act: 'option', key: 'output'},
init(task, node){
eventHandlers.add('keydown', function (e) {
task.run(e.keyCode);
task.reset();
});
}
}
}
builder(node) {
node.addOutput(new Rete.Output('act', '', actionSocket))
node.addOutput(new Rete.Output('key', 'Key code', dataSocket));
}
worker(node, inputs, data) {
console.log('Keydown event', node.id, data);
return {key: data}
}
}
class EnterPressComponent extends Rete.Component {
constructor(){
super('Enter pressed');
this.task = {
outputs: {then:'option', else:'option'}
}
}
builder(node) {
node
.addInput(new Rete.Input('act','', actionSocket))
.addInput(new Rete.Input('key', 'Key code', dataSocket))
.addOutput(new Rete.Output('then', 'Then', actionSocket))
.addOutput(new Rete.Output('else', 'Else', actionSocket));
}
worker(node, inputs, outputs) {
if (inputs['key'][0] == 13)
this.closed = ['else'];
else
this.closed = ['then'];
console.log('Print', node.id, inputs);
}
}
class AlertComponent extends Rete.Component {
constructor() {
super('Alert');
this.task = {
outputs: {}
}
}
builder(node) {
var ctrl = new MessageControl(this.editor, node.data.msg);
node
.addControl(ctrl)
.addInput(new Rete.Input('act', '', actionSocket));
}
worker(node, inputs) {
console.log('Alert', node.id, node.data);
alert(node.data.msg);
}
}
var components = [new KeydownComponent, new EnterPressComponent, new AlertComponent];
var container = document.querySelector('#rete')
var editor = new Rete.NodeEditor('[email protected]', container,);
editor.use(AlightRenderPlugin);
editor.use(ConnectionPlugin);
editor.use(ContextMenuPlugin);
editor.use(TaskPlugin);
var engine = new Rete.Engine('[email protected]');
components.map(c => {
editor.register(c);
engine.register(c);
});
editor.on('connectioncreate connectionremove nodecreate noderemove', ()=>{
if(editor.silent) return;
eventHandlers.clear();
compile();
});
async function compile() {
await engine.abort();
await engine.process(editor.toJSON());
}
var data = {
'id': '[email protected]',
'nodes': {
'2': {
'id': 2,
'data': {},
'group': null,
'inputs': {},
'outputs': {
'act': {
'connections': [
{
'node': 3,
'input': 'act'
}
]
},
'key': {
'connections': [
{
'node': 3,
'input': 'key'
}
]
}
},
'position': [
114, 133
],
'name': 'Keydown event'
},
'3': {
'id': 3,
'data': {},
'group': null,
'inputs': {
'act':{
'connections': [
{
'node': 2,
'output': 'act'
}
]
},
'key': {
'connections': [
{
'node': 2,
'output': 'key'
}
]
}
},
'outputs': {
'then':{
'connections': [
{
'node': 10,
'input': 'act'
}
]
},
'else': {
'connections': [
{
'node': 11,
'input': 'act'
}
]
}
},
'position': [
443, 112
],
'name': 'Enter pressed'
},
'10': {
'id': 10,
'data': {
'msg': 'Enter!'
},
'group': null,
'inputs': {
'act': {
'connections': [
{
'node': 3,
'output': 'then'
}
]
}
},
'outputs': [],
'position': [
773, 106
],
'name': 'Alert'
},
'11': {
'id': 11,
'data': {
'msg': 'Another key pressed'
},
'group': null,
'inputs': {
'act': {
'connections': [
{
'node': 3,
'output': 'else'
}
]
}
},
'outputs': [],
'position': [
766, 292
],
'name': 'Alert'
}
},
'groups': {}
}
editor.fromJSON(data).then(() => {
editor.view.resize();
compile();
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/rete.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/alight.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/alight-render-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/connection-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/context-menu-plugin.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/build/task-plugin.min.js"></script>
html,body{
height: 100%;
margin: 0;
}
#d3ne {
height: 100%;
position: relative;
}
.socket.data {
background: rgb(143, 125, 224)
}
.socket.act {
background: rgb(16, 202, 16);
border-radius: 0 !important;
width: 16px !important;
}
id {
position: absolute;
left: -6px;
top: -6px;
background: white;
}
button.compile {
z-index: 5;
position: absolute;
top: 10px;
left: 10px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment