Snippet Gametime

Solmyr

Ultra Cool Member
Reaction score
30
I updated the documentation to include all the functions. Had kinda forgotten about it...
 

tooltiperror

Super Moderator
Reaction score
231
JASS2-esque wrappers would be a nice addition, but certainly not important to the system itself.

This is good, has undergone revisions to fix what was sub-par, and serves a purpose mappers often need.

Approved.
 

Nestharus

o-o
Reaction score
84
This is currently bugged. When the timer expires, it's elapsed time will be 1, which would be incorrect for the timestamp (1 bigger than it should be).

Here is a working version. The expirations will be a bit slower, but at least it doesn't bug up =).
JASS:

/**  
 *                               GAMETIME
 *                               written by: Solmyr
 *
 *  Requires the latest version of JassHelper.
 *  
 *  This is just an ordinary snippet that you might find useful.
 *
 *  The main purpose is to simply provide a standardized platform for tracking the
 *  duration of the game using a global timer and a time counter.
 *  It is done the way it is because timers with high expiration times can
 *  a bit inaccurate.
 *
 *  The output can be:
 *  
 *    1. A real that is returned by the Time.getExact(), the Time.getRounded() and the 
 *       Time.getDecimal() functions. The first two return the whole elapsed game time,
 *       either in an exact accurate or a rounded manner, while the third one returns the
 *       decimal part of the currently elapsed time.
 *
 *    2. An integer that is returned by the Time.getSeconds() function. The integer
 *       equals the amount of fully elapsed seconds.
 *       
 *    3. A string that is returned by the Time.getStamp() function. The string represents 
 *       a timestamp in the HH:MM:SS format. 
 *
 */

//! zinc
library Gametime {

    public struct Time extends array {

        private {
            static timer mainTimer = CreateTimer();
            static integer timeCounter = 0;
            static string timeStamp = "";
        }

        /* All of the following static methods are inline-friendly, except for getStamp(). */

        static method getSeconds() -> integer {
            return thistype.timeCounter;
        }

        static method getDecimal() -> real {
            return TimerGetElapsed(thistype.mainTimer);
        }
        
        static method getExact() -> real {
            return (TimerGetElapsed(thistype.mainTimer) + thistype.timeCounter); 
        }

        static method getRounded() -> real {
            return ((R2I(thistype.getExact() + 0.5)) * 1.0);
        }

        static method getStamp() -> string {
            integer seconds = R2I(thistype.getExact() + 0.5), minutes = 0, hours = 0;
            thistype.timeStamp = "";

            hours = (seconds / 3600);
            seconds -= (3600 * hours);

            minutes = (seconds / 60);
            seconds -= (60 * minutes);

            if (hours < 10) { thistype.timeStamp = "0"; }
            thistype.timeStamp += I2S(hours) + ":";

            if (minutes < 10) { thistype.timeStamp += "0"; }
            thistype.timeStamp += I2S(minutes) + ":";

            if (seconds < 10) { thistype.timeStamp += "0"; }

            return (thistype.timeStamp + I2S(seconds));
        }

        private static method onInit() {
            TimerStart(thistype.mainTimer, 1, false, static method() { timeCounter += 1; ResumeTimer(thistype.mainTimer); });
            PauseTimer(thistype.mainTimer);
            ResumeTimer(thistype.mainTimer);
        }
    }
}
//! endzinc
 

tooltiperror

Super Moderator
Reaction score
231
It's polite to not simply rewrite things and post them in others threads when they are active, but to tell them what to fix :)
 

Solmyr

Ultra Cool Member
Reaction score
30
This is currently bugged. When the timer expires, it's elapsed time will be 1, which would be incorrect for the timestamp (1 bigger than it should be).
I don't understand what you're trying to say here.
 

Nestharus

o-o
Reaction score
84
...

Well, your system is currently broken. For example, if you tried to get a timestamp at 1 second, this would return a timestamp of 2.


If you don't get it, just change your onInit to this since I've already explained it as well as I can.
JASS:

            TimerStart(thistype.mainTimer, 1, false, static method() { timeCounter += 1; ResumeTimer(thistype.mainTimer); });
            PauseTimer(thistype.mainTimer);
            ResumeTimer(thistype.mainTimer);


The above is the only way to fix the bug.



And more information on this bug...


When a timer expires and that timer was not previous paused (ever) or is a repeating timer, that timer will show an elapsed time of its timeout rather than an elapsed time of 0. This means that in your system, when your timer expires and you increase your counter, at that instant, the elapsed time will be 1 (not 0), meaning that your timestamp will be 1 bigger than it should be. This bug will only occur if code is used the instant the timer expires.


You should address this bug rather than just ignore it and pretend that it's not there.


To fix this bug, you must pause the timer one time. This means that you can't use a repeating timer.

Also, replace all resume timers with TimerStart(... , ... , false, ...)

ResumeTimer is slower than TimerStart : P.
 

Solmyr

Ultra Cool Member
Reaction score
30
No, it isn't broken, and that bug cannot possibly happen in normal circumstances.

There is absolutely no way you can call [ljass]Time.getStamp()[/ljass] (or any other function) at the exact moment of the timer's expiration, simply because WC3's engine is linear.

The only situation where the bug would occur is the following:
JASS:
private static method onInit() {
    TimerStart(thistype.mainTimer, 1.00, true, static method() { 
        timeCounter += 1; 
        BJDebugMsg(thistype.getStamp());
    });
}

even if you did this:
JASS:
private static method onInit() {
    TimerStart(thistype.mainTimer, 1.00, true, static method() { timeCounter += 1; });
    TimerStart(CreateTimer(), 1.00, true, static method() { BJDebugMsg(thistype.getStamp()); });
}

the bug would not occur.
 

Nestharus

o-o
Reaction score
84
Point taken : P.


I guess I was just thinking of the timer systems I've written, thus not thinking about the fact that yours wouldn't have the same issue since you don't use it in the callback ever ^)^.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Members online

      No members online now.

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top