Thread: TimerUtilsEx
View Single Post
Old 10-27-2011, 09:32 AM   #1
Bribe
User
 
Bribe's Avatar
 
Join Date: Mar 2010
Posts: 233

Submissions (1)

Bribe will become famous soon enough (30)Bribe will become famous soon enough (30)

Send a message via AIM to Bribe
Default TimerUtilsEx

This is a fixed version of Vexorian's TimerUtils.
It allows you to call NewTimer inside module initializers (Useful for elapsed game time events and other things)

Collapse JASS:
library TimerUtilsEx
/*************************************************
*
*   TimerUtilsEx
*   v2.1.0.3
*   By Vexorian, Bribe & Magtheridon96
*
*   Original version by Vexorian.
*
*   Flavors:
*       Hashtable:
*           - RAM:              Minimal
*           - TimerData:        Slow
*
*       Array:
*           - RAM:              Maximal
*           - TimerData:        Fast
*
*   All the functions have O(1) complexity.
*   The Array version is the fastest, but the hashtable
*   version is the safest. The Array version is still
*   quite safe though, and I would recommend using it.
*   The system is much slower in debug mode.
*
*   API:
*   ----
*       - function NewTimer takes nothing returns timer
*           - Returns a new timer from the stack.
*       - function NewTimerEx takes integer i returns timer
*           - Returns a new timer from the stack and attaches a value to it.
*       - function ReleaseTimer takes timer t returns integer
*           - Throws a timer back into the stack. Also returns timer data.
*       - function SetTimerData takes timer t, integer value returns nothing
*           - Attaches a value to a timer.
*       - function GetTimerData takes timer t returns integer
*           - Returns the attached value.
*
*************************************************/

    globals //Calibration
        //Use hashtable, or fast array?
        private constant boolean USE_HASH = false
        //Max Number of Timers Held in Stack
        private constant integer QUANTITY = 256
    endglobals
    
    globals
        private timer array tT
        private integer tN = 0
        private hashtable ht = InitHashtable()
    endglobals
    
    private module Init
        static if not USE_HASH then
            private static method onInit takes nothing returns nothing
                local integer i = QUANTITY
                loop
                    set i = i - 1
                    set tT[i] = CreateTimer()
                    exitwhen i == 0
                endloop
                
                set tN = QUANTITY
            endmethod
        endif
    endmodule
    
    // JassHelper doesn't support static ifs for globals.
    private struct Data extends array
        static if not USE_HASH then
            static integer array data
        endif
        implement Init
    endstruct
    
    // Double free protection
    private function ValidTimer takes integer i returns boolean
        return LoadBoolean(ht, i, 1)
    endfunction
    
    private function Get takes integer id returns integer
        debug if not ValidTimer(id) then
            debug call BJDebugMsg("[TimerUtils]Error: Tried to get data from invalid timer.")
        debug endif
        static if USE_HASH then
            return LoadInteger(ht, id, 0)
        else
            return Data.data[id - 0x100000]
        endif
    endfunction
    
    private function Set takes integer id, integer data returns nothing
        debug if not ValidTimer(id) then
            debug call BJDebugMsg("[TimerUtils]Error: Tried to attach data to invalid timer.")
        debug endif
        static if USE_HASH then
            call SaveInteger(ht, id, 0, data)
        else
            set Data.data[id - 0x100000] = data
        endif
    endfunction
    
    function SetTimerData takes timer t, integer data returns nothing
        call Set(GetHandleId(t), data)
    endfunction
    
    function GetTimerData takes timer t returns integer
        return Get(GetHandleId(t))
    endfunction
    
    function NewTimerEx takes integer data returns timer
        local integer id
        if tN == 0 then
            static if USE_HASH then
                set tT[0] = CreateTimer()
            else
                debug call BJDebugMsg("[TimerUtils]Error: No Timers In The Stack! You must increase 'QUANTITY'")
                return null
            endif
        else
            set tN = tN - 1
        endif
        set id = GetHandleId(tT[tN])
        call SaveBoolean(ht, id, 1, true)
        call Set(id, data)
        return tT[tN]
    endfunction
    
    function NewTimer takes nothing returns timer
        return NewTimerEx(0)
    endfunction
    
    function ReleaseTimer takes timer t returns integer
        local integer id = GetHandleId(t)
        local integer data = 0
        
        // Pause the timer just in case.
        call PauseTimer(t)
        
        // Make sure the timer is valid.
        if ValidTimer(id) then
            // Get the timer's data.
            set data = Get(id)
            
            // Unmark handle id as a valid timer.
            call RemoveSavedBoolean(ht, id, 1)
            
            //If it's not run in USE_HASH mode, this next block is useless.
            static if USE_HASH then
            
                //At least clear hash memory while it's in the recycle stack.
                call RemoveSavedInteger(ht, id, 0)
                
                // If the recycle limit is reached
                if tN == QUANTITY then
                    // then we destroy the timer.
                    call DestroyTimer(t)
                    return data
                endif
            endif
            
            //Recycle the timer.
            set tT[tN] = t
            set tN = tN + 1
            
        //Tried to pass a bad timer.
        debug else
            debug call BJDebugMsg("[TimerUtils]Error: Tried to release non-active timer!")
        endif
        
        //Return Timer Data.
        return data
    endfunction

endlibrary

library TimerUtils requires TimerUtilsEx
endlibrary
Bribe is offline   Reply With Quote
Sponsored Links - Login to hide this ad!