Skip to content

Commit

Permalink
Added getStatus method to scene node
Browse files Browse the repository at this point in the history
Added "loading" and "loaded" events to geometry and texture nodes
Fixed render interval
  • Loading branch information
xeolabs committed Mar 28, 2012
1 parent 04b17b2 commit b89aedf
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 95 deletions.
2 changes: 1 addition & 1 deletion build.xml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@

<fileset dir="${SRC_DIR}" includes="scenejs/tag/tagModule.js"/>

<fileset dir="${SRC_DIR}" includes="scenejs/load-status/loadStatusModule.js"/>
<fileset dir="${SRC_DIR}" includes="scenejs/status/sceneStatusModule.js"/>

<fileset dir="${SRC_DIR}" includes="scenejs/geometry/geometry.js"/>
<fileset dir="${SRC_DIR}" includes="scenejs/geometry/objects/teapot.js"/>
Expand Down
26 changes: 1 addition & 25 deletions src/scenejs/core/node.js
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ SceneJS._Node.prototype._compileNodes = function() { // Selected children - usef
child = children[i];

if (SceneJS_compileModule.preVisitNode(child)) {
child._compileWithEvents();
child._compile();
}
SceneJS_compileModule.postVisitNode(child);
}
Expand All @@ -186,30 +186,6 @@ SceneJS._Node.prototype._compileNodes = function() { // Selected children - usef
}
};


/**
* Wraps _compile to fire built-in events either side of rendering.
* @private */
SceneJS._Node.prototype._compileWithEvents = function() {

/* As scene is traversed, SceneJS_loadStatusModule will track the counts
* of nodes that are still initialising
*
* If we are listening to "loading-status" events on this node, then we'll
* get a snapshot of those stats, then report the difference from that
* via the event once we have rendered this node.
*/
var loadStatusSnapshot;
if (this.listeners["loading-status"]) {
loadStatusSnapshot = SceneJS_loadStatusModule.getStatusSnapshot();
}
this._compile();
if (this.listeners["loading-status"]) { // Report diff of loading stats that occurred while rending this tree
this._fireEvent("loading-status", SceneJS_loadStatusModule.diffStatus(loadStatusSnapshot));
}

};

/**
* Returns the SceneJS-assigned ID of the node.
* @returns {string} Node's ID
Expand Down
3 changes: 3 additions & 0 deletions src/scenejs/geometry/geometry.js
Original file line number Diff line number Diff line change
Expand Up @@ -302,13 +302,16 @@ new (function() {
this._stream = params.stream;
this.core._loading = true;

self._fireEvent("loading");

var self = this;
createGeometry(
this.scene,
this._stream,
function(geo) {
SceneJS._apply(geo, self.core);
self.core._loading = false;
self._fireEvent("loaded");
SceneJS_compileModule.nodeUpdated(self, "loaded"); // Compile again to apply freshly-loaded geometry
},
options);
Expand Down
52 changes: 0 additions & 52 deletions src/scenejs/load-status/loadStatusModule.js

This file was deleted.

85 changes: 69 additions & 16 deletions src/scenejs/scene/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,16 +199,43 @@ new (function() {
return context.getParameter(context.DEPTH_BITS);
};

window.requestAnimFrame = (function() {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function(/* function */ callback, /* DOMElement */ element) {
window.setTimeout(callback, 1000 / 60);
};
})();
if (! self.Int32Array) {

self.Int32Array = Array;
self.Float32Array = Array;

}

// Ripped off from THREE.js - https://github.com/mrdoob/three.js/blob/master/src/Three.js
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating

(function() {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame']
|| window[vendors[x] + 'RequestCancelAnimationFrame'];
}

if (!window.requestAnimationFrame)
window.requestAnimationFrame = function(callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function() {
callback(currTime + timeToCall);
},
timeToCall);
lastTime = currTime + timeToCall;
return id;
};

if (!window.cancelAnimationFrame)
window.cancelAnimationFrame = function(id) {
clearTimeout(id);
};
}());

