Instantly share code, notes, and snippets.
Created
June 3, 2012 22:26
-
Star
1
(1)
You must be signed in to star a gist -
Fork
0
(0)
You must be signed in to fork a gist
-
Save digitaljohn/2865226 to your computer and use it in GitHub Desktop.
Hybrid of both the Shared State and Message Google+ hangout API features.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var SharedData = Class.extend({ | |
// Storage area for the latest key values | |
_cache: {}, | |
// Packet Signature | |
_packetSig: "SDP", | |
// The packet that gets sent via sendMessage | |
_packet: {k:"",v:""}, | |
// Refernence to the timeout | |
_deltaTimeout: null, | |
_messageTimeout: null, | |
// Refernence to what changed | |
_deltaChanged: [], | |
_messageChanged: [], | |
// The last time a delta was sent | |
_lastDelta: 0, | |
// How often can the delta change (every 1 second) | |
_maxDeltaUpdate: 1000, | |
// Setup and attach listeners to the Google+ Hangout API | |
init: function() | |
{ | |
console.log("SharedData::init"); | |
var _this = this; | |
gapi.hangout.data.onStateChanged.add(function(e){ | |
_this._onStateChanged(e); | |
}); | |
gapi.hangout.data.onMessageReceived.add(function(e){ | |
_this._onMessageReceived(e); | |
}); | |
}, | |
setValue: function(key, val) | |
{ | |
// Store the value in the local cache | |
this._cache[key] = val; | |
// Store the fact that the key changed and needs to be sent via message and shared state | |
this._messageChanged.push(key); | |
this._deltaChanged.push(key); | |
// Set a timeout to 1 ms so if you have a script changing multiple values... | |
// they will cue up and be sent in a single packet via sendMessage | |
if( this._messageTimeout == null ) | |
{ | |
var _this = this; | |
this._messageTimeout = setTimeout(function(){ | |
_this._sendMessage(); | |
}, 1); | |
} | |
// Set a timeout to send the data via the shared state. Limit it! | |
if( this._deltaTimeout == null ) | |
{ | |
// Make sure it wont max out the limit... limiting the timeout to a range of 1-1000 ms. | |
var time = Math.max(1, this._maxDeltaUpdate - (this._now() - this._lastDelta) ); | |
var _this = this; | |
this._deltaTimeout = setTimeout(function(){ | |
_this._sendDelta(); | |
}, time); | |
} | |
}, | |
getValue: function(key) | |
{ | |
if(this._cache[key] != undefined) | |
{ | |
// Found updated key... return that | |
return this._cache[key]; | |
} | |
else | |
{ | |
// No key found... return from the Shared Data | |
return gapi.hangout.data.getValue( key ); | |
} | |
}, | |
_sendMessage: function() | |
{ | |
// Build a message of key value pairs | |
var message = []; | |
for(var i in this._messageChanged) | |
{ | |
message.push( {k:this._messageChanged[i], v:this._cache[ this._messageChanged[i]} ); | |
} | |
// Clear the changed array | |
this._messageChanged = []; | |
// Send the data with a signature! | |
gapi.hangout.data.sendMessage( this._packetSig+":"+JSON.stringify(message) ); | |
// Clear the timeout back to null | |
this._messageTimeout = null; | |
}, | |
_sendDelta: function() | |
{ | |
// Build a delta of key value pairs | |
var delta = {}; | |
for(var i in this._deltaChanged) | |
{ | |
delta[ this._deltaChanged[i] ] = this._cache[ this._deltaChanged[i] ]; | |
} | |
// Clear the changed array | |
this._deltaChanged = []; | |
// Send the data! | |
gapi.hangout.data.submitDelta( delta ); | |
// Clear the timeout back to null | |
this._deltaTimeout = null; | |
// Remember when it we last used submitDelta for rate limiting | |
this._lastDelta = this._now(); | |
}, | |
_onStateChanged: function(event) | |
{ | |
var key; | |
var val; | |
// Loop though the added keys and update the cache | |
for (var i in event.addedKeys) { | |
key = event.addedKeys[i].key; | |
val = event.addedKeys[i].value; | |
this._updateCache(key, val); | |
} | |
}, | |
_onMessageReceived: function(event) | |
{ | |
// Return if packet does not have the valid sigature | |
var split = event.message.split(":"); | |
if(split[0] != this._packetSig) return; | |
// Decode the packet | |
var packet = JSON.parse( split[1] ); | |
// Loop though the key value pairs and update the cache | |
for(var i in packet) | |
{ | |
this._updateCache(packet[i].k, packet[i].v); | |
} | |
}, | |
_updateCache: function(key, val) | |
{ | |
// Store the key if there is a change | |
if( this._cache[key] != val ) | |
{ | |
this._cache[key] = val; | |
// Dispatch the change! | |
// We use a core event bus to hook various parts of the application together. Roll your own however you prefer. | |
bus.dispatchEvent( { type:"SharedData.CHANGE", key:key, value:val } ); | |
} | |
}, | |
// Return now doen to a 1000ms accuracy. | |
_now: function() | |
{ | |
return (new Date()).getTime(); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment