node-red-contrib-leap-motion
Version:
Node-Red nodes for leap motion
167 lines (142 loc) • 4.79 kB
JavaScript
var chooseProtocol = require('../protocol').chooseProtocol
, EventEmitter = require('events').EventEmitter
, _ = require('underscore');
var BaseConnection = module.exports = function(opts) {
this.opts = _.defaults(opts || {}, {
host : '127.0.0.1',
enableGestures: false,
scheme: this.getScheme(),
port: this.getPort(),
background: false,
optimizeHMD: false,
requestProtocolVersion: BaseConnection.defaultProtocolVersion
});
this.host = this.opts.host;
this.port = this.opts.port;
this.scheme = this.opts.scheme;
this.protocolVersionVerified = false;
this.background = null;
this.optimizeHMD = null;
this.on('ready', function() {
this.enableGestures(this.opts.enableGestures);
this.setBackground(this.opts.background);
this.setOptimizeHMD(this.opts.optimizeHMD);
if (this.opts.optimizeHMD){
console.log("Optimized for head mounted display usage.");
}else {
console.log("Optimized for desktop usage.");
}
});
};
// The latest available:
BaseConnection.defaultProtocolVersion = 6;
BaseConnection.prototype.getUrl = function() {
return this.scheme + "//" + this.host + ":" + this.port + "/v" + this.opts.requestProtocolVersion + ".json";
}
BaseConnection.prototype.getScheme = function(){
return 'ws:'
}
BaseConnection.prototype.getPort = function(){
return 6437
}
BaseConnection.prototype.setBackground = function(state) {
this.opts.background = state;
if (this.protocol && this.protocol.sendBackground && this.background !== this.opts.background) {
this.background = this.opts.background;
this.protocol.sendBackground(this, this.opts.background);
}
}
BaseConnection.prototype.setOptimizeHMD = function(state) {
this.opts.optimizeHMD = state;
if (this.protocol && this.protocol.sendOptimizeHMD && this.optimizeHMD !== this.opts.optimizeHMD) {
this.optimizeHMD = this.opts.optimizeHMD;
this.protocol.sendOptimizeHMD(this, this.opts.optimizeHMD);
}
}
BaseConnection.prototype.handleOpen = function() {
if (!this.connected) {
this.connected = true;
this.emit('connect');
}
}
BaseConnection.prototype.enableGestures = function(enabled) {
this.gesturesEnabled = enabled ? true : false;
this.send(this.protocol.encode({"enableGestures": this.gesturesEnabled}));
}
BaseConnection.prototype.handleClose = function(code, reason) {
if (!this.connected) return;
this.disconnect();
// 1001 - an active connection is closed
// 1006 - cannot connect
if (code === 1001 && this.opts.requestProtocolVersion > 1) {
if (this.protocolVersionVerified) {
this.protocolVersionVerified = false;
}else{
this.opts.requestProtocolVersion--;
}
}
this.startReconnection();
}
BaseConnection.prototype.startReconnection = function() {
var connection = this;
if(!this.reconnectionTimer){
(this.reconnectionTimer = setInterval(function() { connection.reconnect() }, 500));
}
}
BaseConnection.prototype.stopReconnection = function() {
this.reconnectionTimer = clearInterval(this.reconnectionTimer);
}
// By default, disconnect will prevent auto-reconnection.
// Pass in true to allow the reconnection loop not be interrupted continue
BaseConnection.prototype.disconnect = function(allowReconnect) {
if (!allowReconnect) this.stopReconnection();
if (!this.socket) return;
this.socket.close();
delete this.socket;
delete this.protocol;
delete this.background; // This is not persisted when reconnecting to the web socket server
delete this.optimizeHMD;
delete this.focusedState;
if (this.connected) {
this.connected = false;
this.emit('disconnect');
}
return true;
}
BaseConnection.prototype.reconnect = function() {
if (this.connected) {
this.stopReconnection();
} else {
this.disconnect(true);
this.connect();
}
}
BaseConnection.prototype.handleData = function(data) {
var message = JSON.parse(data);
var messageEvent;
if (this.protocol === undefined) {
messageEvent = this.protocol = chooseProtocol(message);
this.protocolVersionVerified = true;
this.emit('ready');
} else {
messageEvent = this.protocol(message);
}
this.emit(messageEvent.type, messageEvent);
}
BaseConnection.prototype.connect = function() {
if (this.socket) return;
this.socket = this.setupSocket();
return true;
}
BaseConnection.prototype.send = function(data) {
this.socket.send(data);
}
BaseConnection.prototype.reportFocus = function(state) {
if (!this.connected || this.focusedState === state) return;
this.focusedState = state;
this.emit(this.focusedState ? 'focus' : 'blur');
if (this.protocol && this.protocol.sendFocused) {
this.protocol.sendFocused(this, this.focusedState);
}
}
_.extend(BaseConnection.prototype, EventEmitter.prototype);