1 /** 2 * @fileOverview 3 * telepathy.enchant.js 4 * @version 0.1.0 5 * @require enchant.js v0.8.0+ 6 * @author UEI Corporation 7 */ 8 (function() { 9 /** 10 * @namespace enchant.telepathy 11 */ 12 enchant.telepathy = {}; 13 14 /** 15 * @type String 16 */ 17 enchant.telepathy.SEND_API_URL = 'http://skylab.enchantmoon.com/moonblock/add_data/'; 18 /** 19 * @type String 20 */ 21 enchant.telepathy.RECV_API_URL = 'http://skylab.enchantmoon.com/moonblock/watch/'; 22 23 /** 24 * @type String 25 */ 26 enchant.Event.TELEPATHY = 'telepathy'; 27 28 /** 29 * @scope enchant.telepathy.Telepathy.prototype 30 */ 31 enchant.telepathy.Telepathy = enchant.Class.create(enchant.Event, { 32 /** 33 * @name enchant.telepathy.Telepathy 34 * @class 35 * @constructs 36 * @extends enchant.Event 37 */ 38 initialize: function(channel, data) { 39 enchant.Event.call(this, enchant.Event.TELEPATHY); 40 41 /** 42 * @type String 43 */ 44 this.channel = channel; 45 /** 46 * @type * 47 */ 48 this.data = data; 49 } 50 }); 51 52 /** 53 * @scope enchant.telepathy.TelepathySense.prototype 54 */ 55 enchant.telepathy.TelepathySense = enchant.Class.create(enchant.EventTarget, { 56 /** 57 * @name enchant.telepathy.TelepathySense 58 * @class 59 * @construct 60 * @extends enchant.EventTarget 61 */ 62 initialize: function() { 63 enchant.EventTarget.call(this); 64 65 /** 66 * @type Object 67 */ 68 this.channelers = {}; 69 /** 70 * @type Object 71 */ 72 this.eventSources = {}; 73 /** 74 * @type enchant.telepathy.Telepathy 75 */ 76 this.lastTelepathy = null; 77 /** 78 * @type String 79 */ 80 this.sendAPI = enchant.telepathy.SEND_API_URL; 81 /** 82 * @type String 83 */ 84 this.recvAPI = enchant.telepathy.RECV_API_URL; 85 86 this.addEventListener(enchant.Event.TELEPATHY, this._ontelepathy); 87 }, 88 /** 89 * @param {enchant.Event} evt 90 * @private 91 */ 92 _ontelepathy: function(evt) { 93 var i, l, 94 channelers = this.channelers[evt.channel]; 95 96 this.lastTelepathy = evt; 97 98 if (!channelers) { 99 return; 100 } 101 102 for (i = 0, l = channelers.length; i < l; i++) { 103 channelers[i].dispatchEvent(evt); 104 } 105 }, 106 /** 107 */ 108 addChanneler: function(channel, target) { 109 if (this.channelers[channel]) { 110 if (this.channelers[channel].indexOf(target) === -1) { 111 this.channelers[channel].push(target); 112 } 113 } else { 114 this.channelers[channel] = [ target ]; 115 } 116 }, 117 /** 118 */ 119 removeChanneler: function(channel, target) { 120 var i; 121 122 if (!this.channelers[channel]) { 123 return; 124 } 125 126 i = this.channelers[channel].indexOf(target); 127 128 if (i !== -1) { 129 this.channelers[channel].splice(i, 1); 130 } 131 }, 132 /** 133 */ 134 send: function(channel, message) { 135 var xhr = new XMLHttpRequest(), 136 data = JSON.stringify({ value: message }); 137 138 xhr.open('POST', this.sendAPI + channel, true); 139 xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 140 xhr.addEventListener('error', function(evt) { 141 var errorEvent = new enchant.Event(enchant.Event.ERROR); 142 errorEvent.message = 'Cannot send telepathy: ' + channel; 143 this.dispatchEvent(errorEvent); 144 }.bind(this)); 145 xhr.send('object=' + data); 146 }, 147 /** 148 */ 149 open: function(channel) { 150 var eventSource = new EventSource(this.recvAPI + channel); 151 152 eventSource.addEventListener('message', function(evt) { 153 var i, l, 154 data = JSON.parse(evt.data), 155 stream = data.objects; 156 157 for (i = 0, l = stream.length; i < l; i++) { 158 this.dispatchEvent(new enchant.telepathy.Telepathy(channel, JSON.parse(stream[i]).value)); 159 } 160 }.bind(this)); 161 162 this.eventSources[channel] = eventSource; 163 }, 164 /** 165 */ 166 close: function(channel) { 167 var eventSource = this.eventSources[channel]; 168 169 if (eventSource) { 170 eventSource.close(); 171 delete this.eventSources[channel]; 172 delete this.channelers[channel]; 173 } 174 }, 175 /** 176 */ 177 closeAll: function() { 178 for (var channel in this.eventSources) { 179 this.close(channel); 180 } 181 }, 182 /** 183 */ 184 finalize: function() { 185 this.clearEventListener(); 186 this.closeAll(); 187 this.channelers = {}; 188 } 189 }); 190 191 }()); 192