vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: AceEvent-2.0
3 Revision: $Rev: 4599 $
4 Author(s): ckknight (ckknight@gmail.com)
5 Inspired By: AceEvent 1.x by Turan (<email here>)
6 Website: http://www.wowace.com/
7 Documentation: http://wiki.wowace.com/index.php/AceEvent-2.0
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceEvent-2.0
9 Description: Mixin to allow for event handling and inter-addon communication.
10 Dependencies: AceLibrary, AceOO-2.0, Compost-2.0 (optional)
11 ]]
12  
13 local MAJOR_VERSION = "AceEvent-2.0"
14 local MINOR_VERSION = "$Revision: 4599 $"
15  
16 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
17 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
18  
19 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
20  
21 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
22 local Mixin = AceOO.Mixin
23 local AceEvent = Mixin {
24 "RegisterEvent",
25 "UnregisterEvent",
26 "UnregisterAllEvents",
27 "TriggerEvent",
28 "ScheduleEvent",
29 "ScheduleRepeatingEvent",
30 "CancelScheduledEvent",
31 "CancelAllScheduledEvents",
32 "TriggerDelayedEvent", -- remove on July 23
33 "CancelDelayedEvent", -- remove on July 23
34 "IsEventRegistered",
35 "IsEventScheduled",
36 }
37  
38 local Compost = AceLibrary:HasInstance("Compost-2.0") and AceLibrary("Compost-2.0")
39  
40 function AceEvent:RegisterEvent(event, method, once)
41 AceEvent:argCheck(event, 2, "string")
42 AceEvent:argCheck(method, 3, "string", "function", "nil")
43 AceEvent:argCheck(once, 4, "boolean", "nil")
44 if not method then
45 method = event
46 end
47 if type(method) == "string" and type(self[method]) ~= "function" then
48 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
49 end
50  
51 if not AceEvent.registry[event] then
52 AceEvent.registry[event] = Compost and Compost:Acquire() or {}
53 AceEvent.frame:RegisterEvent(event)
54 end
55  
56 AceEvent.registry[event][self] = method
57  
58 if once then
59 if not AceEvent.onceRegistry then
60 AceEvent.onceRegistry = Compost and Compost:Acquire() or {}
61 end
62 if not AceEvent.onceRegistry[event] then
63 AceEvent.onceRegistry[event] = Compost and Compost:Acquire() or {}
64 end
65 AceEvent.onceRegistry[event][self] = true
66 else
67 if AceEvent.onceRegistry and AceEvent.onceRegistry[event] then
68 AceEvent.onceRegistry[event][self] = nil
69 end
70 end
71 end
72  
73 local _G = getfenv(0)
74 function AceEvent:TriggerEvent(event, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
75 AceEvent:argCheck(event, 2, "string")
76 local _G_event = _G.event
77 _G.event = event
78  
79 if AceEvent.registry[event] then
80 if AceEvent.onceRegistry and AceEvent.onceRegistry[event] then
81 for obj in pairs(AceEvent.onceRegistry[event]) do
82 local mem, time
83 if AceEvent.debugTable then
84 if not AceEvent.debugTable[event] then
85 AceEvent.debugTable[event] = Compost and Compost:Acquire() or {}
86 end
87 if not AceEvent.debugTable[event][obj] then
88 AceEvent.debugTable[event][obj] = Compost and Compost:AcquireHash(
89 'mem', 0,
90 'time', 0
91 ) or {
92 mem = 0,
93 time = 0
94 }
95 end
96 mem, time = gcinfo(), GetTime()
97 end
98 local method = AceEvent.registry[event][obj]
99 AceEvent.registry[event][obj] = nil
100 AceEvent.onceRegistry[event][obj] = nil
101 if type(method) == "string" then
102 if obj[method] then
103 obj[method](obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
104 end
105 elseif method then -- function
106 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
107 end
108 if AceEvent.debugTable then
109 mem, time = mem - gcinfo(), time - GetTime()
110 AceEvent.debugTable[event][obj].mem = AceEvent.debugTable[event][obj].mem + mem
111 AceEvent.debugTable[event][obj].time = AceEvent.debugTable[event][obj].time + time
112 end
113 obj = nil
114 end
115 end
116 for obj, method in pairs(AceEvent.registry[event]) do
117 local mem, time
118 if AceEvent.debugTable then
119 if not AceEvent.debugTable[event] then
120 AceEvent.debugTable[event] = Compost and Compost:Acquire() or {}
121 end
122 if not AceEvent.debugTable[event][obj] then
123 AceEvent.debugTable[event][obj] = Compost and Compost:AcquireHash(
124 'mem', 0,
125 'time', 0
126 ) or {
127 mem = 0,
128 time = 0
129 }
130 end
131 mem, time = gcinfo(), GetTime()
132 end
133 if type(method) == "string" then
134 if obj[method] then
135 obj[method](obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
136 end
137 else -- function
138 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
139 end
140 if AceEvent.debugTable then
141 mem, time = mem - gcinfo(), time - GetTime()
142 AceEvent.debugTable[event][obj].mem = AceEvent.debugTable[event][obj].mem + mem
143 AceEvent.debugTable[event][obj].time = AceEvent.debugTable[event][obj].time + time
144 end
145 end
146 end
147 _G.event = _G_event
148 end
149  
150 local GetTime = GetTime
151 local delayRegistry
152 local function OnUpdate()
153 local t = GetTime()
154 local last = nil
155 for k,v in pairs(delayRegistry) do
156 if v.time <= t then
157 if v.repeatDelay then
158 v.time = t + v.repeatDelay
159 last = k
160 else
161 delayRegistry[k] = nil
162 end
163 local event = v.event
164 if type(event) == "function" then
165 event(unpack(v))
166 else
167 AceEvent:TriggerEvent(event, unpack(v))
168 end
169 if not v.repeatDelay and Compost then
170 Compost:Reclaim(v)
171 end
172 k = last
173 else
174 last = k
175 end
176 end
177 if not next(delayRegistry) then
178 AceEvent.frame:Hide()
179 end
180 end
181  
182 local stage = 3
183 if tonumber(date("%Y%m%d")) < 20060716 then
184 stage = 1
185 elseif tonumber(date("%Y%m%d")) < 20060723 then
186 stage = 2
187 end
188  
189 if stage <= 2 then
190 function AceEvent:TriggerDelayedEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
191 if stage == 2 then
192 local line = string.gsub(debugstack(), ".-\n(.-)\n.*", "%1")
193 DEFAULT_CHAT_MESSAGE:AddMessage(line .. " - `TriggerDelayedEvent' has been replaced with `ScheduleEvent'. This will cause an error on July 23, 2006.")
194 end
195 self:ScheduleEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
196 end
197 function AceEvent:CancelDelayedEvent(t)
198 if stage == 2 then
199 local line = string.gsub(debugstack(), ".-\n(.-)\n.*", "%1")
200 DEFAULT_CHAT_MESSAGE:AddMessage(line .. " - `CancelDelayedEvent' has been replaced with `CancelScheduledEvent'. This will cause an error on July 23, 2006.")
201 end
202 self:CancelScheduledEvent(t)
203 end
204 end
205  
206 local function ScheduleEvent(self, repeating, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
207 local id
208 if type(event) == "string" or type(event) == "table" then
209 if type(event) == "table" then
210 if not delayRegistry[event] then
211 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
212 end
213 end
214 if type(delay) ~= "number" then
215 id, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20 = event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20
216 AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
217 AceEvent:argCheck(delay, 4, "number")
218 self:CancelScheduledEvent(id)
219 end
220 else
221 AceEvent:argCheck(event, 2, "string", "function")
222 AceEvent:argCheck(delay, 3, "number")
223 end
224  
225 if not AceEvent.delayRegistry then
226 AceEvent.delayRegistry = Compost and Compost:Acquire() or {}
227 delayRegistry = AceEvent.delayRegistry
228 AceEvent.frame:SetScript("OnUpdate", OnUpdate)
229 end
230 local t
231 if type(id) == "table" then
232 for k in pairs(id) do
233 id[k] = nil
234 end
235 table.setn(id, 0)
236 t = id
237 else
238 t = Compost and Compost:Acquire() or {}
239 end
240 t.n = 0
241 table.insert(t, a1)
242 table.insert(t, a2)
243 table.insert(t, a3)
244 table.insert(t, a4)
245 table.insert(t, a5)
246 table.insert(t, a6)
247 table.insert(t, a7)
248 table.insert(t, a8)
249 table.insert(t, a9)
250 table.insert(t, a10)
251 table.insert(t, a11)
252 table.insert(t, a12)
253 table.insert(t, a13)
254 table.insert(t, a14)
255 table.insert(t, a15)
256 table.insert(t, a16)
257 table.insert(t, a17)
258 table.insert(t, a18)
259 table.insert(t, a19)
260 table.insert(t, a20)
261 t.event = event
262 t.time = GetTime() + delay
263 t.self = self
264 t.id = id or t
265 t.repeatDelay = repeating and delay
266 AceEvent.delayRegistry[t.id] = t
267 AceEvent.frame:Show()
268 return t.id
269 end
270  
271 function AceEvent:ScheduleEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
272 return ScheduleEvent(self, false, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
273 end
274  
275 function AceEvent:ScheduleRepeatingEvent(event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
276 return ScheduleEvent(self, true, event, delay, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
277 end
278  
279 function AceEvent:CancelScheduledEvent(t)
280 AceEvent:argCheck(t, 2, "string", "table")
281 if AceEvent.delayRegistry then
282 local v = AceEvent.delayRegistry[t]
283 if v then
284 AceEvent.delayRegistry[t] = nil
285 if Compost then
286 Compost:Reclaim(v)
287 end
288 if not next(AceEvent.delayRegistry) then
289 AceEvent.frame:Hide()
290 end
291 return true
292 end
293 end
294 return false
295 end
296  
297 function AceEvent:IsEventScheduled(t)
298 AceEvent:argCheck(t, 2, "string", "table")
299 if AceEvent.delayRegistry then
300 local v = AceEvent.delayRegistry[t]
301 if v then
302 if Compost then
303 Compost:Reclaim(v)
304 end
305 return true, v.time - GetTime()
306 end
307 end
308 return false, nil
309 end
310  
311 function AceEvent:UnregisterEvent(event)
312 AceEvent:argCheck(event, 2, "string")
313  
314 if AceEvent.registry[event] and AceEvent.registry[event][self] then
315 AceEvent.registry[event][self] = nil
316 else
317 AceEvent:error("Cannot unregister an event that you are not registered with.")
318 end
319 end
320  
321 function AceEvent:UnregisterAllEvents()
322 for event, data in pairs(AceEvent.registry) do
323 data[self] = nil
324 end
325 end
326  
327 function AceEvent:CancelAllScheduledEvents()
328 if AceEvent.delayRegistry then
329 for k,v in pairs(AceEvent.delayRegistry) do
330 if v.self == target then
331 if Compost then
332 Compost:Reclaim(v)
333 end
334 AceEvent.delayRegistry[k] = nil
335 end
336 end
337 end
338 end
339  
340 function AceEvent:IsEventRegistered(event)
341 AceEvent:argCheck(event, 2, "string")
342 if AceEvent.registry[event] and AceEvent.registry[event][self] then
343 return true, AceEvent.registry[event][self]
344 end
345 return false, nil
346 end
347  
348 function AceEvent:OnEmbedDisable(target)
349 self.UnregisterAllEvents(target)
350  
351 self.CancelAllScheduledEvents(target)
352 end
353  
354 function AceEvent:EnableDebugging()
355 if not self.debugTable then
356 self.debugTable = {}
357 end
358 end
359  
360 function AceEvent:IsFullyInitialized()
361 return self.postInit or false
362 end
363  
364 function AceEvent:IsPostPlayerLogin()
365 return self.playerLogin or false
366 end
367  
368 function AceEvent:activate(oldLib, oldDeactivate)
369 AceEvent = self
370  
371 if oldLib then
372 self.onceRegistry = oldLib.onceRegistry
373 self.delayRegistry = oldLib.delayRegistry
374 self.registry = oldLib.registry
375 self.frame = oldLib.frame
376 self.debugTable = oldLib.debugTable
377 self.playerLogin = oldLib.pew or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage and true
378 self.postInit = oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
379 end
380 if not self.registry then
381 self.registry = {}
382 end
383 if not self.frame then
384 self.frame = CreateFrame("Frame")
385 end
386 self.frame:SetScript("OnEvent", function()
387 if event then
388 self:TriggerEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
389 end
390 end)
391 if self.delayRegistry then
392 delayRegistry = self.delayRegistry
393 self.frame:SetScript("OnUpdate", OnUpdate)
394 end
395  
396 self:UnregisterAllEvents()
397 self:CancelAllScheduledEvents()
398  
399 if not self.playerLogin then
400 self:RegisterEvent("PLAYER_LOGIN", function()
401 self.playerLogin = true
402 end, true)
403 end
404  
405 if not self.postInit then
406 local isReload = true
407 local function func()
408 self.postInit = true
409 self:TriggerEvent("AceEvent_FullyInitialized")
410 self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
411 self:UnregisterEvent("SPELLS_CHANGED")
412 end
413 self:RegisterEvent("MEETINGSTONE_CHANGED", function()
414 self.playerLogin = true
415 self:ScheduleEvent("AceEvent_FullyInitialized", func, isReload and 1 or 4)
416 end, true)
417 self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function()
418 self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.05)
419 end)
420 self:RegisterEvent("SPELLS_CHANGED", function()
421 isReload = false
422 end)
423 end
424  
425 self.super.activate(self, oldLib, oldDeactivate)
426 if oldLib then
427 oldDeactivate(oldLib)
428 end
429 end
430  
431 local function external(self, major, instance)
432 if major == "Compost-2.0" then
433 Compost = instance
434 end
435 end
436  
437 AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, AceEvent.activate, nil, external)
438 AceEvent = AceLibrary(MAJOR_VERSION)