• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

[Lua] [Deprecated] Timer32

Bribe

Code Moderator
Level 50
Joined
Sep 26, 2009
Messages
9,468
Bringing "Timer32" to Lua. The function naming convention is impossible to replicate 1-to-1, but I hope I have made it fairly intuitive nevertheless.

Credit goes to Jesus4Lyf and Nestharus for the development leading up to this resource.

If you want to know what Timer32 is, read up on it here: System - Timer32

Lua:
do
--[[
   Timer32 for Lua, version 1.0.0.0, published by Bribe on HiveWorkshop.com
  
Credits:
   Original Timer32 written by Jesus4Lyf on TheHelper.net
   Several improvements to Timer32 by Nestharus via his CTL32.
   AGD and Eikonium for motivating me to "convert" yet another vJass resource to Lua.
  
API:
  
   T32_start(callbackFunction, optionalDuration) -> integer
   - Starts running callbackFunction every 0.03125 seconds
   - Returns an integer to represent the registration of this node
   - Returns 0 if the user did not pass any parameter.
   - If the callbackFunction returns 'true', the periodic event will stop.
   - The callbackFunction can either have no parameters, or can have a single parameter to accept the current node.
   - If the optionalDuration is given, the periodic event will cease after that duration.
   !! Warning: Do not call T32_start unless on or after GlobalInitialization phase.
  
   T32_stop(returnedIntegerFromT32_start) -> boolean
   - Pass the integer node returned from T32_start.
   - Returns whether the removal was successful (true) or not (false)
   - You can stop the period event in one of three ways:
  
   T32_reset(returnedIntegerFromT32_start, duration) -> boolean
   - Pass the integer node returned from T32_start.
   - Pass a new or updated duration for the periodic event to stop running.
   - Returns whether the duration reset was successful (true) or not (false)
   ! Note: Unlike with T32_start, the duration here is actually required.
--]]
  
   local _PERIOD = 0.03125 -- configure this if wished
  
   local nextInList = {} nextInList[0] = 0 --head of list is 0
   local prevInList = {} prevInList[0] = 0 --tail of list is also 0
  
   local recycle = {}      -- recycle stack
   local timeLeft = {}     -- track duration
   local t = CreateTimer() -- one timer to control everything
  
   function T32_stop(this) -- returns whether the removal was successful.
      if not prevInList[this] then
         return false
      end
      -- Remove node from list
      nextInList[prevInList[this]] = nextInList[this]
      prevInList[nextInList[this]] = prevInList[this]
     
      prevInList[this] = nil --prevent double-frees
      timeLeft[this] = nil --reset in case the user specified a duration
     
      recycle[#recycle + 1] = this -- recycle this
      if nextInList[0] == 0 then
         PauseTimer(t)
      end
      return true
   end
  
   local funcs = {}        -- function stack
   local listNode = 0
   function T32_start(func, duration) -- Returns integer for node value in list.
      if not func then
         return 0
      end
     
      if type(func) == "number" then -- user wants to put the duration first. Why not allow both?
         if not duration then
            return 0
         end
         func, duration = duration, func -- swap
      end
     
      local this = recycle[#recycle]    -- Try to get a recycled node
      if this then
         recycle[#recycle] = nil        -- When recycle was successful
      else
         this = listNode + 1        -- Else create a new node
         listNode = this
      end
     
      funcs[this] = func            -- Tag function to node
     
      if duration then
         timeLeft[this] = duration  -- Track time left by set duration
      end
     
      --Add node to linked list
      prevInList[nextInList[0]] = this
      nextInList[this] = nextInList[0]
      nextInList[0] = this
      prevInList[this] = 0
     
      if this == 1 then
         TimerStart(t, _PERIOD, true, function()
            local dur
            local node = nextInList[0]
           
            while (node ~= 0) do
               if funcs[node](node) then
                  T32_stop(node)
               else
                  dur = timeLeft[node]
                  if dur then
                     dur = dur - _PERIOD
                     if dur <= 0.00 then
                        T32_stop(node)
                     else
                        timeLeft[node] = dur
                     end
                  end
               end
               node = nextInList[node]
            end
         end)
      end
      return this
   end
  
   function T32_reset(this, duration)
      if not prevInList[this] or not duration then
         return false
      end
      timeLeft[this] = duration
      return true
   end
  
end
 
Last edited:
Top