Skip to content

Instantly share code, notes, and snippets.

@robotconscience
Forked from adenine/gist:2223408
Created March 28, 2012 14:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save robotconscience/2226632 to your computer and use it in GitHub Desktop.
Save robotconscience/2226632 to your computer and use it in GitHub Desktop.
ecs.js
// BIND FIX FOR OLDER BROWSERS
if( Function.prototype.bind ) {
} else {
/** safari, why you no bind!? */
Function.prototype.bind = function (bind) {
var self = this;
return function () {
var args = Array.prototype.slice.call(arguments);
return self.apply(bind || null, args);
};
};
}
/*!
* \namespace ECSjs
* \brief An javascript library to connect to ECS installation.
* <br />Copyright (C) 2012 LAB at Rockwell Group http://lab.rockwellgroup.com
*
* @author The Lab
* @modified 03/30/2012
* @version 0.0.2
*/
var ECSjs = {}
/*! \class ECSjs::Connection
\brief Creates a new ECS connection with host
*/
ECSjs.Connection = function( framework ){
this.bConnected = false
this.framework = framework || "ecs";
this.onConnectHooks = [];
this.onDisconnectHooks = [];
this.onMessageHooks = [];
this.onStartHooks = [];
this.onStopHooks = [];
this.onFileHooks = [];
};
/*! \fn ECSjs::Connection::connect
* \brief Setup ECS connection
* \memberof ECSjs::Connection
* \param role (optional) The ECS role that this application is fulfilling
* \param host (optional) The host of the ecsc that this application should connect to. Defaults to 127.0.0.1. You must specify a host if you are connecting to a remote ECS server.
* \param port (optional) The port on the host of the ecsc that this application should connect to. Defaults to 7847 (ECS default). You must specify a port if you change the port your local or remote ECS server is running on.
*
*/
ECSjs.Connection.prototype.connect = function( host, port, channel, role ) {
this.role = role || "";
this.host = host || "127.0.0.1";
this.port = port || 7847;
this.channel = channel || "/";
this.socket = new WebSocket("ws://"+this.host+":"+this.port+this.channel);
this.socket._parent = this;
this.socket.onmessage = this.onWSMessage.bind(this);
this.socket.onopen = this.onConnectionOpened.bind(this);
this.socket.onclose = this.onConnectionClosed.bind(this);
};
/*!
* \fn ECSjs::Connection::sendMessage
* \brief Send an ECS message
* \memberof ECSjs::Connection
* \param key The name of the route you are sending.
* \param value the value you are sending
*/
ECSjs.Connection.prototype.sendMessage = function( key, value ) {
if (!this.bConnected){
if (console) console.warn("Not connected!");
return;
}
if( this.framework == "ecs" ) {
this.socket.send( "<route_update><configs><config><name>"+key+"</name><value>"+value+"</value></config></configs></route_update>" );
} else {
value['route'] = key;
this.socket.send( JSON.stringify(value) );
}
};
/*!
* \fn ECSjs::Connection::onMessage
* \brief Pass in a function to receive messages from ECS
* \memberof ECSjs::Connection
* \param fun function you would like to be called; must catch (key, value)
*/
ECSjs.Connection.prototype.onMessage = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onMessage is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onMessageHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onConnect
* \brief Pass in a function in your add a listener to "connect" events from ECS.
* \memberof ECSjs::Connection
* \param fun function you would like to be called
*/
ECSjs.Connection.prototype.onConnect = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onConnect is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onConnectHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onDisconnect
* \brief Pass in a function in your add a listener to "disconnect" events
* \memberof ECSjs::Connection
* \param fun function you would like to be called
*/
ECSjs.Connection.prototype.onDisconnect = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onDisconnect is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onDisconnectHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onStart
* \brief Pass in a function in your add a listener to "start" events from ECS.
* \memberof ECSjs::Connection
* \param fun function you would like to be called
*/
ECSjs.Connection.prototype.onStart = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onStart is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onStartHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onStop
* \brief Pass in a function in your add a listener to "stop" events from ECS.
* \memberof ECSjs::Connection
* \param fun function you would like to be called
*/
ECSjs.Connection.prototype.onStop = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onStop is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onStopHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onFile
* \brief Pass in a function to receive files from ECS
* \memberof ECSjs::Connection
* \param fun function you would like to be called; must catch (filepath)
*/
ECSjs.Connection.prototype.onFile = function( fun ) {
if ( typeof fun !== "function" ){
console.warn( "method passed to ECSjs.Connection.onFile is not a function");
} else {
// DEV NOTE: SHOULD WE CHECK FOR DUPLICATES?
this.onFileHooks.push( fun );
}
};
/*!
* \fn ECSjs::Connection::onConnectionOpened
* \memberof ECSjs::Connection
* \private
*/
ECSjs.Connection.prototype.onConnectionOpened = function() {
this.bConnected = true;
if (console) console.log("ECS connected");
if( this.framework == "ecs" ) {
this.socket.send("<application_message><role>"+this.role+"</role></application_message>");
}
for (var i=0; i<this.onConnectHooks.length; i++){
this.onConnectHooks[i]();
};
};
/*!
* \fn ECSjs::Connection::onConnectionClosed
* \memberof ECSjs::Connection
* \private
*/
ECSjs.Connection.prototype.onConnectionClosed = function() {
this.bConnected = false;
for (var i=0; i<this.onDisconnectHooks.length; i++){
this.onDisconnectHooks[i]();
};
};
/*!
* \fn ECSjs::Connection::onWSMessage
* \memberof ECSjs::Connection
* \private
*/
ECSjs.Connection.prototype.onWSMessage = function( evt ) {
if( this.framework == "ecs" ) {
var xml;
if (window.DOMParser){
var parser=new DOMParser();
xml = parser.parseFromString(evt.data, "text/xml");
} else {
// Internet Explorer
xml = new ActiveXObject("Microsoft.XMLDOM");
xml.async=false;
xml.loadXML(evt.data);
}
if (evt.data.indexOf("route_update") >= 0) {
var configs = xml.getElementsByTagName("configs")[0].childNodes;
for (var i=0; i < configs.length; i++) {
var name = null;
var value = null;
var curConfig = configs[i];
// Config name
var n = curConfig.getElementsByTagName("name")[0];
name = n.childNodes[0].nodeValue;
// Config value
var val = curConfig.getElementsByTagName("value")[0];
value = val.childNodes[0].nodeValue;
// Invoke route update method if we have a complete name/value pair
if (name != null && value != null) {
for (var i=0; i<this.onMessageHooks.length; i++){
this.onMessageHooks[i](name, value);
};
}
}
} else if (evt.data.indexOf("application_message") >= 0) {
var action = xml.getElementsByTagName("action")[0];
var a = action.childNodes[0].nodeValue;
if (a == "start"){
for (var i=0; i<this.onStartHooks.length; i++){
this.onStartHooks[i]();
};
} else if (a == "stop"){
for (var i=0; i<this.onStopHooks.length; i++) {
this.onStopHooks[i]();
}
}
} else if (evt.data.indexOf("file_transfer") >= 0) {
var action = xml.getElementsByTagName("filepath")[0];
var fp = action.childNodes[0].nodeValue;
// Invoke the file transfer method with the file path
if (fp != null && !fp.equals("")) {
for (var i=0; i<this.onFileHooks.length; i++){
this.onFileHooks[i](fp);
}
}
}
} else {
var dataObj = JSON.parse( evt.data );
if ( dataObj.route ) {
for (var i=0; i<this.onMessageHooks.length; i++){
this.onMessageHooks[i](dataObj.route, dataObj.data);
};
} else {
for (var i=0; i<this.onMessageHooks.length; i++){
this.onMessageHooks[i]( "route", dataObj );
};
}
}
};
/** @constant */
ECSjs.ECS = "ecs";
/** @constant */
ECSjs.INTERACTIVE_SPACES = "interactiveSpaces";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment