Warcraft III: MapsModelsSkinsIconsSpellsToolsTutorials
WC3 JASS: Code SnippetsJASS and vJASS Spells and SystemsJass Tutorials
Chat @Discord

Author Topic: TimerIndexer v1.2  (Read 3392 times)

  • Newbie - level 1
  • *
  • Posts: 13
  • WC3 Models: 0
  • WC3 Tutorials: 0
  • WC3 Tools: 0
  • WC3 Maps: 0
  • WC3 Skins: 0
  • WC3 Icons: 0
  • WC3 Spells: 0
  • Reputation: 0
  • Just a Man in the Back
    • View Profile
TimerIndexer v1.2
« on: September 03, 2016, 10:49:40 PM »
Useful system especially in making an MUI spell which uses timers. Instead of saving the spell data in a hashtable with the handleid of the timer as the parent key, you can just use normal arrays with the timerid as the index. This also allows you to pass custom data (integer) to timers.

System Features:
  • Indexed timers (Array safe, 1-8190 but can also be customized to be 8190+) NEW
  • Timer custom data (integer) attachment [NEW]
  • Timer double free protection
  • Automatic timer replacement (Useful safety feature which automatically replaces timers belonging to this system with a timer of the same timerid and handleid when destroyed)
Timer Indexer v1.2
Code: jass  [Select]
  1. library TimerIndexer //v1.2
  2.  
  3.  
  4. //! novjass
  5.      ________________
  6.     |                |
  7.     | Written by AGD |
  8.     |________________|
  9.  
  10.  
  11.     |=====|
  12.     | API |
  13.     |=====|
  14.  
  15.         function GetTimer takes nothing returns timer/*
  16.         - Allocates a new usable timer from the stock
  17.  
  18.       */function GetTimerEx takes integer i returns timer/*
  19.         - Retrieves a new usable timer from the stock and initializes
  20.           its custom integer data to <i>
  21.  
  22.       */function GetTimerById takes integer i returns timer/*
  23.         - Retrieves a timer of ID <i> from the stock but returns
  24.           null if that timer is not free
  25.  
  26.       */function FreeTimer takes timer t returns nothing/*
  27.         - Releases the timer back to the stock
  28.  
  29.       */function GetTimerId takes timer t returns integer/*
  30.         - Returns the index of the timer
  31.  
  32.       */function GetTimerData takes timer t returns integer/*
  33.         - Returns the custom integer data attached to the timer
  34.  
  35.       */function SetTimerData takes timer t, integer i returns nothing/*
  36.         - Attaches a custom integer data to the timer
  37.  
  38.       */function IsTimerStocked takes timer t returns boolean/*
  39.         - Checks if the timer is free
  40.  
  41.       */function GetTimerFlag takes timer t returns boolean/*
  42.         - Checks if the timer is included in this system's timer stock
  43.  
  44. *///! endnovjass
  45.  
  46.     globals
  47. /*
  48.         Determines the total number of timers on the stock          */
  49.         private constant integer TIMER_STOCK_SIZE = 8190
  50.  
  51. /*      Determines the delay of timer replacement in case a
  52.         timer belonging to the stock is accidentally destroyed
  53.         Note that this value should be greater than the time
  54.         delay of the handleId recycling which is approximately
  55.         0.0050000 ( It's not advised to change this anyway )        */
  56.         private constant real REPLACE_DELAY = 0.0050001
  57.  
  58.     endglobals
  59.  
  60.     //================================================================
  61.  
  62.     globals
  63.         private timer array T[TIMER_STOCK_SIZE]
  64.         private timer tempTimer
  65.         private integer START_HANDLE
  66.         private integer destroyed
  67.         private integer current
  68.         private integer pitStop
  69.         private integer this
  70.         private integer array recycler[TIMER_STOCK_SIZE]
  71.         private integer array data[TIMER_STOCK_SIZE]
  72.         private boolean dont = false
  73.         private boolean array isTimerStocked[TIMER_STOCK_SIZE]
  74.     endglobals
  75.  
  76.     static if DEBUG_MODE then
  77.         private function Debug takes string msg returns nothing
  78.             call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[Timer Indexer]|R : " + msg)
  79.         endfunction
  80.     endif
  81.  
  82.     function GetTimerId takes timer t returns integer
  83.         return GetHandleId(t) - START_HANDLE
  84.     endfunction
  85.  
  86.     function GetTimerData takes timer t returns integer
  87.         return data[GetTimerId(t)]
  88.     endfunction
  89.  
  90.     function SetTimerData takes timer t, integer i returns nothing
  91.         set data[GetTimerId(t)] = i
  92.     endfunction
  93.  
  94.     function IsTimerStocked takes timer t returns boolean
  95.         return isTimerStocked[GetTimerId(t)]
  96.     endfunction
  97.  
  98.     function GetTimerFlag takes timer t returns boolean
  99.         return GetTimerId(t) > 0 and GetTimerId(t) <= TIMER_STOCK_SIZE
  100.     endfunction
  101.  
  102.     function GetTimer takes nothing returns timer
  103.         set this = recycler[0]
  104.         set recycler[0] = recycler[this]
  105.         if isTimerStocked[this] then
  106.             set isTimerStocked[this] = false
  107.             debug call Debug("Retrieving Timer [" + I2S(this) + "] from stock")
  108.             return T[this]
  109.         endif
  110.         debug call Debug("ERROR: No free timers available, creating a temporary timer.")
  111.         return CreateTimer()
  112.     endfunction
  113.  
  114.     function GetTimerById takes integer i returns timer
  115.         if isTimerStocked[i] then
  116.             debug call Debug("Retrieving Timer [" + I2S(i) + "] from stock")
  117.             return T[i]
  118.         endif
  119.         debug if i < 1 or i > TIMER_STOCK_SIZE then
  120.             debug call Debug("ERROR: Specified timer ID is out of bounds")
  121.         debug else
  122.             debug call Debug("ERROR: Timer [" + I2S(i) + "] is not free")
  123.         debug endif
  124.         return null
  125.     endfunction
  126.  
  127.     function GetTimerEx takes integer i returns timer
  128.         set tempTimer = GetTimer()
  129.         set data[GetTimerId(tempTimer)] = i
  130.         return tempTimer
  131.     endfunction
  132.  
  133.     function FreeTimer takes timer t returns nothing
  134.         local integer i = GetTimerId(t)
  135.         if not isTimerStocked[i] and GetTimerFlag(t) then
  136.             call TimerStart(t, 0, false, null)
  137.             set isTimerStocked[i] = true
  138.             set data[i] = 0
  139.             set recycler[i] = recycler[0]
  140.             set recycler[0] = i
  141.             debug call Debug("Releasing Timer [" + I2S(i) + "] back to the stock")
  142.         elseif not GetTimerFlag(t) then
  143.             call DestroyTimer(t)
  144.             debug call Debug("ERROR: Freed timer does not belong to the stack, destroying timer")
  145.         debug else
  146.             debug call Debug("ERROR: Attempt to double-free Timer [" + I2S(i) + "]")
  147.         endif
  148.     endfunction
  149.  
  150.     private function Replace takes nothing returns nothing
  151.         local integer i = destroyed
  152.         set T[i] = CreateTimer()
  153.         if GetTimerId(T[i]) == i then
  154.             set isTimerStocked[i] = true
  155.             debug call Debug("Timer [" + I2S(GetTimerId(T[i])) + "] was replaced")
  156.         else
  157.             debug call Debug("ERROR: Unable to replace Timer [" + I2S(i) + "]")
  158.             set dont = true
  159.             call DestroyTimer(T[i])
  160.             set dont = false
  161.             set T[i] = null
  162.         endif
  163.         call FreeTimer(GetExpiredTimer())
  164.     endfunction
  165.  
  166.     private function OnDestroy takes timer t returns nothing
  167.         local integer i = GetTimerId(t)
  168.         local trigger trig
  169.         if not dont and GetTimerFlag(t) then
  170.             set T[i] = null
  171.             set isTimerStocked[i] = false
  172.             set destroyed = i
  173.             call DestroyTimer(null)
  174.             call TimerStart(GetTimer(), REPLACE_DELAY, false, function Replace)
  175.             debug call Debug("WARNING: Timer [" + I2S(i) + "] got destroyed!")
  176.             set trig = null
  177.         endif
  178.     endfunction
  179.  
  180.     hook DestroyTimer OnDestroy
  181.  
  182.     private function Delegate takes nothing returns nothing
  183.         local integer i = current
  184.         loop
  185.             set i = i + 1
  186.             set T[i] = CreateTimer()
  187.             set isTimerStocked[i] = true
  188.             set recycler[i] = i + 1
  189.             if i == TIMER_STOCK_SIZE then
  190.                 debug call Debug("Total number of timers created: " + I2S(i))
  191.                 debug call Debug("Timer stock count is complete")
  192.                 return
  193.             endif
  194.             exitwhen i == current + pitStop
  195.         endloop
  196.         set current = i
  197.         call Delegate.evaluate()
  198.     endfunction
  199.  
  200.     private module M
  201.         private static method onInit takes nothing returns nothing
  202.             local integer i = 1
  203.             if TIMER_STOCK_SIZE <= 8190 then
  204.                 set pitStop = TIMER_STOCK_SIZE
  205.             else
  206.                 set pitStop = 1000
  207.             endif
  208.             set recycler[TIMER_STOCK_SIZE] = 0
  209.             set recycler[0] = 1
  210.             set recycler[1] = 2
  211.             set T[i] = CreateTimer()
  212.             set START_HANDLE = GetHandleId(T[i]) - 1
  213.             set isTimerStocked[i] = true
  214.             loop
  215.                 set i = i + 1
  216.                 set T[i] = CreateTimer()
  217.                 set isTimerStocked[i] = true
  218.                 set recycler[i] = i + 1
  219.                 exitwhen i == pitStop
  220.             endloop
  221.             set current = i
  222.             if TIMER_STOCK_SIZE > current then
  223.                 call Delegate.evaluate()
  224.             debug else
  225.                 debug call Debug("Total number of timers created: " + I2S(i))
  226.                 debug call Debug("Timer stock count is complete")
  227.             endif
  228.         endmethod
  229.     endmodule
  230.  
  231.     private struct S extends array
  232.         implement M
  233.     endstruct
  234.  
  235. endlibrary


Changelogs
v1.2
- Added more functionalities such as attaching custom timer data, now the system comprises all but is not limited to the main functionalities of Vexorian's TimerUtils
- Optimized the code especially in the part in updating the timer stack
- Fixed some bugs

v1.1
- Added the possibility for users to configure the timer stock size above 8190
- Some fixes

v1.0
- First Release
« Last Edit: September 26, 2016, 02:47:10 AM by AGD »

 

Blizzard Modding Information Center Starcraft II Modding Information Center Wacraft III Modding Information Center WC3JASS.com - The JASS Vault Chronicles of Darkness - A Warcraft III mod Jetcraft - A Starcraft II mod Troll Smash - A Warcraft III Arena
  Mod DB - Change the Game Power of Corruption - A Warcraft III altered melee map Chaos Realm - The world of Game modders and wc3 addicts Follow us on Facebook!!