time handling

How did you habdle the time in an Application, for now I use a timer with 1 sec fireing, but when the main view is hide/change this timer is stop, so when I return to this view, there is missing lot's of seconds !
I was wandering how other keep track of time in their app ? what's the best practice, as from I've read, the number of timer is a limited resource ?

thanks
  • At 25 days, you can do things like take the number and make it a long with a bit of math (if it's<0), so it's always positive. Just use signed 64's. and with that you can make it to about 50 days after the device was powered on before you hit 0 again.
  • jim_m_58 thanks, I realize that (and actually updated my post before I read your reply), but if you didn't realize/remember that Numbers wrapped to negative at 0x7FFFFFFF, then you wouldn't think to do that. IOW saying that "System.getTimer() resets to 0 after 50 days, and you don't have to worry about negative numbers as long as you remember to convert it to unsigned Long" is a little different than saying "System.getTimer() resets to 0 after 50 days, period."

    I would prefer to be super-pedantic (yet somehow simpler) and say that System.getTimer() returns a signed 32-bit Number which becomes negative after 0x7FFFFFFF. The fact that you have to do some math and use a Long to avoid negative numbers proves that the wrapping around to negative numbers is important.

    Anyway, I'll still pretty sure that as long as you only care about the duration between two samples of System.getTimer(), then wrapping and signed vs. unsigned doesn't matter, as long as the value wrapped no more than one time between samples.
  • Having said all that, maybe Monkey C needs unsigned integer types. I gather that Java was one inspiration for Monkey C, and Java eventually added unsigned types, after initially having none....

    Since that's not going to happen any time soon, here is my one-liner function for interpreting a signed 32-bit Number as unsigned.

    // Interpret a signed 32-bit integer (Number) as an unsigned integer
    // (Positive values will not be changed, except for their type)
    //
    // Return value:
    // The reinterpreted value, as a Lang.Long (64-bit signed integer),
    // suitable for comparisons and arithmetic
    //
    // Examples:
    // 0x7FFFFFFF (32-bit signed) = 2147483647
    // 0x7FFFFFFF (unsigned) = 2147483647
    //
    // 0x80000000 (32-bit signed) = -2147483648
    // 0x80000000 (unsigned) = 2147483648
    //
    // 0xFFFFFFFF (32-bit signed) = -1
    // 0xFFFFFFFF (unsigned) = 4294967295
    //
    function interpretNumberAsUnsigned(x) {
    return x.toLong() & 0xFFFFFFFFl; // can easily be "manually inlined" for tiny memory/speed savings
    }


    Example usage:
    function test_interpretNumberAsUnsigned() {
    // (this is the largest positive Number -- i.e. signed 32-bit integer)
    var x = 0x7FFFFFFF; // 2147483647

    // Print x and the 3 numbers that come after it,
    // each as the original signed Number and the corresponding
    // value interpreted as an unsigned integer
    for (var i = 0; i < 4; i++) {
    System.println("x = " + x);
    var x_unsigned = interpretNumberAsUnsigned(x);
    System.println("x_unsigned = " + x_unsigned);

    System.println("x++;");
    System.println("");
    x++;
    }
    }


    Output:
    x = 2147483647
    x_unsigned = 2147483647
    x++;

    x = -2147483648
    x_unsigned = 2147483648
    x++;

    x = -2147483647
    x_unsigned = 2147483649
    x++;

    x = -2147483646
    x_unsigned = 2147483650
    x++;


    System.getTimer() wrapper that returns unsigned value (as Long)
    function getUnsignedSystemTimer() {
    return interpretNumberAsUnsigned(System.getTimer());
    }
  • So, from all your reading....
    I just need to display a running counter like HH:MM for the duration of my activity, and need to handle some event like displaying another view (push/pop).
    seems to be able to have that with System.getTimer() ? or shoud I better use elapseTime from activity ?
    as there are start/stop but no pause, is it concidered a pause to have the sequence start/stop/start ?

    thanks
  • If you start a recording, then stop it, then start it again, that's how you do a pause. timerTime stops when you do the "stop" and starts running again when you restart.

    elapsedTime keeps running after you do the stop, and runs until you do a save/discard.

    Both timerTime and elaspedTime are in milliseconds. If you want to display/use those as hh:mm:ss, divide by 1000 to get seconds, and then convert that into HH:MM:SS with something like:
    function toHMS(secs) {
    var hr = secs/3600;
    var min = (secs-(hr*3600))/60;
    var sec = secs%60;
    return [hr, min,sec];
    }
  • thanks jim_m_58 , I was not aware that in mokeyC we could return array like that !.
    Got something working using elapsedTime.
    thanks for all those details answers
  • Couple of comments:

    - I'm not sure what your app is, but your users may want to see timerTime in one of the fields, unless there's no way to pause the activity in your app. IOW, in your app, can users pause the activity at all, or will stopping the activity automatically save it as well? If they can pause the activity (like most built-in activities), then they may wish to see timerTime. With elapsedTimer, they get a timer that keeps going when the activity is paused.

    - Yep, returning values in an array is the most efficient way to return multiple values from a function (as opposed to using a class). Sometimes you can replace whole classes with arrays, to save memory. E.g. In the API, latitude/longitude is represented as an array ([lat, lon]), instead of a Point class (which would be seen on platforms where memory is not as much of an issue).

    - The following code to calculate minutes is slightly more efficient, and is usually how it's done (although the above code works fine):
    var min = secs % 3600 / 60; // analogous to how "sec" is calculated above


    (In practice, it will make zero difference to your app.)