topical media & game development

talk show tell print

mobile-query-three-js-tquery.loop.js / js



  
////////////////////////////////////////////////////////////////////////////

// //
////////////////////////////////////////////////////////////////////////////

Handle the rendering loop @class This class handle the rendering loop
parameter: {THREE.World} world the world to display (optional)

  
  tQuery.Loop        = function()
  {        
          // internally if world present do that
          this._hooks        = [];
          this._lastTime        = null;
  };
  
  // make it pluginable
  tQuery.pluginsInstanceOn(tQuery.Loop);
  
  
destructor

  
  tQuery.Loop.prototype.destroy        = function()
  {
          this.stop();
  }
  
  
////////////////////////////////////////////////////////////////////////////

// //
////////////////////////////////////////////////////////////////////////////

start looping
returns: {tQuery.Loop} chained API

  
  tQuery.Loop.prototype.start        = function()
  {
          if( this._timerId )        this.stop();
          this._timerId        = requestAnimationFrame( this._onAnimationFrame.bind(this) );
          // for chained API
          return this;
  }
  
  
stop looping
returns: {tQuery.Loop} chained API

  
  tQuery.Loop.prototype.stop        = function()
  {
          cancelAnimationFrame(this._timerId);
          this._timerId        = null;
          // for chained API
          return this;
  }
  
  tQuery.Loop.prototype._onAnimationFrame        = function()
  {
          // loop on request animation loop
          // - it has to be at the begining of the function
          // - see details at http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
  	this._timerId	= requestAnimationFrame( this._onAnimationFrame.bind(this) );
  
          // update time values
          var now                = tQuery.now()/1000;
          if( !this._lastTime )        this._lastTime = now - 1/60;
          var delta        = now - this._lastTime;
          this._lastTime        = now;
  
          // run all the hooks - from lower priority to higher - in order of registration
          for(var priority = 0; priority <= this._hooks.length; priority++){
                  if( this._hooks[priority] === undefined )        continue;
                  var callbacks        = this._hooks[priority].slice(0)
                  for(var i = 0; i < callbacks.length; i++){
                          callbacks[i](delta, now);
                  }
          }
  }
  
  
////////////////////////////////////////////////////////////////////////////

// Handle the hooks //
////////////////////////////////////////////////////////////////////////////

tQuery.Loop.prototype.PRE_RENDER = 20; tQuery.Loop.prototype.ON_RENDER = 50; tQuery.Loop.prototype.POST_RENDER = 80;
hook a callback at a given priority
parameter: {Number} priority for this callback
parameter: {Function} callback the function which will be called function(time){}
returns: {Function} the callback function. usefull for this._callback = loop.hook(this._callback.bind(this)) and later loop.unhook(this._callback)

  
  tQuery.Loop.prototype.hook        = function(priority, callback)
  {
          // handle parameters
          if( typeof priority === 'function' ){
                  callback        = priority;
                  priority        = this.PRE_RENDER;
          }
  
          this._hooks[priority]        = this._hooks[priority] || [];
          console.assert(this._hooks[priority].indexOf(callback) === -1)
          this._hooks[priority].push(callback);
          return callback;
  }
  
  
unhook a callback at a given priority
parameter: {Number} priority for this callback
parameter: {Function} callback the function which will be called function(time){}
returns: {tQuery.Loop} chained API

  
  tQuery.Loop.prototype.unhook        = function(priority, callback)
  {
          // handle parameters
          if( typeof priority === 'function' ){
                  callback        = priority;
                  priority        = this.PRE_RENDER;
          }
  
          var index        = this._hooks[priority].indexOf(callback);
          console.assert(index !== -1);
          this._hooks[priority].splice(index, 1);
          this._hooks[priority].length === 0 && delete this._hooks[priority]
          // for chained API
          return this;
  }
  
  // bunch of shortcut
  // - TODO should it be in a plugin ?
  
  tQuery.Loop.prototype.hookPreRender        = function(callback){ return this.hook(this.PRE_RENDER, callback);        };
  tQuery.Loop.prototype.hookOnRender        = function(callback){ return this.hook(this.ON_RENDER, callback);        };
  tQuery.Loop.prototype.hookPostRender        = function(callback){ return this.hook(this.POST_RENDER, callback);        };
  tQuery.Loop.prototype.unhookPreRender        = function(callback){ return this.unhook(this.PRE_RENDER, callback);        };
  tQuery.Loop.prototype.unhookOnRender        = function(callback){ return this.unhook(this.ON_RENDER, callback);        };
  tQuery.Loop.prototype.unhookPostRender        = function(callback){ return this.unhook(this.POST_RENDER, callback);        };
  


(C) Æliens 04/09/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.