noflo
Version:
Flow-Based Programming environment for JavaScript
362 lines (334 loc) • 10.3 kB
JavaScript
(function() {
var BasePort, IP, InPort, platform,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
BasePort = require('./BasePort');
IP = require('./IP');
platform = require('./Platform');
InPort = (function(superClass) {
extend(InPort, superClass);
function InPort(options, process) {
this.process = null;
if (!process && typeof options === 'function') {
process = options;
options = {};
}
if (options == null) {
options = {};
}
if (options.buffered == null) {
options.buffered = false;
}
if (options.control == null) {
options.control = false;
}
if (options.triggering == null) {
options.triggering = true;
}
if (!process && options && options.process) {
process = options.process;
delete options.process;
}
if (process) {
platform.deprecated('InPort process callback is deprecated. Please use Process API or the InPort handle option');
if (typeof process !== 'function') {
throw new Error('process must be a function');
}
this.process = process;
}
if (options.handle) {
platform.deprecated('InPort handle callback is deprecated. Please use Process API');
if (typeof options.handle !== 'function') {
throw new Error('handle must be a function');
}
this.handle = options.handle;
delete options.handle;
}
InPort.__super__.constructor.call(this, options);
this.prepareBuffer();
}
InPort.prototype.attachSocket = function(socket, localId) {
if (localId == null) {
localId = null;
}
if (this.hasDefault()) {
if (this.handle) {
socket.setDataDelegate((function(_this) {
return function() {
return new IP('data', _this.options["default"]);
};
})(this));
} else {
socket.setDataDelegate((function(_this) {
return function() {
return _this.options["default"];
};
})(this));
}
}
socket.on('connect', (function(_this) {
return function() {
return _this.handleSocketEvent('connect', socket, localId);
};
})(this));
socket.on('begingroup', (function(_this) {
return function(group) {
return _this.handleSocketEvent('begingroup', group, localId);
};
})(this));
socket.on('data', (function(_this) {
return function(data) {
_this.validateData(data);
return _this.handleSocketEvent('data', data, localId);
};
})(this));
socket.on('endgroup', (function(_this) {
return function(group) {
return _this.handleSocketEvent('endgroup', group, localId);
};
})(this));
socket.on('disconnect', (function(_this) {
return function() {
return _this.handleSocketEvent('disconnect', socket, localId);
};
})(this));
return socket.on('ip', (function(_this) {
return function(ip) {
return _this.handleIP(ip, localId);
};
})(this));
};
InPort.prototype.handleIP = function(ip, id) {
var buf;
if (this.process) {
return;
}
if (this.options.control && ip.type !== 'data') {
return;
}
ip.owner = this.nodeInstance;
if (this.isAddressable()) {
ip.index = id;
}
buf = this.prepareBufferForIP(ip);
buf.push(ip);
if (this.options.control && buf.length > 1) {
buf.shift();
}
if (this.handle) {
this.handle(ip, this.nodeInstance);
}
return this.emit('ip', ip, id);
};
InPort.prototype.handleSocketEvent = function(event, payload, id) {
if (this.isBuffered()) {
this.buffer.push({
event: event,
payload: payload,
id: id
});
if (this.isAddressable()) {
if (this.process) {
this.process(event, id, this.nodeInstance);
}
this.emit(event, id);
} else {
if (this.process) {
this.process(event, this.nodeInstance);
}
this.emit(event);
}
return;
}
if (this.process) {
if (this.isAddressable()) {
this.process(event, payload, id, this.nodeInstance);
} else {
this.process(event, payload, this.nodeInstance);
}
}
if (this.isAddressable()) {
return this.emit(event, payload, id);
}
return this.emit(event, payload);
};
InPort.prototype.hasDefault = function() {
return this.options["default"] !== void 0;
};
InPort.prototype.prepareBuffer = function() {
this.buffer = [];
if (this.isAddressable()) {
this.indexedBuffer = {};
}
this.scopedBuffer = {};
return this.iipBuffer = this.isAddressable() ? {} : [];
};
InPort.prototype.prepareBufferForIP = function(ip) {
if (this.isAddressable()) {
if (ip.scope != null) {
if (!(ip.scope in this.scopedBuffer)) {
this.scopedBuffer[ip.scope] = [];
}
if (!(ip.index in this.scopedBuffer[ip.scope])) {
this.scopedBuffer[ip.scope][ip.index] = [];
}
return this.scopedBuffer[ip.scope][ip.index];
}
if (ip.initial) {
if (!(ip.index in this.iipBuffer)) {
this.iipBuffer[ip.index] = [];
}
return this.iipBuffer[ip.index];
}
if (!(ip.index in this.indexedBuffer)) {
this.indexedBuffer[ip.index] = [];
}
return this.indexedBuffer[ip.index];
}
if (ip.scope != null) {
if (!(ip.scope in this.scopedBuffer)) {
this.scopedBuffer[ip.scope] = [];
}
return this.scopedBuffer[ip.scope];
}
if (ip.initial) {
return this.iipBuffer;
}
return this.buffer;
};
InPort.prototype.validateData = function(data) {
if (!this.options.values) {
return;
}
if (this.options.values.indexOf(data) === -1) {
throw new Error("Invalid data='" + data + "' received, not in [" + this.options.values + "]");
}
};
InPort.prototype.receive = function() {
platform.deprecated('InPort.receive is deprecated. Use InPort.get instead');
if (!this.isBuffered()) {
throw new Error('Receive is only possible on buffered ports');
}
return this.buffer.shift();
};
InPort.prototype.contains = function() {
platform.deprecated('InPort.contains is deprecated. Use InPort.has instead');
if (!this.isBuffered()) {
throw new Error('Contains query is only possible on buffered ports');
}
return this.buffer.filter(function(packet) {
if (packet.event === 'data') {
return true;
}
}).length;
};
InPort.prototype.getBuffer = function(scope, idx, initial) {
if (initial == null) {
initial = false;
}
if (this.isAddressable()) {
if (scope != null) {
if (!(scope in this.scopedBuffer)) {
return void 0;
}
if (!(idx in this.scopedBuffer[scope])) {
return void 0;
}
return this.scopedBuffer[scope][idx];
}
if (initial) {
if (!(idx in this.iipBuffer)) {
return void 0;
}
return this.iipBuffer[idx];
}
if (!(idx in this.indexedBuffer)) {
return void 0;
}
return this.indexedBuffer[idx];
}
if (scope != null) {
if (!(scope in this.scopedBuffer)) {
return void 0;
}
return this.scopedBuffer[scope];
}
if (initial) {
return this.iipBuffer;
}
return this.buffer;
};
InPort.prototype.getFromBuffer = function(scope, idx, initial) {
var buf;
if (initial == null) {
initial = false;
}
buf = this.getBuffer(scope, idx, initial);
if (!(buf != null ? buf.length : void 0)) {
return void 0;
}
if (this.options.control) {
return buf[buf.length - 1];
} else {
return buf.shift();
}
};
InPort.prototype.get = function(scope, idx) {
var res;
res = this.getFromBuffer(scope, idx);
if (res !== void 0) {
return res;
}
return this.getFromBuffer(null, idx, true);
};
InPort.prototype.hasIPinBuffer = function(scope, idx, validate, initial) {
var buf, i, len, packet;
if (initial == null) {
initial = false;
}
buf = this.getBuffer(scope, idx, initial);
if (!(buf != null ? buf.length : void 0)) {
return false;
}
for (i = 0, len = buf.length; i < len; i++) {
packet = buf[i];
if (validate(packet)) {
return true;
}
}
return false;
};
InPort.prototype.hasIIP = function(idx, validate) {
return this.hasIPinBuffer(null, idx, validate, true);
};
InPort.prototype.has = function(scope, idx, validate) {
if (!this.isAddressable()) {
validate = idx;
idx = null;
}
if (this.hasIPinBuffer(scope, idx, validate)) {
return true;
}
if (this.hasIIP(idx, validate)) {
return true;
}
return false;
};
InPort.prototype.length = function(scope, idx) {
var buf;
buf = this.getBuffer(scope, idx);
if (!buf) {
return 0;
}
return buf.length;
};
InPort.prototype.ready = function(scope, idx) {
return this.length(scope) > 0;
};
InPort.prototype.clear = function() {
return this.prepareBuffer();
};
return InPort;
})(BasePort);
module.exports = InPort;
}).call(this);