facebook

JS timer different between devices : CLOSED

  1. MobiOne Archive
  2.  > 
  3. Getting Help – General
Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #349358 Reply

    Code_A
    Member

    I am running into an issue that doesn’t make sense to me. Hopefully someone can help me shed some light on this.

    I have two timers, one that fires 60 times / sec., and another one that fires every second to display how many times the main timer fired during the 1 second interval. This second timer is just confirming the main timer is working as expected (i.e., firing 60 times / second).

    All works fine in the simulator (getting ~60 fires), however I am getting vastly different results depending on the device I install the app on, for example:
    iPhone5 = ~60 (as expected!)
    iPod4 = ~25
    iPad1 = ~25
    Droid Xyboard 8.2= ~35

    Why are they not all ~60? I wouldn’t expect hardware would make the big of a difference in the timer. Does this have something to do with the asynchronous nature of the timers, or is there a flaw in my logic? Is there a better way to implement the timer to get them all at 60 no matter what the device?

    this.count = 0;
    this.start(); //start main timer
    
    this.start = function() {
            var self = this;
            this.oneSecondTimer();  //start timer to display count every second
            setInterval(function() {
                self.count++;
            }, 1000/60 );  //60 frames per second
        };
        
    this.oneSecondTimer = function(){
            var self = this;
            setInterval(function() {
                alert(self.count);
                self.count = 0;
            }, 1000)
        };
    #349369 Reply

    Hi Code A,

    I shared your issue with the dev team and learned that this happen because there is no guarantee on how often timer procedures are called. They can eat battery on mobile browsers so usually this time is limited for mobile devices.

    To be as fast as and as battery-friendly as possible you must use requestAnimationFrame

    #349371 Reply

    Code_A
    Member

    Octavio, thank you for the information. I will try to implement the timer on the way that you have suggested. Hopefully I get more consistent results using this method!

    #349403 Reply

    Code_A
    Member

    So I am trying to implement this but I am not having much luck. Hopefully someone with more JS experience can help me out. All this code worked when I was using sertInterval(), but now that I have switched to requestAnimationFrame() method it no longer works after one execution. I feel like it has something to do with the *this* keyword. I have tried several different variations but to no avail. Any ideas?

    this.start();
    
    this.start = function tick() {
    
            var self = this;
            requestAnimationFrame(tick); 
            self.loop ();  // <--- throws an error telling me this function is undefined after first execution!!!
    
        };
    
    this.loop = function () {
                this.update();
                this.draw();
        };
    #349405 Reply

    Hi CodeA,

    This is not a direct answer, but there might be some explanation somewhere in these lines:

    http://learn.jquery.com/javascript-101/this-keyword/

    TG

    #349407 Reply

    Code_A
    Member

    Ok. So I have simplified the code to just run a recursive loop using this requestAnimationFrame() Example. I can only get the loop() function to execute once. Any help on this would be greatly appreciated. I have also included the .js file. Just add it to a .mobi file and it should run.

    var test;
    
    function testThis() {
    
        
        this.start = function tick() {
            requestAnimationFrame(tick);
            this.loop();
    
        };
             
        this.loop = function () {
            alert("looping...");
        };
    
    }
    
    window.onload = function() {
        test = new testThis().start();
    };
    Attachments:
    You must be logged in to view attached files.
    #349409 Reply

    Hi CodeA,

    Here is a looping version for you.

    Got rid of all the “this” syntax to simplify.

    Added a START button to kick things off, so one can setup the console view etc to see the trace output.

    TG

    See attachment CodeA.mobi

    Attachments:
    You must be logged in to view attached files.
    #349410 Reply

    Code_A
    Member

    TG, thank you for your continued support. I appreciate your help with this issue.

    One thing I should’ve mentioned is that all of my code is contained within the single .js file and I use an html widget as canvas to draw the game. I could try to separate out the looping part as you have suggested, but before restructuring all of my code I wanted to see if there was a way to get it to work the way I have it currently organized.

    I have to think there is a way to maintain scope when calling the requestAnimationFrame function. I was able to do it with setInterval, but why not now? What is different?

    #349416 Reply

    Hi CodeA,

    Here is your code fixed to loop.

    I think there were two issues:
    1 – THIS reference: was always pointing to window() and causing your code not be found in the right place.
    2 – the function that calls the requestAnimationFrame() recursively needs to have the timestamp parameter in the definition.

    Yada yada yada – it’s working !

    I still have the execution start tied to the START button to control it.
    You can easily lock it to window.onload.

    TG

    Attachments:
    You must be logged in to view attached files.
    #349425 Reply

    Code_A
    Member

    Thanks again for all of your help. I have found your example to be very useful and a good reference as I try to figure this out.
    @tguneysu wrote:

    1 – THIS reference: was always pointing to window() and causing your code not be found in the right place.

    How can I get THIS to remain in the scope of my start() function during the recursive call?

    #349427 Reply

    I found this article (pun intended) explaining scope that is very helpful:
    http://javascriptplayground.com/blog/2012/04/javascript-variable-scope-this/

    Also:

    
    //This calls myFunction with "this" set to obj.
    myFunction.call(obj, arg1, arg2, ...);
    

    Along with this, if you do a series of “console.log(this)” displays, you can trace the “this” settings.

    TG

    #349445 Reply

    Code_A
    Member

    @TG (or anyone else!)
    Thank you for your continued support. I have read the article you posted along with some others, but I am struggling to get this to work. I can get it working just fine using the JS timer, but not when I use the requestAnimationFrame() method.

    I have put together a better example of my program and the exact situation I am facing. If you have time, I would appreciate you taking one more look at my code to try to get it working. Make sure the .test.js is included the JS libraries section of the .mobi file. When it runs, you should see it counting the loop iterations.

    Thanks again.

    Attachments:
    You must be logged in to view attached files.
    #349510 Reply

    Code_A
    Member

    Maybe another way to ask the same question about THIS:

    Here is how I maintain the scope of THIS using the setInterval() method (and it works):

    this.start = function tick(timestamp) {
            var self = this;
            setInterval(function() { 
            self.loop();
            }, 1000/60);
        };
        
        this.loop = function () {
            alert("looping...");
        };

    Here I am trying to maintain the scope of THIS using the same logic with the recursive requestAnimationFrame() method (but it doesn’t work):

    this.start = function tick(timestamp) {
            var self = this;  //recursive call is resetting the scope of THIS!!!
            requestID = requestAnimationFrame(tick);
            self.loop();
        };
        
        this.loop = function () {
            alert("looping...");
        };

    How do I maintain the scope of THIS with the recursive function?

    #349514 Reply

    Code_A
    Member

    After much searching, I finally found the solution. This is how you can maintain the scope of THIS with a recursive function call.

    this.start = function () {
            var self = this;
            requestAnimationFrame(function(){self.start()});  //this is how you make the recursive call to the function
            self.loop();
        };
        
        this.loop = function () {
            alert("looping...");
        };

    Thanks for the help everyone.

Viewing 14 posts - 1 through 14 (of 14 total)
Reply To: JS timer different between devices : CLOSED

You must be logged in to post in the forum log in