9 years
edited 8 years
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:
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
1 library TimerIndexer //v1.2
2 3 4 //! novjass5 ________________
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 stock17 18 */function GetTimerEx takes integer i returns timer/*
19 - Retrieves a new usable timer from the stock and initializes20 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 returns24 null if that timer is not free25 26 */function FreeTimer takes timer t returns nothing/*
27 - Releases the timer back to the stock28 29 */function GetTimerId takes timer t returns integer/*
30 - Returns the index of the timer31 32 */function GetTimerData takes timer t returns integer/*
33 - Returns the custom integer data attached to the timer34 35 */function SetTimerData takes timer t, integer i returns nothing/*
36 - Attaches a custom integer data to the timer37 38 */function IsTimerStocked takes timer t returns boolean/*
39 - Checks if the timer is free40 41 */function GetTimerFlag takes timer t returns boolean/*
42 - Checks if the timer is included in this system's timer stock43 44 *///! endnovjass
45 46 globals47 /*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 a52 timer belonging to the stock is accidentally destroyed53 Note that this value should be greater than the time54 delay of the handleId recycling which is approximately55 0.0050000 ( It's not advised to change this anyway ) */56 private constant real REPLACE_DELAY = 0.0050001
57 58 endglobals59 60 //================================================================61 62 globals63 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 endglobals75 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 endfunction80 endif81 82 function GetTimerId takes timer t returns integer
83 return GetHandleId(t) - START_HANDLE
84 endfunction85 86 function GetTimerData takes timer t returns integer
87 return data[GetTimerId(t)]
88 endfunction89 90 function SetTimerData takes timer t, integer i returns nothing
91 set data[GetTimerId(t)] = i
92 endfunction93 94 function IsTimerStocked takes timer t returns boolean
95 return isTimerStocked[GetTimerId(t)]
96 endfunction97 98 function GetTimerFlag takes timer t returns boolean
99 return GetTimerId(t) > 0 and GetTimerId(t) <= TIMER_STOCK_SIZE
100 endfunction101 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 endif110 debug call Debug("ERROR: No free timers available, creating a temporary timer.")
111 return CreateTimer()
112 endfunction113 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 endif119 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 endfunction126 127 function GetTimerEx takes integer i returns timer
128 set tempTimer = GetTimer()
129 set data[GetTimerId(tempTimer)] = i
130 return tempTimer131 endfunction132 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 endif148 endfunction149 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 else157 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 endif163 call FreeTimer(GetExpiredTimer())
164 endfunction165 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 endif178 endfunction179 180 hook DestroyTimer OnDestroy
181 182 private function Delegate takes nothing returns nothing
183 local integer i = current
184 loop185 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 return193 endif194 exitwhen i == current + pitStop
195 endloop196 set current = i
197 call Delegate.evaluate()
198 endfunction199 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 else206 set pitStop = 1000
207 endif208 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 loop215 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 endloop221 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 endif228 endmethod229 endmodule230 231 private struct S extends array
232 implement M233 endstruct234 235 endlibrary
ChangelogsSpoiler
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