I seem to be having some unexpected results with a framerate counter in javascript. Up until recently the counter has been fine and I have been running my little js app at 30fps.
It uses setTimeout() (with a time adjustment to counter the system 'falling behind').
window.requestAnimFrame = (function()
{
return function (callback) {
time += FPS;
Heartbeat._eTime = (new Date().getTime() - Heartbeat._start);
var diff = Heartbeat._eTime - time;
Heartbeat._delta = FPS - diff;
Heartbeat._deltaS = Heartbeat._delta / 1000;
window.setTimeout(callback, FPS - diff);
};
})();
Heartbeat is merely an object that contains the frame rate info.
*Here is my problem: *
_MainLoopHandler: function () {
timer = new Date().getTime();
counter = timer;
while (this._messages.length > 0 && (counter - timer) < 5)
{
// process messages from _messages array
}
counter = new Date().getTime();
// THE ABOVE IS HAPPY AT 30 FPS
while ((counter - timer) < 6) {
1 + 1;
}
// THE ABOVE WHILE IS VERY UNHAPPY :(
}
So the above code block is the function that is called from setTimeout every 33.33 milliseconds (30 fps). if I take the bottom while loop out, the FPS counter will sit happily at 30fps. However, if I leave it in, the FPS counter goes crazy. it goes up to the 200FPS 300FPS then suddenly goes -200FPS -10FPS 0.01FPS. Its completely off the wall. The while loop will only run maybe 10 times per "frame".
Note also, the hard-coded values 5 and 6 are simply a check to see if 5 or 6 milliseconds have passed while processing the loops (for load balance).
Is this simply javascript being unable to handle the amount of info or has anyone else had a similar problem.
Thanks!
I don't really know what's going on, but I think you should use local variables to control your time, constantly reassess counter
and process 1 message at a time. Also, I don't really understand that last loop (I've also renamed the variables):
_MainLoopHandler: function () {
var start = new Date().getTime();
var current;
do {
if (this._messages.length === 0) break;
// process 1 message
current = new Date().getTime();
} while (current - start < 5);
}
You can also encapsulate the timing concern in an object (not shown) to streamline the code:
_MainLoopHandler: function () {
var timing = new Timing();
do {
if (this._messages.length === 0) break;
// process 1 message
} while (timing.elapsed() < 5);
}