Skip to content

Instantly share code, notes, and snippets.

@vojtatom
Last active March 7, 2019 19:00
Show Gist options
  • Select an option

  • Save vojtatom/3ec16611fe3c990af8605eb5b5a104c2 to your computer and use it in GitHub Desktop.

Select an option

Save vojtatom/3ec16611fe3c990af8605eb5b5a104c2 to your computer and use it in GitHub Desktop.
SAGE2 animation sync
// SAGE2 is available for use under the SAGE2 Software License
//
// University of Illinois at Chicago's Electronic Visualization Laboratory (EVL)
// and University of Hawai'i at Manoa's Laboratory for Advanced Visualization and
// Applications (LAVA)
//
// See full text, terms and conditions in the LICENSE.txt included file
//
// Copyright (c) 2014
/*
following code contains tips how to implement "realtime"
(not really) state sync for app with "animation": true in instructions.json
presume I have in my instructions.json:
...
"load": {
"key1": whatever,
"key2": ...,
"key3": null
},
...
NOTES:
* do not use objects as elements of load and do
not replace values with objects, use arrays instead
(but you can use objects as element of an array)
*/
var app = SAGE2_App.extend({
init: function(data){
/* required and custom init, calling functions, other stuff */
/* this.state variable is in consistent state as you would assume, either
loaded from instructions.json or downloaded from server */
},
load: function(date) {
/* perform load, state is in consistent state, same as above */
},
draw: function(date) {
/* add the following call to the end or beginning of draw, depending on what works or you... */
this.stateDistribute();
/* draw stuff for ex. this.app.draw() */
/* or here this.stateDistribute(); */
},
/* force clients to distribute state (or parts of it) via broadcast */
stateDistribute: function(){
/* create lastRefresh in case you haven't done that before;
following 3 lines can be deleted
and this.lastRefresh = Date.now(); moved into init */
if (!('lastRefresh' in this)){
this.lastRefresh = Date.now();
}
/* setup custom time timerange how often should state be forced to update */
if (Date.now() - this.lastRefresh > 3000){
this.lastRefresh = Date.now();
/* using isMaster is possibly a weak point, but it never failed in testing */
/* basically what you want is to choose only one browser running this app to perform following code */
if(isMaster){
/* tldr: set all keys of load you want to update!!*/
/* manually set individual properties of new temporary state,
keys and values in following object will be distributed and saved
into state on each client,
therefore you should use only keys previously set in load (in instructions.js)*/
let newState = {
'key1' : this.getSomeValuesForKeyOne(),
'key2' : this.anotherCall(),
'key3' : this.oneMore(),
};
/* broadcast state accross browsers */
this.broadcast('stateUpdate', newState);
}
}
},
stateUpdate: function(newState){
/* setup individual keys in this.state from newState */
for (let key in newState){
this.state[key] = newState[key];
}
/* some other magic you want to do with your new freshly synced this.state */
/* not neccesary but why not, just in case you want to use this function asynchronously */
this.SAGE2Sync(true);
},
});
@vojtatom
Copy link
Copy Markdown
Author

vojtatom commented Mar 7, 2019

...

    draw: function(date) {

        /* draw stuff */

        this.stateDistribute();
    },

    stateDistribute: function(){
        if (!('lastRefresh' in this)){
            this.lastRefresh = Date.now();
        }

        if (Date.now() - this.lastRefresh > 3000){
            this.lastRefresh = Date.now();
            
            if(isMaster){
                /* alternative approach to distribute state of master browser directly
                    by copying selected keys from this.state */
                let stateKeys = ['key1', 'key2', 'key3'];
                let newState = {};
                for(let key of stateKeys){
                    newState[key] = this.state[key];
                }

                this.broadcast('stateUpdate', newState);
            }
        }
    },

    stateUpdate: function(newState){
        for (let key in newState){
            this.state[key] = newState[key];
        }
        this.SAGE2Sync(true);
    },

...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment