9 years
edited 8 years
LoopCode v1.3
This system allows you to register a code that will run every specified timeout. Note that this system only uses one timer for all registered codes. Therefore, codes with periods indivisible by 0.03125 doesn't run with a constant time interval. Although the difference will not exceed 0.03125, you probably don't want it to be that way. But this will not be much of a problem for codes with low frequency period such as those with timeouts greater than 2 seconds since the difference wouldn't be so noticeable.
In short, this works best for codes with timeout divisible by 0.03125 seconds.
Main Script
Sample Script
Changelogs
v1.3
- Fixed a minor error concerning the index of a registered code in the RunLoop not being decremented by 1 when a code is removed from the loop.
v1.2
- Replaced TriggerEvaluate() with .evaluate() through the use of function interface
- Added an option to the configuration whether or not the system will automatically adjust the code timeout in case the entered timeout is lesser than the minimum supported timeout
- Removed the requirement Table. Instead, uses arrays which were made possible through using interface functions as the index.
v1.1
- Fixed the bug regarding the incorrect unregistering and re-registering codes to the loop
- Uses a TableArray instead of two separate tables
v1.0
- Initial release
Feedback will be appreciated.
This system allows you to register a code that will run every specified timeout. Note that this system only uses one timer for all registered codes. Therefore, codes with periods indivisible by 0.03125 doesn't run with a constant time interval. Although the difference will not exceed 0.03125, you probably don't want it to be that way. But this will not be much of a problem for codes with low frequency period such as those with timeouts greater than 2 seconds since the difference wouldn't be so noticeable.
In short, this works best for codes with timeout divisible by 0.03125 seconds.
Main Script
1 library LoopCode2 3 4 //! novjass5 ________________
6 | |
7 | Written by AGD |
8 |________________|
9 10 |=====|
11 | API |
12 |=====|
13 14 function interface LoopCode takes nothing returns nothing/*
15 - Interface of functions to be registered in the loop16
17 */function RegisterLoopCode takes LoopCode c, real timeout returns boolean/*
18 - Registers a code to run every <timeout> seconds and returns a boolean value depending19 on the success of the operation20
21 */function RemoveLoopCode takes LoopCode c returns boolean/*
22 - Unregisters a code from the loop and returns a boolean value depending23 on the success of the operation24
25 */function SetCodeTimeout takes LoopCode c, real timeout returns boolean/*
26 - Sets a new loop timeout for a code27
28 *///! endnovjass
29 30 //======================================================================================31 32 globals33 private constant real TIMEOUT = 0.03125
34 private constant boolean AUTO_ADJUST = true
35 endglobals36 37 //======================================================================================38 39 globals40 private LoopCode array codes
41 private timer Timer = CreateTimer()
42 private integer id = 0
43 private integer count = 0
44 private real array codeTimeout
45 private real array elapsed
46 private integer array index
47 private boolean array check
48 endglobals49 50 //======================================================================================51 52 function interface LoopCode takes nothing returns nothing
53 54 static if DEBUG_MODE then
55 private function Debug takes string msg returns nothing
56 call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 60, "|CFFFFCC00[LoopEvent] :|R" + msg)
57 endfunction58 endif59 60 private function RunLoop takes nothing returns nothing
61 set id = 0
62 loop63 set id = id + 1
64 set elapsed[id] = elapsed[id] + TIMEOUT
65 if elapsed[id] >= codeTimeout[id] then
66 call codes[id].evaluate()
67 set elapsed[id] = elapsed[id] - codeTimeout[id]
68 endif69 exitwhen id == count
70 endloop71 endfunction72 73 function RegisterLoopCode takes LoopCode c, real timeout returns boolean
74 static if AUTO_ADJUST then
75 if timeout < TIMEOUT then
76 set timeout = TIMEOUT
77 debug call Debug("Entered code execution timeout is less than the minimum value (" + R2S(TIMEOUT) + "), auto-adjusting timeout to (" + R2S(TIMEOUT) + ")")
78 endif79 else80 if timeout < TIMEOUT then
81 debug call Debug("ERROR: Entered code execution timeout is less than the minimum value (" + R2S(TIMEOUT) + ")")
82 return false
83 endif84 endif85 if not check[c] then
86 debug if timeout - (timeout/TIMEOUT)*TIMEOUT > 0.00 then
87 debug call Debug("WARNING: Entered code timeout is not divisible by " + R2S(TIMEOUT) + ", this code's execution interval will not be even")
88 debug endif
89 set count = count + 1
90 set elapsed[count] = 0.00
91 set codeTimeout[count] = timeout
92 set codes[count] = c
93 set index[c] = count
94 set check[c] = true
95 if count == 1 then
96 call TimerStart(Timer, TIMEOUT, true, function RunLoop)
97 debug call Debug("There is one code instance registered, starting to run timer")
98 endif99 return true
100 endif101 debug call Debug("ERROR: Attempt to double register a code")
102 return false
103 endfunction104 105 function RemoveLoopCode takes LoopCode c returns boolean
106 local integer i = index[c]
107 if check[c] then
108 debug call Debug("Removing a code from the loop")
109 set check[c] = false
110 set index[codes[count]] = i
111 set codes[i] = codes[count]
112 set codeTimeout[i] = codeTimeout[count]
113 if id >= i then
114 set id = id - 1
115 endif116 set count = count - 1
117 if count == 0 then
118 call TimerStart(Timer, 0, false, null)
119 debug call Debug("There are no code instances running, stopping timer")
120 endif121 return true
122 endif123 debug call Debug("ERROR: Attempt to remove a null or an already removed code")
124 return false
125 endfunction126 127 function SetCodeTimeout takes LoopCode c, real timeout returns boolean
128 local integer i = index[c]
129 if check[c] then
130 static if AUTO_ADJUST then
131 if codeTimeout[i] >= TIMEOUT then
132 set codeTimeout[i] = timeout
133 else134 set codeTimeout[i] = TIMEOUT
135 debug call Debug("Entered code execution timeout is less than the minimum value (" + R2S(TIMEOUT) + "), auto-adjusting timeout to (" + R2S(TIMEOUT) + ")")
136 endif137 return true
138 else139 if codeTimeout[i] >= TIMEOUT then
140 set codeTimeout[i] = timeout
141 return true
142 endif143 debug call Debug("ERROR: Entered code execution timeout is less than the minimum value (" + R2S(TIMEOUT) + ")")
144 return false
145 endif146 endif147 debug call Debug("ERROR: Specified code is not registered")
148 return false
149 endfunction150 151 152 endlibrary
Sample Script
Spoiler
1 2 scope MySpell initializer Init
3 4 globals5 private constant real TIMEOUT = 0.03125
6 private integer maxIndex = 0
7 private real array elapsed
8 endglobals9 10 private function Loop takes nothing returns nothing
11 local integer index = 0
12 loop13 set index = index + 1
14 if elapsed < 10 then
15 set elapsed[index] = elapsed[index] + TIMEOUT
16 else17 set elapsed[index] = elapsed[maxIndex]
18 set maxIndex = maxIndex - 1
19 set index = index - 1
20 if maxIndex == 0 then
21 call RemoveLoopCode(LoopCode.Loop)
22 endif23 endif24 exitwhen index == maxIndex
25 endloop26 endfunction27 28 private function OnCast takes nothing returns boolean
29 // Setup spell data and oncast effects30 set maxIndex = maxIndex + 1
31 set elapsed[maxIndex] = 0.00
32 call RegisterLoopCode(LoopCode.Loop, TIMEOUT)
33 return false
34 endfunction35 36 private function Init takes nothing returns nothing
37 local trigger t = CreateTrigger()
38 call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
39 call TriggerAddCondition(t, FIlter(function OnCast))
40 endfunction41 42 endscope
Changelogs
Spoiler
v1.3
- Fixed a minor error concerning the index of a registered code in the RunLoop not being decremented by 1 when a code is removed from the loop.
v1.2
- Replaced TriggerEvaluate() with .evaluate() through the use of function interface
- Added an option to the configuration whether or not the system will automatically adjust the code timeout in case the entered timeout is lesser than the minimum supported timeout
- Removed the requirement Table. Instead, uses arrays which were made possible through using interface functions as the index.
v1.1
- Fixed the bug regarding the incorrect unregistering and re-registering codes to the loop
- Uses a TableArray instead of two separate tables
v1.0
- Initial release
Feedback will be appreciated.