rpd
Version:
RPD is a minimal framework for building Node-Based User Interfaces, powered by Reactive Programming
241 lines (218 loc) • 8.56 kB
JavaScript
;(function(global) {
"use strict";
var Rpd = global.Rpd;
if (typeof Rpd === "undefined" && typeof require !== "undefined") {
Rpd = require('rpd');
}
var COMMAND_SEPARATOR = '\n';
var ARGS_SEPARATOR = ' ';
Rpd.export.plain = function(name) {
var spec = exportSpec;
var commands = [];
var lines = [ Rpd.VERSION ];
var moves = {};
var knownEvents = Rpd.events.filter(function(update) { return spec[update.type]; });
var pushCommand = function(update) {
if (update.type === 'node/move') {
moves[update.node.id] = spec['node/move'](update).join(ARGS_SEPARATOR);
} else {
lines.push(spec[update.type](update).join(ARGS_SEPARATOR));
}
};
function storeMoves() {
Object.keys(moves).forEach(function(nodeId) {
lines.push(moves[nodeId]);
});
};
knownEvents.onValue(pushCommand);
return function() {
knownEvents.offValue(pushCommand);
storeMoves();
return lines.join(COMMAND_SEPARATOR);
};
}
Rpd.import.plain = function(lines) {
lines = lines.split(COMMAND_SEPARATOR);
var spec = makeImportSpec();
var version = lines[0];
if ((version !== Rpd.VERSION) && console && console.warn) {
console.warn('Plain file version', version, 'and RPD Version',
Rpd.VERSION, 'are not equal to each other');
}
var commands = lines.slice(1);
commands.forEach(function(command) {
command = command.split(ARGS_SEPARATOR);
if (command.length) spec[command[0]](command.slice(1));
});
}
// ================================= EXPORT =================================
var exportSpec = {
'network/add-patch': function(update) {
var patch = update.patch;
return [ 'network/add-patch', patch.id, encodeURIComponent(patch.name) ];
},
'patch/open': function(update) {
return update.parent ? [ 'patch/open', update.patch.id, update.parent.id ]
: [ 'patch/open', update.patch.id ];
},
'patch/close': function(update) {
return [ 'patch/close', update.patch.id ];
},
'patch/set-inputs': function(update) {
var patch = update.patch;
var srcInputs = update.inputs,
inputs = [];
srcInputs.forEach(function(srcInput) { inputs.push(srcInput.id); });
return [ 'patch/set-inputs', update.patch.id ].concat(inputs);
},
'patch/set-outputs': function(update) {
var patch = update.patch;
var srcOutputs = update.outputs,
outputs = [];
srcOutputs.forEach(function(srcOutput) { outputs.push(srcOutput.id); });
return [ 'patch/set-outputs', update.patch.id ].concat(outputs);
},
'patch/project': function(update) {
return [ 'patch/project', update.patch.id, update.target.id, update.node.id ];
},
'patch/move-canvas': function(update) {
return [ 'patch/move-canvas', update.patch.id, update.position[0], update.position[1] ];
},
'patch/resize-canvas': function(update) {
return [ 'patch/resize-canvas', update.patch.id, update.size[0], update.size[1] ];
},
'patch/add-node': function(update) {
var node = update.node;
return [ 'patch/add-node', node.patch.id, node.id, node.type, encodeURIComponent(node.def.title) ];
},
'patch/remove-node': function(update) {
return [ 'patch/remove-node', update.patch.id, update.node.id ];
},
'node/turn-on': function(update) {
return [ 'node/turn-on', update.node.id ];
},
'node/turn-off': function(update) {
return [ 'node/turn-off', update.node.id ];
},
'node/add-inlet': function(update) {
var inlet = update.inlet;
return [ 'node/add-inlet', update.node.id, inlet.id,
inlet.type, inlet.alias, encodeURIComponent(inlet.def.label) ];
},
'node/remove-inlet': function(update) {
return [ 'node/remove-inlet', update.node.id, update.inlet.id ];
},
'node/add-outlet': function(update) {
var outlet = update.outlet;
return [ 'node/add-outlet', update.node.id, outlet.id,
outlet.type, outlet.alias, encodeURIComponent(outlet.def.label) ];
},
'node/remove-outlet': function(update) {
return [ 'node/remove-outlet', update.node.id, update.outlet.id ];
},
'node/move': function(update) {
return [ 'node/move', update.node.id ].concat(update.position);
},
'node/configure': function(update) {
return [ 'node/configure', update.node.id ].concat(JSON.stringify(update.props));
},
'outlet/connect': function(update) {
return [ 'outlet/connect', update.outlet.id, update.inlet.id, update.link.id ];
},
'outlet/disconnect': function(update) {
return [ 'outlet/disconnect', update.outlet.id, update.link.id ];
},
'link/enable': function(update) {
return [ 'link/enable', update.link.id ];
},
'link/disable': function(update) {
return [ 'link/disable', update.link.id ];
}
};
// ================================= IMPORT =================================
function makeImportSpec() {
var patches = {},
nodes = {},
inlets = {},
outlets = {},
links = {};
return {
'network/add-patch': function(command) {
patches[command[0]] = Rpd.addClosedPatch(decodeURIComponent(command[1]));
},
'patch/open': function(command) {
patches[command[0]].open(command.length > 1 ? patches[command[1]] : null);
},
'patch/close': function(command) {
patches[command[0]].close();
},
'patch/set-inputs': function(command) {
var inputs = command.slice(1),
inputsTrg = [];
inputs.forEach(function(input) {
inputsTrg.push(inlets[input]);
});
patches[command[0]].inputs(inputsTrg);
},
'patch/set-outputs': function(command) {
var outputs = command.slice(1),
outputsTrg = [];
outputs.forEach(function(output) {
outputsTrg.push(outlets[output]);
});
patches[command[0]].outputs(outputsTrg);
},
'patch/project': function(command) {
patches[command[0]].project(nodes[command[2]]);
},
'patch/move-canvas': function(command) {
patches[command[0]].moveCanvas(parseFloat(command[1]), parseFloat(command[2]));
},
'patch/resize-canvas': function(command) {
patches[command[0]].resizeCanvas(parseFloat(command[1]), parseFloat(command[2]));
},
'patch/add-node': function(command) {
nodes[command[1]] = patches[command[0]].addNode(command[2], decodeURIComponent(command[3]));
},
'patch/remove-node': function(command) {
patches[command[0]].removeNode(nodes[command[1]]);
},
'node/turn-on': function(command) {
nodes[command[0]].turnOn();
},
'node/turn-off': function(command) {
nodes[command[0]].turnOff();
},
'node/add-inlet': function(command) {
inlets[command[1]] = nodes[command[0]].addInlet(command[2], command[3], decodeURIComponent(command[4]));
},
'node/remove-inlet': function(command) {
nodes[command[0]].removeInlet(inlets[command[1]]);
},
'node/add-outlet': function(command) {
outlets[command[1]] = nodes[command[0]].addOutlet(command[2], command[3], decodeURIComponent(command[4]));
},
'node/remove-outlet': function(command) {
nodes[command[0]].removeOutlet(outlets[command[1]]);
},
'node/move': function(command) {
nodes[command[0]].move(parseFloat(command[1]), parseFloat(command[2]));
},
'node/configure': function(command) {
nodes[command[0]].configure(JSON.parse(command[1]));
},
'outlet/connect': function(command) {
links[command[2]] = outlets[command[0]].connect(inlets[command[1]]);
},
'outlet/disconnect': function(command) {
outlets[command[0]].disconnect(links[command[1]]);
},
'link/enable': function(command) {
links[command[0]].enable();
},
'link/disable': function(command) {
links[command[0]].disable();
}
}
}
}(this));