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: 17136 $
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
6 Website: http://www.wowace.com/
7 Documentation: http://www.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, scheduling, and inter-addon
10 communication.
11 Dependencies: AceLibrary, AceOO-2.0
12 ]]
13  
14 local MAJOR_VERSION = "AceEvent-2.0"
15 local MINOR_VERSION = "$Revision: 17136 $"
16  
17 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
18 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
19  
20 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
21  
22 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
23 local Mixin = AceOO.Mixin
24 local AceEvent = Mixin {
25 "RegisterEvent",
26 "RegisterAllEvents",
27 "UnregisterEvent",
28 "UnregisterAllEvents",
29 "TriggerEvent",
30 "ScheduleEvent",
31 "ScheduleRepeatingEvent",
32 "CancelScheduledEvent",
33 "CancelAllScheduledEvents",
34 "IsEventRegistered",
35 "IsEventScheduled",
36 "RegisterBucketEvent",
37 "UnregisterBucketEvent",
38 "UnregisterAllBucketEvents",
39 "IsBucketEventRegistered",
40 }
41  
42 local table_setn
43 do
44 local version = GetBuildInfo()
45 if string.find(version, "^2%.") then
46 -- 2.0.0
47 table_setn = function() end
48 else
49 table_setn = table.setn
50 end
51 end
52  
53 local weakKey = {__mode="k"}
54 local new, del
55 do
56 local list = setmetatable({}, weakKey)
57 function new()
58 local t = next(list)
59 if t then
60 list[t] = nil
61 return t
62 else
63 return {}
64 end
65 end
66  
67 function del(t)
68 setmetatable(t, nil)
69 for k in pairs(t) do
70 t[k] = nil
71 end
72 list[t] = true
73 end
74 end
75  
76 local FAKE_NIL
77 local RATE
78  
79 local eventsWhichHappenOnce = {
80 PLAYER_LOGIN = true,
81 AceEvent_FullyInitialized = true,
82 VARIABLES_LOADED = true,
83 PLAYER_LOGOUT = true,
84 }
85  
86 local registeringFromAceEvent
87 function AceEvent:RegisterEvent(event, method, once)
88 AceEvent:argCheck(event, 2, "string")
89 if self == AceEvent and not registeringFromAceEvent then
90 AceEvent:argCheck(method, 3, "function")
91 self = method
92 else
93 AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number")
94 if type(method) == "boolean" or type(method) == "number" then
95 AceEvent:argCheck(once, 4, "nil")
96 once, method = method, event
97 end
98 end
99 AceEvent:argCheck(once, 4, "number", "boolean", "nil")
100 if eventsWhichHappenOnce[event] then
101 once = true
102 end
103 local throttleRate
104 if type(once) == "number" then
105 throttleRate, once = once
106 end
107 if not method then
108 method = event
109 end
110 if type(method) == "string" and type(self[method]) ~= "function" then
111 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
112 else
113 assert(type(method) == "function" or type(method) == "string")
114 end
115  
116 local AceEvent_registry = AceEvent.registry
117 if not AceEvent_registry[event] then
118 AceEvent_registry[event] = new()
119 AceEvent.frame:RegisterEvent(event)
120 end
121  
122 local remember = true
123 if AceEvent_registry[event][self] then
124 remember = false
125 end
126 AceEvent_registry[event][self] = method
127  
128 local AceEvent_onceRegistry = AceEvent.onceRegistry
129 if once then
130 if not AceEvent_onceRegistry then
131 AceEvent.onceRegistry = new()
132 AceEvent_onceRegistry = AceEvent.onceRegistry
133 end
134 if not AceEvent_onceRegistry[event] then
135 AceEvent_onceRegistry[event] = new()
136 end
137 AceEvent_onceRegistry[event][self] = true
138 else
139 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
140 AceEvent_onceRegistry[event][self] = nil
141 if not next(AceEvent_onceRegistry[event]) then
142 AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
143 end
144 end
145 end
146  
147 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
148 if throttleRate then
149 if not AceEvent_throttleRegistry then
150 AceEvent.throttleRegistry = new()
151 AceEvent_throttleRegistry = AceEvent.throttleRegistry
152 end
153 if not AceEvent_throttleRegistry[event] then
154 AceEvent_throttleRegistry[event] = new()
155 end
156 if AceEvent_throttleRegistry[event][self] then
157 AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
158 end
159 AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey)
160 local t = AceEvent_throttleRegistry[event][self]
161 t[RATE] = throttleRate
162 else
163 if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then
164 if AceEvent_throttleRegistry[event][self] then
165 AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
166 end
167 if not next(AceEvent_throttleRegistry[event]) then
168 AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
169 end
170 end
171 end
172  
173 if remember then
174 AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event)
175 end
176 end
177  
178 local ALL_EVENTS
179  
180 function AceEvent:RegisterAllEvents(method)
181 if self == AceEvent then
182 AceEvent:argCheck(method, 1, "function")
183 self = method
184 else
185 AceEvent:argCheck(method, 1, "string", "function")
186 if type(method) == "string" and type(self[method]) ~= "function" then
187 AceEvent:error("Cannot register all events to method %q, it does not exist", method)
188 end
189 end
190  
191 local AceEvent_registry = AceEvent.registry
192 if not AceEvent_registry[ALL_EVENTS] then
193 AceEvent_registry[ALL_EVENTS] = new()
194 AceEvent.frame:RegisterAllEvents()
195 end
196  
197 AceEvent_registry[ALL_EVENTS][self] = method
198 end
199  
200 local _G = getfenv(0)
201 local memstack, timestack = {}, {}
202 local memdiff, timediff
203 function AceEvent:TriggerEvent(event, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
204 AceEvent:argCheck(event, 2, "string")
205 local AceEvent_registry = AceEvent.registry
206 if (not AceEvent_registry[event] or not next(AceEvent_registry[event])) and (not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS])) then
207 return
208 end
209 local _G_event = _G.event
210 _G.event = event
211 local lastEvent = AceEvent.currentEvent
212 AceEvent.currentEvent = event
213  
214 local AceEvent_onceRegistry = AceEvent.onceRegistry
215 local AceEvent_debugTable = AceEvent.debugTable
216 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
217 local tmp = new()
218 for obj, method in pairs(AceEvent_onceRegistry[event]) do
219 tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
220 end
221 local obj = next(tmp)
222 while obj do
223 local mem, time
224 if AceEvent_debugTable then
225 if not AceEvent_debugTable[event] then
226 AceEvent_debugTable[event] = new()
227 end
228 if not AceEvent_debugTable[event][obj] then
229 AceEvent_debugTable[event][obj] = new()
230 AceEvent_debugTable[event][obj].mem = 0
231 AceEvent_debugTable[event][obj].time = 0
232 AceEvent_debugTable[event][obj].count = 0
233 end
234 if memdiff then
235 table.insert(memstack, memdiff)
236 table.insert(timestack, timediff)
237 end
238 memdiff, timediff = 0, 0
239 mem, time = gcinfo(), GetTime()
240 end
241 local method = tmp[obj]
242 AceEvent.UnregisterEvent(obj, event)
243 if type(method) == "string" then
244 local obj_method = obj[method]
245 if obj_method then
246 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
247 end
248 elseif method then -- function
249 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
250 end
251 if AceEvent_debugTable then
252 local dmem, dtime = memdiff, timediff
253 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
254 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
255 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
256 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
257  
258 memdiff, timediff = table.remove(memstack), table.remove(timestack)
259 if memdiff then
260 memdiff = memdiff + mem + dmem
261 timediff = timediff + time + dtime
262 end
263 end
264 tmp[obj] = nil
265 obj = next(tmp)
266 end
267 del(tmp)
268 end
269  
270 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
271 local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
272 if AceEvent_registry[event] then
273 local tmp = new()
274 for obj, method in pairs(AceEvent_registry[event]) do
275 tmp[obj] = method
276 end
277 local obj = next(tmp)
278 while obj do
279 local method = tmp[obj]
280 local continue = false
281 if throttleTable and throttleTable[obj] then
282 local a1 = a1
283 if a1 == nil then
284 a1 = FAKE_NIL
285 end
286 if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
287 throttleTable[obj][a1] = GetTime()
288 else
289 continue = true
290 end
291 end
292 if not continue then
293 local mem, time
294 if AceEvent_debugTable then
295 if not AceEvent_debugTable[event] then
296 AceEvent_debugTable[event] = new()
297 end
298 if not AceEvent_debugTable[event][obj] then
299 AceEvent_debugTable[event][obj] = new()
300 AceEvent_debugTable[event][obj].mem = 0
301 AceEvent_debugTable[event][obj].time = 0
302 AceEvent_debugTable[event][obj].count = 0
303 end
304 if memdiff then
305 table.insert(memstack, memdiff)
306 table.insert(timestack, timediff)
307 end
308 memdiff, timediff = 0, 0
309 mem, time = gcinfo(), GetTime()
310 end
311 if type(method) == "string" then
312 local obj_method = obj[method]
313 if obj_method then
314 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
315 end
316 elseif method then -- function
317 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
318 end
319 if AceEvent_debugTable then
320 local dmem, dtime = memdiff, timediff
321 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
322 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
323 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
324 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
325  
326 memdiff, timediff = table.remove(memstack), table.remove(timestack)
327 if memdiff then
328 memdiff = memdiff + mem + dmem
329 timediff = timediff + time + dtime
330 end
331 end
332 end
333 tmp[obj] = nil
334 obj = next(tmp)
335 end
336 del(tmp)
337 end
338 if AceEvent_registry[ALL_EVENTS] then
339 local tmp = new()
340 for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
341 tmp[obj] = method
342 end
343 local obj = next(tmp)
344 while obj do
345 local method = tmp[obj]
346 local mem, time
347 if AceEvent_debugTable then
348 if not AceEvent_debugTable[event] then
349 AceEvent_debugTable[event] = new()
350 end
351 if not AceEvent_debugTable[event][obj] then
352 AceEvent_debugTable[event][obj] = new()
353 AceEvent_debugTable[event][obj].mem = 0
354 AceEvent_debugTable[event][obj].time = 0
355 AceEvent_debugTable[event][obj].count = 0
356 end
357 if memdiff then
358 table.insert(memstack, memdiff)
359 table.insert(timestack, timediff)
360 end
361 memdiff, timediff = 0, 0
362 mem, time = gcinfo(), GetTime()
363 end
364 if type(method) == "string" then
365 local obj_method = obj[method]
366 if obj_method then
367 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
368 end
369 elseif method then -- function
370 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
371 end
372 if AceEvent_debugTable then
373 local dmem, dtime = memdiff, timediff
374 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
375 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
376 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
377 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
378  
379 memdiff, timediff = table.remove(memstack), table.remove(timestack)
380 if memdiff then
381 memdiff = memdiff + mem + dmem
382 timediff = timediff + time + dtime
383 end
384 end
385 tmp[obj] = nil
386 obj = next(tmp)
387 end
388 del(tmp)
389 end
390 _G.event = _G_event
391 AceEvent.currentEvent = lastEvent
392 end
393  
394 -- local accessors
395 local getn = table.getn
396 local tinsert = table.insert
397 local tremove = table.remove
398 local floor = math.floor
399 local GetTime = GetTime
400 local next = next
401 local pairs = pairs
402 local unpack = unpack
403  
404 local delayRegistry
405 local tmp = {}
406 local function OnUpdate()
407 local t = GetTime()
408 for k,v in pairs(delayRegistry) do
409 tmp[k] = true
410 end
411 for k in pairs(tmp) do
412 local v = delayRegistry[k]
413 if v then
414 local v_time = v.time
415 if not v_time then
416 delayRegistry[k] = del(v)
417 elseif v_time <= t then
418 local v_repeatDelay = v.repeatDelay
419 if v_repeatDelay then
420 -- use the event time, not the current time, else timing inaccuracies add up over time
421 v.time = v_time + v_repeatDelay
422 end
423 local event = v.event
424 local mem, time
425 if AceEvent_debugTable then
426 mem, time = gcinfo(), GetTime()
427 end
428 if type(event) == "function" then
429 event(unpack(v))
430 else
431 AceEvent:TriggerEvent(event, unpack(v))
432 end
433 if AceEvent_debugTable then
434 mem, time = gcinfo() - mem, GetTime() - time
435 v.mem = v.mem + mem
436 v.timeSpent = v.timeSpent + time
437 v.count = v.count + 1
438 end
439 if not v_repeatDelay then
440 local x = delayRegistry[k]
441 if x and x.time == v_time then -- check if it was manually reset
442 delayRegistry[k] = del(v)
443 end
444 end
445 end
446 end
447 end
448 for k in pairs(tmp) do
449 tmp[k] = nil
450 end
451 if not next(delayRegistry) then
452 AceEvent.frame:Hide()
453 end
454 end
455  
456 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)
457 local id
458 if type(event) == "string" or type(event) == "table" then
459 if type(event) == "table" then
460 if not delayRegistry or not delayRegistry[event] then
461 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
462 end
463 end
464 if type(delay) ~= "number" then
465 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
466 AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
467 AceEvent:argCheck(delay, 4, "number")
468 self:CancelScheduledEvent(id)
469 end
470 else
471 AceEvent:argCheck(event, 2, "string", "function")
472 AceEvent:argCheck(delay, 3, "number")
473 end
474  
475 if not delayRegistry then
476 AceEvent.delayRegistry = new()
477 delayRegistry = AceEvent.delayRegistry
478 AceEvent.frame:SetScript("OnUpdate", OnUpdate)
479 end
480 local t
481 if type(id) == "table" then
482 for k in pairs(id) do
483 id[k] = nil
484 end
485 t = id
486 else
487 t = new()
488 end
489 t[1] = a1
490 t[2] = a2
491 t[3] = a3
492 t[4] = a4
493 t[5] = a5
494 t[6] = a6
495 t[7] = a7
496 t[8] = a8
497 t[9] = a9
498 t[10] = a10
499 t[11] = a11
500 t[12] = a12
501 t[13] = a13
502 t[14] = a14
503 t[15] = a15
504 t[16] = a16
505 t[17] = a17
506 t[18] = a18
507 t[19] = a19
508 t[20] = a20
509 table_setn(t, 20)
510 t.event = event
511 t.time = GetTime() + delay
512 t.self = self
513 t.id = id or t
514 t.repeatDelay = repeating and delay
515 if AceEvent_debugTable then
516 t.mem = 0
517 t.count = 0
518 t.timeSpent = 0
519 end
520 delayRegistry[t.id] = t
521 AceEvent.frame:Show()
522 return t.id
523 end
524  
525 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)
526 if type(event) == "string" or type(event) == "table" then
527 if type(event) == "table" then
528 if not delayRegistry or not delayRegistry[event] then
529 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
530 end
531 end
532 if type(delay) ~= "number" then
533 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
534 AceEvent:argCheck(a1, 4, "number")
535 end
536 else
537 AceEvent:argCheck(event, 2, "string", "function")
538 AceEvent:argCheck(delay, 3, "number")
539 end
540  
541 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)
542 end
543  
544 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)
545 if type(event) == "string" or type(event) == "table" then
546 if type(event) == "table" then
547 if not delayRegistry or not delayRegistry[event] then
548 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
549 end
550 end
551 if type(delay) ~= "number" then
552 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
553 AceEvent:argCheck(a1, 4, "number")
554 end
555 else
556 AceEvent:argCheck(event, 2, "string", "function")
557 AceEvent:argCheck(delay, 3, "number")
558 end
559  
560 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)
561 end
562  
563 function AceEvent:CancelScheduledEvent(t)
564 AceEvent:argCheck(t, 2, "string", "table")
565 if delayRegistry then
566 local v = delayRegistry[t]
567 if v then
568 delayRegistry[t] = del(v)
569 if not next(delayRegistry) then
570 AceEvent.frame:Hide()
571 end
572 return true
573 end
574 end
575 return false
576 end
577  
578 function AceEvent:IsEventScheduled(t)
579 AceEvent:argCheck(t, 2, "string", "table")
580 if delayRegistry then
581 local v = delayRegistry[t]
582 if v then
583 return true, v.time - GetTime()
584 end
585 end
586 return false, nil
587 end
588  
589 function AceEvent:UnregisterEvent(event)
590 AceEvent:argCheck(event, 2, "string")
591 local AceEvent_registry = AceEvent.registry
592 if AceEvent_registry[event] and AceEvent_registry[event][self] then
593 AceEvent_registry[event][self] = nil
594 local AceEvent_onceRegistry = AceEvent.onceRegistry
595 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
596 AceEvent_onceRegistry[event][self] = nil
597 if not next(AceEvent_onceRegistry[event]) then
598 AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
599 end
600 end
601 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
602 if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
603 AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
604 if not next(AceEvent_throttleRegistry[event]) then
605 AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
606 end
607 end
608 if not next(AceEvent_registry[event]) then
609 AceEvent_registry[event] = del(AceEvent_registry[event])
610 if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
611 AceEvent.frame:UnregisterEvent(event)
612 end
613 end
614 else
615 if self == AceEvent then
616 error(string.format("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0.", event), 2)
617 else
618 AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
619 end
620 end
621 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
622 end
623  
624 function AceEvent:UnregisterAllEvents()
625 local AceEvent_registry = AceEvent.registry
626 if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
627 AceEvent_registry[ALL_EVENTS][self] = nil
628 if not next(AceEvent_registry[ALL_EVENTS]) then
629 del(AceEvent_registry[ALL_EVENTS])
630 AceEvent.frame:UnregisterAllEvents()
631 for k,v in pairs(AceEvent_registry) do
632 if k ~= ALL_EVENTS then
633 AceEvent.frame:RegisterEvent(k)
634 end
635 end
636 AceEvent_registry[event] = nil
637 end
638 end
639 local first = true
640 for event, data in pairs(AceEvent_registry) do
641 if first then
642 if AceEvent_registry.AceEvent_EventUnregistered then
643 event = "AceEvent_EventUnregistered"
644 else
645 first = false
646 end
647 end
648 local x = data[self]
649 data[self] = nil
650 if x and event ~= ALL_EVENTS then
651 if not next(data) then
652 del(data)
653 if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
654 AceEvent.frame:UnregisterEvent(event)
655 end
656 AceEvent_registry[event] = nil
657 end
658 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
659 end
660 if first then
661 event = nil
662 end
663 end
664 if AceEvent.onceRegistry then
665 for event, data in pairs(AceEvent.onceRegistry) do
666 data[self] = nil
667 end
668 end
669 end
670  
671 function AceEvent:CancelAllScheduledEvents()
672 if delayRegistry then
673 for k,v in pairs(delayRegistry) do
674 if v.self == self then
675 delayRegistry[k] = del(v)
676 end
677 end
678 if not next(delayRegistry) then
679 AceEvent.frame:Hide()
680 end
681 end
682 end
683  
684 function AceEvent:IsEventRegistered(event)
685 AceEvent:argCheck(event, 2, "string")
686 local AceEvent_registry = AceEvent.registry
687 if self == AceEvent then
688 return AceEvent_registry[event] and next(AceEvent_registry[event]) and true or false
689 end
690 if AceEvent_registry[event] and AceEvent_registry[event][self] then
691 return true, AceEvent_registry[event][self]
692 end
693 return false, nil
694 end
695  
696 local bucketfunc
697 function AceEvent:RegisterBucketEvent(event, delay, method)
698 AceEvent:argCheck(event, 2, "string", "table")
699 if type(event) == "table" then
700 for k,v in pairs(event) do
701 if type(k) ~= "number" then
702 AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
703 elseif type(v) ~= "string" then
704 AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
705 end
706 end
707 end
708 AceEvent:argCheck(delay, 3, "number")
709 if AceEvent == self then
710 AceEvent:argCheck(method, 4, "function")
711 self = method
712 else
713 if type(event) == "string" then
714 AceEvent:argCheck(method, 4, "string", "function", "nil")
715 if not method then
716 method = event
717 end
718 else
719 AceEvent:argCheck(method, 4, "string", "function")
720 end
721  
722 if type(method) == "string" and type(self[method]) ~= "function" then
723 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
724 end
725 end
726 if not AceEvent.buckets then
727 AceEvent.buckets = new()
728 end
729 if not AceEvent.buckets[event] then
730 AceEvent.buckets[event] = new()
731 end
732 if not AceEvent.buckets[event][self] then
733 AceEvent.buckets[event][self] = new()
734 AceEvent.buckets[event][self].current = new()
735 AceEvent.buckets[event][self].self = self
736 else
737 AceEvent.CancelScheduledEvent(self, AceEvent.buckets[event][self].id)
738 end
739 local bucket = AceEvent.buckets[event][self]
740 bucket.method = method
741  
742 local func = function(arg1)
743 bucket.run = true
744 if arg1 then
745 bucket.current[arg1] = true
746 end
747 end
748 AceEvent.buckets[event][self].func = func
749 if type(event) == "string" then
750 AceEvent.RegisterEvent(self, event, func)
751 else
752 for _,v in ipairs(event) do
753 AceEvent.RegisterEvent(self, v, func)
754 end
755 end
756 if not bucketfunc then
757 bucketfunc = function(bucket)
758 local current = bucket.current
759 local method = bucket.method
760 local self = bucket.self
761 if bucket.run then
762 if type(method) == "string" then
763 self[method](self, current)
764 elseif method then -- function
765 method(current)
766 end
767 for k in pairs(current) do
768 current[k] = nil
769 k = nil
770 end
771 bucket.run = false
772 end
773 end
774 end
775 bucket.id = AceEvent.ScheduleRepeatingEvent(self, bucketfunc, delay, bucket)
776 end
777  
778 function AceEvent:IsBucketEventRegistered(event)
779 AceEvent:argCheck(event, 2, "string", "table")
780 return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
781 end
782  
783 function AceEvent:UnregisterBucketEvent(event)
784 AceEvent:argCheck(event, 2, "string", "table")
785 if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
786 AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
787 end
788  
789 local bucket = AceEvent.buckets[event][self]
790  
791 if type(event) == "string" then
792 AceEvent.UnregisterEvent(self, event)
793 else
794 for _,v in ipairs(event) do
795 AceEvent.UnregisterEvent(self, v)
796 end
797 end
798 AceEvent:CancelScheduledEvent(bucket.id)
799  
800 del(bucket.current)
801 AceEvent.buckets[event][self] = del(AceEvent.buckets[event][self])
802 if not next(AceEvent.buckets[event]) then
803 AceEvent.buckets[event] = del(AceEvent.buckets[event])
804 end
805 end
806  
807 function AceEvent:UnregisterAllBucketEvents()
808 if not AceEvent.buckets or not next(AceEvent.buckets) then
809 return
810 end
811 for k,v in pairs(AceEvent.buckets) do
812 if v == self then
813 AceEvent.UnregisterBucketEvent(self, k)
814 k = nil
815 end
816 end
817 end
818  
819 function AceEvent:OnEmbedDisable(target)
820 self.UnregisterAllEvents(target)
821  
822 self.CancelAllScheduledEvents(target)
823  
824 self.UnregisterAllBucketEvents(target)
825 end
826  
827 function AceEvent:EnableDebugging()
828 if not self.debugTable then
829 self.debugTable = new()
830  
831 if delayRegistry then
832 for k,v in pairs(self.delayRegistry) do
833 if not v.mem then
834 v.mem = 0
835 v.count = 0
836 v.timeSpent = 0
837 end
838 end
839 end
840 end
841 end
842  
843 function AceEvent:IsFullyInitialized()
844 return self.postInit or false
845 end
846  
847 function AceEvent:IsPostPlayerLogin()
848 return self.playerLogin or false
849 end
850  
851 function AceEvent:activate(oldLib, oldDeactivate)
852 AceEvent = self
853  
854 if oldLib then
855 self.onceRegistry = oldLib.onceRegistry
856 self.throttleRegistry = oldLib.throttleRegistry
857 self.delayRegistry = oldLib.delayRegistry
858 self.buckets = oldLib.buckets
859 self.registry = oldLib.registry
860 self.frame = oldLib.frame
861 self.debugTable = oldLib.debugTable
862 self.playerLogin = oldLib.pew or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage and true
863 self.postInit = oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
864 self.ALL_EVENTS = oldLib.ALL_EVENTS
865 self.FAKE_NIL = oldLib.FAKE_NIL
866 self.RATE = oldLib.RATE
867 end
868 if not self.registry then
869 self.registry = {}
870 end
871 if not self.frame then
872 self.frame = CreateFrame("Frame", "AceEvent20Frame")
873 end
874 if not self.ALL_EVENTS then
875 self.ALL_EVENTS = {}
876 end
877 if not self.FAKE_NIL then
878 self.FAKE_NIL = {}
879 end
880 if not self.RATE then
881 self.RATE = {}
882 end
883 ALL_EVENTS = self.ALL_EVENTS
884 FAKE_NIL = self.FAKE_NIL
885 RATE = self.RATE
886 local inPlw = false
887 local blacklist = {
888 UNIT_INVENTORY_CHANGED = true,
889 BAG_UPDATE = true,
890 ITEM_LOCK_CHANGED = true,
891 ACTIONBAR_SLOT_CHANGED = true,
892 }
893 self.frame:SetScript("OnEvent", function()
894 local event = event
895 if event == "PLAYER_ENTERING_WORLD" then
896 inPlw = false
897 elseif event == "PLAYER_LEAVING_WORLD" then
898 inPlw = true
899 end
900 if event and (not inPlw or not blacklist[event]) then
901 self:TriggerEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
902 end
903 end)
904 if self.delayRegistry then
905 delayRegistry = self.delayRegistry
906 self.frame:SetScript("OnUpdate", OnUpdate)
907 end
908  
909 self:UnregisterAllEvents()
910 self:CancelAllScheduledEvents()
911  
912 registeringFromAceEvent = true
913 self:RegisterEvent("LOOT_OPENED", function()
914 SendAddonMessage("LOOT_OPENED", "", "RAID")
915 end)
916 registeringFromAceEvent = nil
917  
918 if not self.playerLogin then
919 registeringFromAceEvent = true
920 self:RegisterEvent("PLAYER_LOGIN", function()
921 self.playerLogin = true
922 end, true)
923 registeringFromAceEvent = nil
924 end
925  
926 if not self.postInit then
927 local isReload = true
928 local function func()
929 self.postInit = true
930 self:TriggerEvent("AceEvent_FullyInitialized")
931 if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
932 self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
933 end
934 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
935 self:UnregisterEvent("MEETINGSTONE_CHANGED")
936 end
937 if self.registry["MINIMAP_ZONE_CHANGED"] and self.registry["MINIMAP_ZONE_CHANGED"][self] then
938 self:UnregisterEvent("MINIMAP_ZONE_CHANGED")
939 end
940 if self.registry["LANGUAGE_LIST_CHANGED"] and self.registry["LANGUAGE_LIST_CHANGED"][self] then
941 self:UnregisterEvent("LANGUAGE_LIST_CHANGED")
942 end
943 end
944 registeringFromAceEvent = true
945 local f = function()
946 self.playerLogin = true
947 self:ScheduleEvent("AceEvent_FullyInitialized", func, 1)
948 end
949 self:RegisterEvent("MEETINGSTONE_CHANGED", f, true)
950 self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function()
951 self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.05)
952 end)
953 self:RegisterEvent("LANGUAGE_LIST_CHANGED", function()
954 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
955 self:UnregisterEvent("MEETINGSTONE_CHANGED")
956 self:RegisterEvent("MINIMAP_ZONE_CHANGED", f, true)
957 end
958 end)
959 registeringFromAceEvent = nil
960 end
961  
962 self.super.activate(self, oldLib, oldDeactivate)
963 if oldLib then
964 oldDeactivate(oldLib)
965 end
966 end
967  
968 AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, AceEvent.activate)
969 AceEvent = AceLibrary(MAJOR_VERSION)