vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | |
2 | --[[ |
||
3 | Name: Metrognome-2.0 |
||
4 | Revision: $Rev: 5623 $ |
||
5 | Author: Tekkub Stoutwrithe (tekkub@gmail.com) |
||
6 | Website: http://wiki.wowace.com/index.php/Metrognome_Embedded_Library |
||
7 | Documentation: http://wiki.wowace.com/index.php/Metrognome_Embedded_Library_Methods |
||
8 | SVN: svn://svn.wowace.com/root/trunk/Metrognome/Metrognome-2.0 |
||
9 | Description: OnUpdate timer managing library |
||
10 | Dependencies: AceLibrary, AceOO-2.0, Compost-2.0 (optional) |
||
11 | ]] |
||
12 | |||
13 | local vmajor, vminor = "Metrognome-2.0", "$Revision: 5623 $" |
||
14 | |||
15 | if not AceLibrary then error(vmajor .. " requires AceLibrary.") end |
||
16 | if not AceLibrary:IsNewVersion(vmajor, vminor) then return end |
||
17 | |||
18 | if not AceLibrary:HasInstance("AceOO-2.0") then error(vmajor .. " requires AceOO-2.0") end |
||
19 | |||
20 | |||
21 | local compost = AceLibrary:HasInstance("Compost-2.0") and AceLibrary("Compost-2.0") |
||
22 | |||
23 | local AceOO = AceLibrary:GetInstance("AceOO-2.0") |
||
24 | local Mixin = AceOO.Mixin |
||
25 | local Metrognome = Mixin { |
||
26 | "RegisterMetro", |
||
27 | "UnregisterMetro", |
||
28 | "StartMetro", |
||
29 | "StopMetro", |
||
30 | "ChangeMetroRate", |
||
31 | "ClearMetroStats", |
||
32 | "MetroStatus", |
||
33 | "MetroProfile", |
||
34 | } |
||
35 | |||
36 | local function getnewtable() return compost and compost:Acquire() or {} end |
||
37 | local function reclaimtable(t) if compost then compost:Reclaim(t) end end |
||
38 | |||
39 | |||
40 | -- Sets up a new OnUpdate handler |
||
41 | -- name - A unique name, if you only need one handler then your addon's name will suffice here |
||
42 | -- func - Function to be called |
||
43 | -- rate (optional but highly reccomended) - The rate (in seconds) at which your function should be called |
||
44 | -- a1-4 (optional) - A args to be passed to func, this is a great place to pass self |
||
45 | -- if a2 is defined then the elapsed time will not be passed to your function! |
||
46 | -- Returns true if you've been registered |
||
47 | function Metrognome:Register(name, func, rate, a1, a2, a3, a4, a5, a6) |
||
48 | Metrognome:argCheck(name, 2, "string") |
||
49 | Metrognome:argCheck(func, 3, "function") |
||
50 | Metrognome:assert(not Metrognome.var.handlers[name], "A timer with the name "..name.." is already registered") |
||
51 | |||
52 | local t = getnewtable() |
||
53 | t.name, t.func, t.rate = name, func, rate or 0 |
||
54 | t.a1, t.a2, t.a3, t.a4, t.a5, t.a6 = a1, a2, a3, a4, a5, a6 |
||
55 | Metrognome.var.handlers[name] = t |
||
56 | return true |
||
57 | end |
||
58 | |||
59 | |||
60 | -- Removes an OnUpdate handler |
||
61 | -- name - the hander you want to remove |
||
62 | -- Returns true if successful |
||
63 | function Metrognome:Unregister(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) |
||
64 | Metrognome:argCheck(a1, 2, "string") |
||
65 | |||
66 | if not Metrognome.var.handlers[a1] then return end |
||
67 | reclaimtable(Metrognome.var.handlers[a1]) |
||
68 | Metrognome.var.handlers[a1] = nil |
||
69 | if a2 then Metrognome:Unregister(a2,a3,a4,a5,a6,a7,a8,a9,a10) |
||
70 | elseif not Metrognome:HasHandlers() then Metrognome.var.frame:Hide() end |
||
71 | return true |
||
72 | end |
||
73 | |||
74 | |||
75 | -- Begins triggering updates |
||
76 | -- name - the hander you want to start |
||
77 | -- numexec (optional) - Limit the number of times the timer runs |
||
78 | -- Returns true if successful |
||
79 | function Metrognome:Start(name, numexec) |
||
80 | Metrognome:argCheck(name, 2, "string") |
||
81 | |||
82 | if not Metrognome.var.handlers[name] then return end |
||
83 | Metrognome.var.handlers[name].limit = numexec |
||
84 | Metrognome.var.handlers[name].elapsed = 0 |
||
85 | Metrognome.var.handlers[name].running = true |
||
86 | Metrognome.var.frame:Show() |
||
87 | return true |
||
88 | end |
||
89 | |||
90 | |||
91 | -- Stops triggering updates |
||
92 | -- name - the hander you want to stop |
||
93 | -- Returns true if successful |
||
94 | function Metrognome:Stop(name) |
||
95 | Metrognome:argCheck(name, 2, "string") |
||
96 | |||
97 | if not Metrognome.var.handlers[name] then return end |
||
98 | Metrognome.var.handlers[name].running = nil |
||
99 | Metrognome.var.handlers[name].limit = nil |
||
100 | if not Metrognome:HasHandlers() then Metrognome.var.frame:Hide() end |
||
101 | return true |
||
102 | end |
||
103 | |||
104 | |||
105 | -- Changes the execution rate of a timer. |
||
106 | -- This will also reset the timer's elapsed time to 0 |
||
107 | -- name - The timer you wish to change |
||
108 | -- newrate (optional)- The new exec rate, in seconds. If nil or 0 default OnUpdate timing will be used |
||
109 | -- n#,r# (optional) - Recusivly calls ChangeRate to allow you to set up to 5 rates in one call. |
||
110 | -- Returns true if successful |
||
111 | function Metrognome:ChangeRate(name, newrate, n2,r2,n3,r3,n4,r4,n5,r5) |
||
112 | Metrognome:argCheck(name, 2, "string") |
||
113 | |||
114 | if not Metrognome.var.handlers[name] then |
||
115 | if n2 then return nil, Metrognome:ChangeRate(n2,r2,n3,r3,n4,r4,n5,r5) |
||
116 | else return end |
||
117 | end |
||
118 | |||
119 | local t = Metrognome.var.handlers[name] |
||
120 | t.elapsed = 0 |
||
121 | t.rate = newrate or 0 |
||
122 | if n2 then return true, Metrognome:ChangeRate(n2,r2,n3,r3,n4,r4,n5,r5) |
||
123 | else return true end |
||
124 | end |
||
125 | |||
126 | |||
127 | -- Resets the profile stats for a timer |
||
128 | -- Accepts up to 10 timer names to clear |
||
129 | function Metrognome:ClearStats(name, n2, n3, n4, n5, n6, n7, n8, n9, n10) |
||
130 | Metrognome:argCheck(name, 2, "string") |
||
131 | |||
132 | if not Metrognome.var.handlers[name] then |
||
133 | if n2 then return nil, Metrognome:ClearStats(n2,r2,n3,r3,n4,r4,n5,r5) |
||
134 | else return end |
||
135 | end |
||
136 | |||
137 | local t = Metrognome.var.handlers[name] |
||
138 | t.count, t.mem, t.time = 0, 0, 0 |
||
139 | if n2 then return true, Metrognome:ClearStats(n2,r2,n3,r3,n4,r4,n5,r5) |
||
140 | else return true end |
||
141 | end |
||
142 | |||
143 | |||
144 | -- Query a timer's status |
||
145 | -- Args: name - the schedule you wish to look up |
||
146 | -- Returns: registered - true if a schedule exists with this name |
||
147 | -- rate - the registered rate, if defined |
||
148 | -- running - true if this schedule is currently running |
||
149 | -- limit - limit of times to repeat this timer |
||
150 | -- elapsed - time elapsed this cycle of the timer |
||
151 | function Metrognome:Status(name) |
||
152 | Metrognome:argCheck(name, 2, "string") |
||
153 | |||
154 | if not Metrognome.var.handlers[name] then return end |
||
155 | return true, Metrognome.var.handlers[name].rate, Metrognome.var.handlers[name].running, Metrognome.var.handlers[name].limit, Metrognome.var.handlers[name].elapsed |
||
156 | end |
||
157 | |||
158 | |||
159 | -- Query a timer's profile info |
||
160 | -- Args: name - the schedule you wish to look up |
||
161 | -- Returns: mem - the total memory consumed by the timer's execution (in KiB) |
||
162 | -- time - the total time consumed by the timer's execution (in sec) |
||
163 | -- count - the number of times the timer has been triggered |
||
164 | -- rate - the rate at which the timer triggers (0 means the default OnUpdate rate) |
||
165 | function Metrognome:Profile(name) |
||
166 | Metrognome:argCheck(name, 2, "string") |
||
167 | |||
168 | if not Metrognome.var.handlers[name] then return end |
||
169 | local t = Metrognome.var.handlers[name] |
||
170 | return t.mem, t.time, t.count, t.rate |
||
171 | end |
||
172 | |||
173 | |||
174 | function Metrognome:OnUpdate() |
||
175 | for i,v in pairs(this.owner.var.handlers) do |
||
176 | if v.running then |
||
177 | v.elapsed = v.elapsed + arg1 |
||
178 | if v.elapsed >= v.rate then |
||
179 | local mem, time = gcinfo(), GetTime() |
||
180 | v.func(v.a1 or v.arg, v.a2 or v.elapsed, v.a3, v.a4, v.a5, v.a6) |
||
181 | mem, time = gcinfo() - mem, GetTime() - time |
||
182 | if mem >= 0 then v.mem, v.time, v.count = (v.mem or 0) + mem, (v.time or 0) + time, (v.count or 0) + 1 end |
||
183 | v.elapsed = 0 |
||
184 | if v.limit then v.limit = v.limit - 1 end |
||
185 | if v.limit and v.limit <= 0 then this.owner:Stop(i) end |
||
186 | end |
||
187 | end |
||
188 | end |
||
189 | end |
||
190 | |||
191 | |||
192 | function Metrognome:HasHandlers() |
||
193 | if next(Metrognome.var.handlers) then return true end |
||
194 | end |
||
195 | |||
196 | |||
197 | ------------------------------ |
||
198 | -- Mixins Methods -- |
||
199 | ------------------------------ |
||
200 | |||
201 | Metrognome.StartMetro = Metrognome.Start |
||
202 | Metrognome.StopMetro = Metrognome.Stop |
||
203 | Metrognome.ChangeMetroRate = Metrognome.ChangeRate |
||
204 | Metrognome.ClearMetroStats = Metrognome.ClearStats |
||
205 | Metrognome.MetroStatus = Metrognome.Status |
||
206 | Metrognome.MetroProfile = Metrognome.Profile |
||
207 | |||
208 | |||
209 | function Metrognome:RegisterMetro(name, func, rate, a1, a2, a3, a4, a5, a6) |
||
210 | if not Metrognome.var.addons[self] then Metrognome.var.addons[self] = getnewtable() end |
||
211 | Metrognome.var.addons[self][name] = Metrognome:Register(name, func, rate, a1, a2, a3, a4, a5, a6) |
||
212 | end |
||
213 | |||
214 | |||
215 | function Metrognome:UnregisterMetro(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) |
||
216 | Metrognome:argCheck(a1, 2, "string") |
||
217 | |||
218 | if Metrognome.var.addons[self] then Metrognome.var.addons[self][a1] = nil end |
||
219 | Metrognome:Unregister(a1) |
||
220 | if a2 then self:UnregisterMetro(a2,a3,a4,a5,a6,a7,a8,a9,a10) end |
||
221 | end |
||
222 | |||
223 | |||
224 | function Metrognome:OnEmbedDisable(target) |
||
225 | if self.var.addons[target] then |
||
226 | for i in pairs(Metrognome.var.addons[target]) do |
||
227 | self:Stop(i) |
||
228 | end |
||
229 | end |
||
230 | end |
||
231 | |||
232 | |||
233 | -------------------------------- |
||
234 | -- Load this bitch! -- |
||
235 | -------------------------------- |
||
236 | |||
237 | function Metrognome:activate(oldLib, oldDeactivate) |
||
238 | Metrognome = self |
||
239 | |||
240 | if oldLib then self.var = oldLib.var |
||
241 | else |
||
242 | self.var = { -- "Local" variables go here |
||
243 | frame = CreateFrame("Frame"), |
||
244 | handlers = {}, |
||
245 | addons = {}, |
||
246 | } |
||
247 | self.var.frame:Hide() |
||
248 | self.var.frame.name = "Metrognome-2.0 Frame" |
||
249 | end |
||
250 | if not self.var.addons then self.var.addons = {} end |
||
251 | self.var.frame:SetScript("OnUpdate", self.OnUpdate) |
||
252 | self.var.frame.owner = self |
||
253 | |||
254 | self.super.activate(self, oldLib, oldDeactivate) |
||
255 | if oldDeactivate then oldDeactivate(oldLib) end |
||
256 | end |
||
257 | |||
258 | |||
259 | local function external(self, major, instance) |
||
260 | if major == "Compost-2.0" then compost = instance end |
||
261 | end |
||
262 | |||
263 | |||
264 | AceLibrary:Register(Metrognome, vmajor, vminor, Metrognome.activate, nil, external) |
||
265 |