OpenROV /
openrov-cockpit
| 1 | /* |
||
| 2 | This abstraction presents the Socket.io (and potentially other |
||
| 3 | transports) as an EventEmiiter. It takes care of forwarding |
||
| 4 | the messages between the emitter and the message transport. |
||
| 5 | */ |
||
| 6 | (function () { |
||
| 7 | var socketIOtoEmitterBridge = function (socket, emitter) { |
||
| 8 | this.socket = socket; |
||
| 9 | var self = this; |
||
| 10 | this.emitter = emitter; |
||
| 11 | this.senderID = generateUUID(); |
||
| 12 | this.cleanupFunctions = []; |
||
| 13 | //Every time something emits on the EventEmitter, we need to forward those on to the socket.IO. Technically we could improve |
||
| 14 | //on this by handling it like we do the SocketIO->eventEmitter below, by listening to the registrations in Socket.IO and only |
||
| 15 | //forwarding those messages when something emits them on the emitter. But then again, socket.IO is probablly already doing that |
||
| 16 | //filtering for us... so it might just add complexity with no real gain. |
||
| 17 | //Apparently socket checks the last variable for a function callback and |
||
| 18 | //does magic. Have to send only the right number of arguments. |
||
| 19 | var ignoreEvents = [ |
||
| 20 | 'newListener', |
||
| 21 | 'removeListener' |
||
| 22 | ]; |
||
| 23 | emitter.onAny(function () { |
||
| 24 | if (!ignoreEvents.includes(this.event)) { |
||
| 25 | var args = new Array(arguments.length); |
||
| 26 | for (var i = 0; i < args.length; ++i) { |
||
| 27 | //i is always valid index in the arguments object |
||
| 28 | args[i] = arguments[i]; |
||
| 29 | } |
||
| 30 | if (args[args.length - 1] === self.senderID) { |
||
| 31 | return; |
||
| 32 | } |
||
| 33 | if (args[0] == this.event) { |
||
| 34 | args.shift(); //to catch behavior change of onyAny after ugprade |
||
| 35 | } |
||
| 36 | //args.push(self.senderID) |
||
| 37 | socket.emit.apply(socket, [this.event].concat(args)); //console.log("Socket <1- ",this.event); |
||
| 38 | } |
||
| 39 | }); |
||
| 40 | //If the emitter has a withHistory function, we need to bridge to the data cache in the socket.io system. We do so by |
||
| 41 | //checking for the last value in the cache and "seeding" the cache in the emitter with the value before letting the |
||
| 42 | //original withHistory call take place. |
||
| 43 | if (emitter.withHistory) { |
||
| 44 | var orig_wh = emitter.withHistory.on; |
||
| 45 | emitter.withHistory.on = function (type, fn) { |
||
| 46 | self.socket.emit('fromcache', type, function () { |
||
| 47 | if (arguments.length == 0){ |
||
|
0 ignored issues
–
show
|
|||
| 48 | return; |
||
| 49 | } |
||
| 50 | var args = new Array(arguments.length); |
||
| 51 | for (var i = 0; i < args.length; ++i) { |
||
| 52 | args[i] = arguments[i]; |
||
| 53 | } |
||
| 54 | if (args[args.length - 1] === self.senderID) { |
||
| 55 | return; |
||
| 56 | } |
||
| 57 | // This is the hook to update the socket cache used in app.js to prepopulate the last messages |
||
| 58 | if (self.socket.lvcCache) { |
||
| 59 | self.socket.lvcCache[type]=args; |
||
| 60 | } |
||
| 61 | args.push(self.senderID); |
||
| 62 | emitter.emit.apply(emitter, [type].concat(args)); //TODO: If this works, use the args pattern for performance. |
||
| 63 | // console.log("Socket -2> ",type); |
||
| 64 | }); |
||
| 65 | orig_wh(type, fn); |
||
| 66 | }; |
||
| 67 | this.cleanupFunctions.push(function () { |
||
| 68 | emitter.withHistory.on = orig_wh; |
||
| 69 | }); |
||
| 70 | } |
||
| 71 | var listeningTo = {}; |
||
| 72 | var linkSocketIOEventToEmitter = function (aType) { |
||
| 73 | if (listeningTo[aType] === undefined) { |
||
| 74 | var handleEvent = function () { |
||
| 75 | var args = new Array(arguments.length); |
||
| 76 | for (var i = 0; i < args.length; ++i) { |
||
| 77 | //i is always valid index in the arguments object |
||
| 78 | args[i] = arguments[i]; |
||
| 79 | } |
||
| 80 | args = args.filter(function (item) { |
||
| 81 | return item !== null; |
||
| 82 | }); |
||
| 83 | if (args[args.length - 1] === self.senderID) { |
||
| 84 | return; |
||
| 85 | } |
||
| 86 | args.push(self.senderID); |
||
| 87 | self.emitter.emit.apply(self.emitter, [aType].concat(args)); //console.log("Socket -3> ",aType); |
||
| 88 | }; |
||
| 89 | self.socket.on(aType, handleEvent); |
||
| 90 | self.cleanupFunctions.push(function () { |
||
| 91 | self.socket.off(aType, handleEvent); |
||
| 92 | }); |
||
| 93 | listeningTo[aType] = true; |
||
| 94 | self.socket.emit('fromcache', aType, function () { |
||
| 95 | if (arguments.length == 0) { |
||
|
0 ignored issues
–
show
It is recommended to use
=== to compare with 0.
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator. Loading history...
|
|||
| 96 | return; |
||
| 97 | } |
||
| 98 | var args = new Array(arguments.length); |
||
| 99 | for (var i = 0; i < args.length; ++i) { |
||
| 100 | //i is always valid index in the arguments object |
||
| 101 | args[i] = arguments[i]; |
||
| 102 | } |
||
| 103 | args = args.filter(function (item) { |
||
| 104 | return item !== null; |
||
| 105 | }); |
||
| 106 | if (args[args.length - 1] === self.senderID) { |
||
| 107 | return; |
||
| 108 | } |
||
| 109 | args.push(self.senderID); |
||
| 110 | emitter.emit.apply(self.emitter, [aType].concat(args)); //TODO: If this works, use the args pattern for performance. |
||
| 111 | //console.log("Socket -4> ",aType); |
||
| 112 | }); |
||
| 113 | } |
||
| 114 | }; |
||
| 115 | //The emitter might already have listeners, if so we need to wire those up to Socket.IO |
||
| 116 | Object.keys(emitter._events).forEach(function (event) { |
||
| 117 | linkSocketIOEventToEmitter(event); |
||
| 118 | }); |
||
| 119 | //Everytime a function registers a listener with the eventEmitter, we need to also register that event with socket.IO so that |
||
| 120 | //it will send along those messages. When the messages arrive, we need to then emit them on the EventEmitter. |
||
| 121 | emitter.on('newListener', function (aType, aListener) { |
||
| 122 | if (aType !== '*') { |
||
| 123 | linkSocketIOEventToEmitter(aType); |
||
| 124 | } |
||
| 125 | }); |
||
| 126 | return this; |
||
| 127 | }; |
||
| 128 | //This will undo the linkage between the emitter and the socket. |
||
| 129 | socketIOtoEmitterBridge.prototype.stop = function stop() { |
||
| 130 | cleanupFunctions.forEach(function (fn) { |
||
| 131 | fn(); |
||
| 132 | }); |
||
| 133 | cleanupFunctions = []; |
||
| 134 | }; |
||
| 135 | window.SocketIOtoEmitterBridge = socketIOtoEmitterBridge; |
||
| 136 | }()); |
Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.
Read more about comparison operations.