/** Sets regular expression to select "tag" nodes to included in render passes
*/
Expand Down Expand Up @@ -236,7 +263,7 @@ new (function() {
compileMode: compileFlags.level == SceneJS_compileModule.COMPILE_EVERYTHING ?
SceneJS_DrawList.COMPILE_SCENE : SceneJS_DrawList.COMPILE_NODES,
resort: compileFlags.resort });
this._compileWithEvents();
this._compile();
SceneJS_compileModule.finishSceneCompile();
return true; // Redraw needed
}
Expand Down Expand Up @@ -273,6 +300,7 @@ new (function() {
* Starts the render loop for this scene
*/
Scene.prototype.start = function(cfg) {

if (this._destroyed) {
throw SceneJS_errorModule.fatalError(SceneJS.errors.NODE_ILLEGAL_STATE, "Scene has been destroyed");
}
Expand All @@ -292,6 +320,8 @@ new (function() {

SceneJS_compileModule.nodeUpdated(this, "start");

var sceneId = self.attr.id;

window[fnName] = function() {
if (self._running && !self._paused) { // idleFunc may have paused scene
if (cfg.idleFunc) {
Expand All @@ -301,7 +331,7 @@ new (function() {
return;
}
SceneJS_eventModule.fireEvent(SceneJS_eventModule.SCENE_IDLE, {
sceneId: self.attr.id
sceneId: sceneId
});
if (self._compileScene()) { // Attempt pending compile and redraw
sleeping = false;
Expand All @@ -314,20 +344,20 @@ new (function() {
fps: getFPS()
});
}
window.requestAnimFrame(window[fnName]);
window.requestAnimationFrame(window[fnName]);
} else {
if (!sleeping && cfg.sleepFunc) {
cfg.sleepFunc();
}
sleeping = true;
window.requestAnimFrame(window[fnName]);
window.requestAnimationFrame(window[fnName]);
}
} else {
window.requestAnimFrame(window[fnName]);
window.requestAnimationFrame(window[fnName]);
}
};
this._startCfg = cfg;
window.requestAnimFrame(window[fnName]); // Push one frame immediately
window.requestAnimationFrame(window[fnName]); // Push one frame immediately
}
};

Expand Down Expand Up @@ -488,6 +518,29 @@ new (function() {
return node ? SceneJS._selectNode(node) : null;
};

/**
* Returns the current status of this scene.
*
* When the scene has been destroyed, the returned status will be a map like this:
*
* {
* destroyed: true
* }
*
* Otherwise, the status will be:
*
* {
* numLoading: Number // Number of asset loads (eg. texture, geometry stream etc.) currently in progress
* }
*
*/
Scene.prototype.getStatus = function() {
return (this._destroyed)
? { destroyed: true }
: SceneJS._shallowClone(SceneJS_sceneStatusModule.sceneStatus[this.attr.id]);
};


SceneJS.reset = function() {
var scenes = getAllScenes();
var temp = [];
Expand Down
35 changes: 35 additions & 0 deletions src/scenejs/status/sceneStatusModule.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* Backend that tracks statistics on loading states of nodes during scene traversal.
*
* This supports the "loading-status" events that we can listen for on scene nodes.
*
* When a node with that listener is pre-visited, it will call getStatus on this module to
* save a copy of the status. Then when it is post-visited, it will call diffStatus on this
* module to find the status for its sub-nodes, which it then reports through the "loading-status" event.
*
* @private
*/
var SceneJS_sceneStatusModule = new (function() {

this.sceneStatus = {};

var self = this;

SceneJS_eventModule.addListener(
SceneJS_eventModule.SCENE_CREATED,
function(params) {
self.sceneStatus[params.sceneId] = {
numLoading: 0
};
});

this.nodeLoading = function(node) {
this.sceneStatus[node.scene.attr.id].numLoading++;
};

this.nodeLoaded = function(node) {
this.sceneStatus[node.scene.attr.id].numLoading--;
};

})();

10 changes: 9 additions & 1 deletion src/scenejs/texture/texture.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,11 +204,19 @@ var SceneJS_textureModule = new (function() {
layer.texture = SceneJS._compilationStates.getState("video", this.scene.attr.id, layer.creationParams.video);

} else {

SceneJS_sceneStatusModule.nodeLoading(this);
this._fireEvent("loading");

var self = this;

layer.texture = createTexture(
this.scene,
layer.creationParams,
function() {

function() { // onComplete
SceneJS_sceneStatusModule.nodeLoaded(self);
self._fireEvent("loaded");
if (self._destroyed) {
destroyTexture(layer.texture);
}
Expand Down

0 comments on commit b89aedf

Please sign in to comment.