vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1  
2 local vmajor, vminor = "1", tonumber(string.sub("$Revision: 2706 $", 12, -3))
3 local stubvarname = "TekLibStub"
4 local libvarname = "Metrognome"
5  
6  
7 -- Check to see if an update is needed
8 -- if not then just return out now before we do anything
9 local libobj = getglobal(libvarname)
10 if libobj and not libobj:NeedsUpgraded(vmajor, vminor) then return end
11  
12  
13 ---------------------------------------------------------------------------
14 -- Embedded Library Registration Stub
15 -- Written by Iriel <iriel@vigilance-committee.org>
16 -- Version 0.1 - 2006-03-05
17 -- Modified by Tekkub <tekkub@gmail.com>
18 ---------------------------------------------------------------------------
19  
20 local stubobj = getglobal(stubvarname)
21 if not stubobj then
22 stubobj = {}
23 setglobal(stubvarname, stubobj)
24  
25  
26 -- Instance replacement method, replace contents of old with that of new
27 function stubobj:ReplaceInstance(old, new)
28 for k,v in pairs(old) do old[k]=nil end
29 for k,v in pairs(new) do old[k]=v end
30 end
31  
32  
33 -- Get a new copy of the stub
34 function stubobj:NewStub(name)
35 local newStub = {}
36 self:ReplaceInstance(newStub, self)
37 newStub.libName = name
38 newStub.lastVersion = ''
39 newStub.versions = {}
40 return newStub
41 end
42  
43  
44 -- Get instance version
45 function stubobj:NeedsUpgraded(vmajor, vminor)
46 local versionData = self.versions[vmajor]
47 if not versionData or versionData.minor < vminor then return true end
48 end
49  
50  
51 -- Get instance version
52 function stubobj:GetInstance(version)
53 if not version then version = self.lastVersion end
54 local versionData = self.versions[version]
55 if not versionData then print(string.format("<%s> Cannot find library version: %s", self.libName, version or "")) return end
56 return versionData.instance
57 end
58  
59  
60 -- Register new instance
61 function stubobj:Register(newInstance)
62 local version,minor = newInstance:GetLibraryVersion()
63 self.lastVersion = version
64 local versionData = self.versions[version]
65 if not versionData then
66 -- This one is new!
67 versionData = {
68 instance = newInstance,
69 minor = minor,
70 old = {},
71 }
72 self.versions[version] = versionData
73 newInstance:LibActivate(self)
74 return newInstance
75 end
76 -- This is an update
77 local oldInstance = versionData.instance
78 local oldList = versionData.old
79 versionData.instance = newInstance
80 versionData.minor = minor
81 local skipCopy = newInstance:LibActivate(self, oldInstance, oldList)
82 table.insert(oldList, oldInstance)
83 if not skipCopy then
84 for i, old in ipairs(oldList) do self:ReplaceInstance(old, newInstance) end
85 end
86 return newInstance
87 end
88 end
89  
90  
91 if not libobj then
92 libobj = stubobj:NewStub(libvarname)
93 setglobal(libvarname, libobj)
94 end
95  
96 local lib = {}
97  
98  
99 -- Return the library's current version
100 function lib:GetLibraryVersion()
101 return vmajor, vminor
102 end
103  
104 local compost
105 -- Activate a new instance of this library
106 function lib:LibActivate(stub, oldLib, oldList)
107 local maj, min = self:GetLibraryVersion()
108  
109 if oldLib then
110 local omaj, omin = oldLib:GetLibraryVersion()
111 self.var = oldLib.var
112 else
113 self.var = { -- "Local" variables go here
114 frame = CreateFrame("Frame"),
115 handlers = {},
116 }
117 self.var.frame:Hide()
118 self.var.frame.name = "Metrognome Frame"
119 end
120 self.var.frame:SetScript("OnUpdate", self.OnUpdate)
121 self.var.frame.owner = self
122 compost = CompostLib and CompostLib:GetInstance("compost-1")
123 -- nil return makes stub do object copy
124 end
125  
126  
127 -- Sets up a new OnUpdate handler
128 -- name - A unique name, if you only need one handler then your addon's name will suffice here
129 -- func - Function to be called
130 -- rate (optional but highly reccomended) - The rate (in seconds) at which your function should be called
131 -- a1-4 (optional) - A args to be passed to func, this is a great place to pass self
132 -- if a2 is defined then the elapsed time will not be passed to your function!
133 -- Returns true if you've been registered
134 function lib:Register(name, func, rate, a1, a2, a3, a4, a5, a6)
135 assert(name, "Register: No timer name was passed")
136 assert(func, "Register: No timer function was passed")
137 if not name or not func or self.var.handlers[name] then return end
138 local t = compost and compost:Acquire() or {}
139 t.name, t.func, t.rate = name, func, rate or 0
140 t.a1, t.a2, t.a3, t.a4, t.a5, t.a6 = a1, a2, a3, a4, a5, a6
141 self.var.handlers[name] = t
142 return true
143 end
144  
145  
146 -- Removes an OnUpdate handler
147 -- name - the hander you want to remove
148 -- Returns true if successful
149 function lib:Unregister(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)
150 assert(a1, "Unregister: No timer name was passed")
151 if not self.var.handlers[a1] then return end
152 if compost then compost:Reclaim(self.var.handlers[a1]) end
153 self.var.handlers[a1] = nil
154 if a2 then self:Unregister(a2,a3,a4,a5,a6,a7,a8,a9,a10)
155 elseif not self:HasHandlers() then self.var.frame:Hide() end
156 return true
157 end
158  
159  
160 -- Begins triggering updates
161 -- name - the hander you want to start
162 -- numexec (optional) - Limit the number of times the timer runs
163 -- Returns true if successful
164 function lib:Start(name, numexec)
165 assert(name, "Start: No timer name was passed")
166 if not self.var.handlers[name] then return end
167 self.var.handlers[name].limit = numexec
168 self.var.handlers[name].elapsed = 0
169 self.var.handlers[name].running = true
170 self.var.frame:Show()
171 return true
172 end
173  
174  
175 -- Stops triggering updates
176 -- name - the hander you want to stop
177 -- Returns true if successful
178 function lib:Stop(name)
179 assert(name, "Stop: No timer name was passed")
180 if not self.var.handlers[name] then return end
181 self.var.handlers[name].running = nil
182 self.var.handlers[name].limit = nil
183 if not self:HasHandlers() then self.var.frame:Hide() end
184 return true
185 end
186  
187  
188 -- Changes the execution rate of a timer.
189 -- This will also reset the timer's elapsed time to 0
190 -- name - The timer you wish to change
191 -- newrate (optional)- The new exec rate, in seconds. If nil or 0 default OnUpdate timing will be used
192 -- n#,r# (optional) - Recusivly calls ChangeRate to allow you to set up to 5 rates in one call.
193 -- Returns true if successful
194 function lib:ChangeRate(name, newrate, n2,r2,n3,r3,n4,r4,n5,r5)
195 assert(name, "ChangeRate: No timer name was passed")
196 if not self.var.handlers[name] then
197 if n2 then return nil, self:ChangeRate(n2,r2,n3,r3,n4,r4,n5,r5)
198 else return end
199 end
200  
201 local t = self.var.handlers[name]
202 t.elapsed = 0
203 t.rate = newrate or 0
204 if n2 then return true, self:ChangeRate(n2,r2,n3,r3,n4,r4,n5,r5)
205 else return true end
206 end
207  
208  
209 -- Resets the profile stats for a timer
210 -- Accepts up to 10 timer names to clear
211 function lib:ClearStats(name, n2, n3, n4, n5, n6, n7, n8, n9, n10)
212 assert(name, "ChangeRate: No timer name was passed")
213 if not self.var.handlers[name] then
214 if n2 then return nil, self:ClearStats(n2,r2,n3,r3,n4,r4,n5,r5)
215 else return end
216 end
217  
218 local t = self.var.handlers[name]
219 t.count, t.mem, t.time = 0, 0, 0
220 if n2 then return true, self:ClearStats(n2,r2,n3,r3,n4,r4,n5,r5)
221 else return true end
222 end
223  
224  
225 -- Query a timer's status
226 -- Args: name - the schedule you wish to look up
227 -- Returns: registered - true if a schedule exists with this name
228 -- rate - the registered rate, if defined
229 -- running - true if this schedule is currently running
230 function lib:Status(name)
231 assert(name, "Status: No timer name was passed")
232 if not self.var.handlers[name] then return end
233 return true, self.var.handlers[name].rate, self.var.handlers[name].running, self.var.handlers[name].limit
234 end
235  
236  
237 -- Query a timer's profile info
238 -- Args: name - the schedule you wish to look up
239 -- Returns: mem - the total memory consumed by the timer's execution (in KiB)
240 -- time - the total time consumed by the timer's execution (in sec)
241 -- count - the number of times the timer has been triggered
242 -- rate - the rate at which the timer triggers (0 means the default OnUpdate rate)
243 function lib:Profile(name)
244 assert(name, "Profile: No timer name was passed")
245 if not self.var.handlers[name] then return end
246 local t = self.var.handlers[name]
247 return t.mem, t.time, t.count, t.rate
248 end
249  
250  
251 function lib:OnUpdate()
252 for i,v in pairs(this.owner.var.handlers) do
253 if v.running then
254 v.elapsed = v.elapsed + arg1
255 if v.elapsed >= v.rate then
256 local mem, time = gcinfo(), GetTime()
257 v.func(v.a1 or v.arg, v.a2 or v.elapsed, v.a3, v.a4, v.a5, v.a6)
258 mem, time = gcinfo() - mem, GetTime() - time
259 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
260 v.elapsed = 0
261 if v.limit then v.limit = v.limit - 1 end
262 if v.limit and v.limit <= 0 then this.owner:Stop(i) end
263 end
264 end
265 end
266 end
267  
268  
269 function lib:HasHandlers()
270 for i in pairs(self.var.handlers) do return true end
271 end
272  
273  
274 --------------------------------
275 -- Load this bitch! --
276 --------------------------------
277 libobj:Register(lib)