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: 14125 $
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: 14125 $"
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  
212 local AceEvent_onceRegistry = AceEvent.onceRegistry
213 local AceEvent_debugTable = AceEvent.debugTable
214 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
215 local tmp = new()
216 for obj, method in pairs(AceEvent_onceRegistry[event]) do
217 tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
218 end
219 local obj = next(tmp)
220 while obj do
221 local mem, time
222 if AceEvent_debugTable then
223 if not AceEvent_debugTable[event] then
224 AceEvent_debugTable[event] = new()
225 end
226 if not AceEvent_debugTable[event][obj] then
227 AceEvent_debugTable[event][obj] = new()
228 AceEvent_debugTable[event][obj].mem = 0
229 AceEvent_debugTable[event][obj].time = 0
230 AceEvent_debugTable[event][obj].count = 0
231 end
232 if memdiff then
233 table.insert(memstack, memdiff)
234 table.insert(timestack, timediff)
235 end
236 memdiff, timediff = 0, 0
237 mem, time = gcinfo(), GetTime()
238 end
239 local method = tmp[obj]
240 AceEvent.UnregisterEvent(obj, event)
241 if type(method) == "string" then
242 local obj_method = obj[method]
243 if obj_method then
244 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
245 end
246 elseif method then -- function
247 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
248 end
249 if AceEvent_debugTable then
250 local dmem, dtime = memdiff, timediff
251 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
252 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
253 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
254 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
255  
256 memdiff, timediff = table.remove(memstack), table.remove(timestack)
257 if memdiff then
258 memdiff = memdiff + mem + dmem
259 timediff = timediff + time + dtime
260 end
261 end
262 tmp[obj] = nil
263 obj = next(tmp)
264 end
265 del(tmp)
266 end
267  
268 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
269 local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
270 if AceEvent_registry[event] then
271 local tmp = new()
272 for obj, method in pairs(AceEvent_registry[event]) do
273 tmp[obj] = method
274 end
275 local obj = next(tmp)
276 while obj do
277 local method = tmp[obj]
278 local continue = false
279 if throttleTable and throttleTable[obj] then
280 local a1 = a1
281 if a1 == nil then
282 a1 = FAKE_NIL
283 end
284 if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
285 throttleTable[obj][a1] = GetTime()
286 else
287 continue = true
288 end
289 end
290 if not continue then
291 local mem, time
292 if AceEvent_debugTable then
293 if not AceEvent_debugTable[event] then
294 AceEvent_debugTable[event] = new()
295 end
296 if not AceEvent_debugTable[event][obj] then
297 AceEvent_debugTable[event][obj] = new()
298 AceEvent_debugTable[event][obj].mem = 0
299 AceEvent_debugTable[event][obj].time = 0
300 AceEvent_debugTable[event][obj].count = 0
301 end
302 if memdiff then
303 table.insert(memstack, memdiff)
304 table.insert(timestack, timediff)
305 end
306 memdiff, timediff = 0, 0
307 mem, time = gcinfo(), GetTime()
308 end
309 if type(method) == "string" then
310 local obj_method = obj[method]
311 if obj_method then
312 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
313 end
314 elseif method then -- function
315 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
316 end
317 if AceEvent_debugTable then
318 local dmem, dtime = memdiff, timediff
319 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
320 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
321 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
322 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
323  
324 memdiff, timediff = table.remove(memstack), table.remove(timestack)
325 if memdiff then
326 memdiff = memdiff + mem + dmem
327 timediff = timediff + time + dtime
328 end
329 end
330 end
331 tmp[obj] = nil
332 obj = next(tmp)
333 end
334 del(tmp)
335 end
336 if AceEvent_registry[ALL_EVENTS] then
337 local tmp = new()
338 for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
339 tmp[obj] = method
340 end
341 local obj = next(tmp)
342 while obj do
343 local method = tmp[obj]
344 local mem, time
345 if AceEvent_debugTable then
346 if not AceEvent_debugTable[event] then
347 AceEvent_debugTable[event] = new()
348 end
349 if not AceEvent_debugTable[event][obj] then
350 AceEvent_debugTable[event][obj] = new()
351 AceEvent_debugTable[event][obj].mem = 0
352 AceEvent_debugTable[event][obj].time = 0
353 AceEvent_debugTable[event][obj].count = 0
354 end
355 if memdiff then
356 table.insert(memstack, memdiff)
357 table.insert(timestack, timediff)
358 end
359 memdiff, timediff = 0, 0
360 mem, time = gcinfo(), GetTime()
361 end
362 if type(method) == "string" then
363 local obj_method = obj[method]
364 if obj_method then
365 obj_method(obj, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
366 end
367 elseif method then -- function
368 method(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
369 end
370 if AceEvent_debugTable then
371 local dmem, dtime = memdiff, timediff
372 mem, time = gcinfo() - mem - memdiff, GetTime() - time - timediff
373 AceEvent_debugTable[event][obj].mem = AceEvent_debugTable[event][obj].mem + mem
374 AceEvent_debugTable[event][obj].time = AceEvent_debugTable[event][obj].time + time
375 AceEvent_debugTable[event][obj].count = AceEvent_debugTable[event][obj].count + 1
376  
377 memdiff, timediff = table.remove(memstack), table.remove(timestack)
378 if memdiff then
379 memdiff = memdiff + mem + dmem
380 timediff = timediff + time + dtime
381 end
382 end
383 tmp[obj] = nil
384 obj = next(tmp)
385 end
386 del(tmp)
387 end
388 _G.event = _G_event
389 end
390  
391 -- local accessors
392 local getn = table.getn
393 local tinsert = table.insert
394 local tremove = table.remove
395 local floor = math.floor
396 local GetTime = GetTime
397 local next = next
398 local pairs = pairs
399 local unpack = unpack
400  
401 local delayRegistry
402 local function OnUpdate()
403 local t = GetTime()
404 local k,v = next(delayRegistry)
405 local last = nil
406 while k do
407 local v_time = v.time
408 if not v_time then
409 delayRegistry[k] = del(v)
410 elseif v_time <= t then
411 local v_repeatDelay = v.repeatDelay
412 if v_repeatDelay then
413 -- use the event time, not the current time, else timing inaccuracies add up over time
414 v.time = v_time + v_repeatDelay
415 end
416 local event = v.event
417 local mem, time
418 if AceEvent_debugTable then
419 mem, time = gcinfo(), GetTime()
420 end
421 if type(event) == "function" then
422 event(unpack(v))
423 else
424 AceEvent:TriggerEvent(event, unpack(v))
425 end
426 if AceEvent_debugTable then
427 mem, time = gcinfo() - mem, GetTime() - time
428 v.mem = v.mem + mem
429 v.timeSpent = v.timeSpent + time
430 v.count = v.count + 1
431 end
432 if not v_repeatDelay then
433 local x = delayRegistry[k]
434 if x and x.time == v_time then -- check if it was manually reset
435 delayRegistry[k] = del(v)
436 end
437 end
438 end
439 if delayRegistry[k] then
440 last = k
441 end
442 k,v = next(delayRegistry, last)
443 end
444 if not next(delayRegistry) then
445 AceEvent.frame:Hide()
446 end
447 end
448  
449 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)
450 local id
451 if type(event) == "string" or type(event) == "table" then
452 if type(event) == "table" then
453 if not delayRegistry or not delayRegistry[event] then
454 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
455 end
456 end
457 if type(delay) ~= "number" then
458 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
459 AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
460 AceEvent:argCheck(delay, 4, "number")
461 self:CancelScheduledEvent(id)
462 end
463 else
464 AceEvent:argCheck(event, 2, "string", "function")
465 AceEvent:argCheck(delay, 3, "number")
466 end
467  
468 if not delayRegistry then
469 AceEvent.delayRegistry = new()
470 delayRegistry = AceEvent.delayRegistry
471 AceEvent.frame:SetScript("OnUpdate", OnUpdate)
472 end
473 local t
474 if type(id) == "table" then
475 for k in pairs(id) do
476 id[k] = nil
477 end
478 t = id
479 else
480 t = new()
481 end
482 t[1] = a1
483 t[2] = a2
484 t[3] = a3
485 t[4] = a4
486 t[5] = a5
487 t[6] = a6
488 t[7] = a7
489 t[8] = a8
490 t[9] = a9
491 t[10] = a10
492 t[11] = a11
493 t[12] = a12
494 t[13] = a13
495 t[14] = a14
496 t[15] = a15
497 t[16] = a16
498 t[17] = a17
499 t[18] = a18
500 t[19] = a19
501 t[20] = a20
502 table_setn(t, 20)
503 t.event = event
504 t.time = GetTime() + delay
505 t.self = self
506 t.id = id or t
507 t.repeatDelay = repeating and delay
508 if AceEvent_debugTable then
509 t.mem = 0
510 t.count = 0
511 t.timeSpent = 0
512 end
513 delayRegistry[t.id] = t
514 AceEvent.frame:Show()
515 return t.id
516 end
517  
518 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)
519 if type(event) == "string" or type(event) == "table" then
520 if type(event) == "table" then
521 if not delayRegistry or not delayRegistry[event] then
522 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
523 end
524 end
525 if type(delay) ~= "number" then
526 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
527 AceEvent:argCheck(a1, 4, "number")
528 end
529 else
530 AceEvent:argCheck(event, 2, "string", "function")
531 AceEvent:argCheck(delay, 3, "number")
532 end
533  
534 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)
535 end
536  
537 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)
538 if type(event) == "string" or type(event) == "table" then
539 if type(event) == "table" then
540 if not delayRegistry or not delayRegistry[event] then
541 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
542 end
543 end
544 if type(delay) ~= "number" then
545 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
546 AceEvent:argCheck(a1, 4, "number")
547 end
548 else
549 AceEvent:argCheck(event, 2, "string", "function")
550 AceEvent:argCheck(delay, 3, "number")
551 end
552  
553 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)
554 end
555  
556 function AceEvent:CancelScheduledEvent(t)
557 AceEvent:argCheck(t, 2, "string", "table")
558 if delayRegistry then
559 local v = delayRegistry[t]
560 if v then
561 delayRegistry[t] = del(v)
562 if not next(delayRegistry) then
563 AceEvent.frame:Hide()
564 end
565 return true
566 end
567 end
568 return false
569 end
570  
571 function AceEvent:IsEventScheduled(t)
572 AceEvent:argCheck(t, 2, "string", "table")
573 if delayRegistry then
574 local v = delayRegistry[t]
575 if v then
576 return true, v.time - GetTime()
577 end
578 end
579 return false, nil
580 end
581  
582 function AceEvent:UnregisterEvent(event)
583 AceEvent:argCheck(event, 2, "string")
584 local AceEvent_registry = AceEvent.registry
585 if AceEvent_registry[event] and AceEvent_registry[event][self] then
586 AceEvent_registry[event][self] = nil
587 local AceEvent_onceRegistry = AceEvent.onceRegistry
588 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
589 AceEvent_onceRegistry[event][self] = nil
590 if not next(AceEvent_onceRegistry[event]) then
591 AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
592 end
593 end
594 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
595 if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
596 AceEvent_throttleRegistry[event][self] = del(AceEvent_throttleRegistry[event][self])
597 if not next(AceEvent_throttleRegistry[event]) then
598 AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
599 end
600 end
601 if not next(AceEvent_registry[event]) then
602 AceEvent_registry[event] = del(AceEvent_registry[event])
603 if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
604 AceEvent.frame:UnregisterEvent(event)
605 end
606 end
607 else
608 if self == AceEvent then
609 error(string.format("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0.", event), 2)
610 else
611 AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
612 end
613 end
614 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
615 end
616  
617 function AceEvent:UnregisterAllEvents()
618 local AceEvent_registry = AceEvent.registry
619 if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
620 AceEvent_registry[ALL_EVENTS][self] = nil
621 if not next(AceEvent_registry[ALL_EVENTS]) then
622 del(AceEvent_registry[ALL_EVENTS])
623 AceEvent.frame:UnregisterAllEvents()
624 for k,v in pairs(AceEvent_registry) do
625 if k ~= ALL_EVENTS then
626 AceEvent.frame:RegisterEvent(k)
627 end
628 end
629 AceEvent_registry[event] = nil
630 end
631 end
632 local first = true
633 for event, data in pairs(AceEvent_registry) do
634 if first then
635 if AceEvent_registry.AceEvent_EventUnregistered then
636 event = "AceEvent_EventUnregistered"
637 else
638 first = false
639 end
640 end
641 local x = data[self]
642 data[self] = nil
643 if x and event ~= ALL_EVENTS then
644 if not next(data) then
645 del(data)
646 if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
647 AceEvent.frame:UnregisterEvent(event)
648 end
649 AceEvent_registry[event] = nil
650 end
651 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
652 end
653 if first then
654 event = nil
655 end
656 end
657 if AceEvent.onceRegistry then
658 for event, data in pairs(AceEvent.onceRegistry) do
659 data[self] = nil
660 end
661 end
662 end
663  
664 function AceEvent:CancelAllScheduledEvents()
665 if delayRegistry then
666 for k,v in pairs(delayRegistry) do
667 if v.self == self then
668 delayRegistry[k] = del(v)
669 end
670 end
671 if not next(delayRegistry) then
672 AceEvent.frame:Hide()
673 end
674 end
675 end
676  
677 function AceEvent:IsEventRegistered(event)
678 AceEvent:argCheck(event, 2, "string")
679 local AceEvent_registry = AceEvent.registry
680 if self == AceEvent then
681 return AceEvent_registry[event] and next(AceEvent_registry[event]) and true or false
682 end
683 if AceEvent_registry[event] and AceEvent_registry[event][self] then
684 return true, AceEvent_registry[event][self]
685 end
686 return false, nil
687 end
688  
689 local bucketfunc
690 function AceEvent:RegisterBucketEvent(event, delay, method)
691 AceEvent:argCheck(event, 2, "string", "table")
692 if type(event) == "table" then
693 for k,v in pairs(event) do
694 if type(k) ~= "number" then
695 AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
696 elseif type(v) ~= "string" then
697 AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
698 end
699 end
700 end
701 AceEvent:argCheck(delay, 3, "number")
702 if AceEvent == self then
703 AceEvent:argCheck(method, 4, "function")
704 self = method
705 else
706 if type(event) == "string" then
707 AceEvent:argCheck(method, 4, "string", "function", "nil")
708 if not method then
709 method = event
710 end
711 else
712 AceEvent:argCheck(method, 4, "string", "function")
713 end
714  
715 if type(method) == "string" and type(self[method]) ~= "function" then
716 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
717 end
718 end
719 if not AceEvent.buckets then
720 AceEvent.buckets = new()
721 end
722 if not AceEvent.buckets[event] then
723 AceEvent.buckets[event] = new()
724 end
725 if not AceEvent.buckets[event][self] then
726 AceEvent.buckets[event][self] = new()
727 AceEvent.buckets[event][self].current = new()
728 AceEvent.buckets[event][self].self = self
729 else
730 AceEvent.CancelScheduledEvent(self, AceEvent.buckets[event][self].id)
731 end
732 local bucket = AceEvent.buckets[event][self]
733 bucket.method = method
734  
735 local func = function(arg1)
736 bucket.run = true
737 if arg1 then
738 bucket.current[arg1] = true
739 end
740 end
741 AceEvent.buckets[event][self].func = func
742 if type(event) == "string" then
743 AceEvent.RegisterEvent(self, event, func)
744 else
745 for _,v in ipairs(event) do
746 AceEvent.RegisterEvent(self, v, func)
747 end
748 end
749 if not bucketfunc then
750 bucketfunc = function(bucket)
751 local current = bucket.current
752 local method = bucket.method
753 local self = bucket.self
754 if bucket.run then
755 if type(method) == "string" then
756 self[method](self, current)
757 elseif method then -- function
758 method(current)
759 end
760 for k in pairs(current) do
761 current[k] = nil
762 k = nil
763 end
764 bucket.run = false
765 end
766 end
767 end
768 bucket.id = AceEvent.ScheduleRepeatingEvent(self, bucketfunc, delay, bucket)
769 end
770  
771 function AceEvent:IsBucketEventRegistered(event)
772 AceEvent:argCheck(event, 2, "string", "table")
773 return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
774 end
775  
776 function AceEvent:UnregisterBucketEvent(event)
777 AceEvent:argCheck(event, 2, "string", "table")
778 if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
779 AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
780 end
781  
782 local bucket = AceEvent.buckets[event][self]
783  
784 if type(event) == "string" then
785 AceEvent.UnregisterEvent(self, event)
786 else
787 for _,v in ipairs(event) do
788 AceEvent.UnregisterEvent(self, v)
789 end
790 end
791 AceEvent:CancelScheduledEvent(bucket.id)
792  
793 del(bucket.current)
794 AceEvent.buckets[event][self] = del(AceEvent.buckets[event][self])
795 if not next(AceEvent.buckets[event]) then
796 AceEvent.buckets[event] = del(AceEvent.buckets[event])
797 end
798 end
799  
800 function AceEvent:UnregisterAllBucketEvents()
801 if not AceEvent.buckets or not next(AceEvent.buckets) then
802 return
803 end
804 for k,v in pairs(AceEvent.buckets) do
805 if v == self then
806 AceEvent.UnregisterBucketEvent(self, k)
807 k = nil
808 end
809 end
810 end
811  
812 function AceEvent:OnEmbedDisable(target)
813 self.UnregisterAllEvents(target)
814  
815 self.CancelAllScheduledEvents(target)
816  
817 self.UnregisterAllBucketEvents(target)
818 end
819  
820 function AceEvent:EnableDebugging()
821 if not self.debugTable then
822 self.debugTable = new()
823  
824 if delayRegistry then
825 for k,v in pairs(self.delayRegistry) do
826 if not v.mem then
827 v.mem = 0
828 v.count = 0
829 v.timeSpent = 0
830 end
831 end
832 end
833 end
834 end
835  
836 function AceEvent:IsFullyInitialized()
837 return self.postInit or false
838 end
839  
840 function AceEvent:IsPostPlayerLogin()
841 return self.playerLogin or false
842 end
843  
844 function AceEvent:activate(oldLib, oldDeactivate)
845 AceEvent = self
846  
847 if oldLib then
848 self.onceRegistry = oldLib.onceRegistry
849 self.throttleRegistry = oldLib.throttleRegistry
850 self.delayRegistry = oldLib.delayRegistry
851 self.buckets = oldLib.buckets
852 self.registry = oldLib.registry
853 self.frame = oldLib.frame
854 self.debugTable = oldLib.debugTable
855 self.playerLogin = oldLib.pew or DEFAULT_CHAT_FRAME and DEFAULT_CHAT_FRAME.defaultLanguage and true
856 self.postInit = oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
857 self.ALL_EVENTS = oldLib.ALL_EVENTS
858 self.FAKE_NIL = oldLib.FAKE_NIL
859 self.RATE = oldLib.RATE
860 end
861 if not self.registry then
862 self.registry = {}
863 end
864 if not self.frame then
865 self.frame = CreateFrame("Frame", "AceEvent20Frame")
866 end
867 if not self.ALL_EVENTS then
868 self.ALL_EVENTS = {}
869 end
870 if not self.FAKE_NIL then
871 self.FAKE_NIL = {}
872 end
873 if not self.RATE then
874 self.RATE = {}
875 end
876 ALL_EVENTS = self.ALL_EVENTS
877 FAKE_NIL = self.FAKE_NIL
878 RATE = self.RATE
879 local inPlw = false
880 local blacklist = {
881 UNIT_INVENTORY_CHANGED = true,
882 BAG_UPDATE = true,
883 ITEM_LOCK_CHANGED = true,
884 ACTIONBAR_SLOT_CHANGED = true,
885 }
886 self.frame:SetScript("OnEvent", function()
887 local event = event
888 if event == "PLAYER_ENTERING_WORLD" then
889 inPlw = false
890 elseif event == "PLAYER_LEAVING_WORLD" then
891 inPlw = true
892 end
893 if event and (not inPlw or not blacklist[event]) then
894 self:TriggerEvent(event, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
895 end
896 end)
897 if self.delayRegistry then
898 delayRegistry = self.delayRegistry
899 self.frame:SetScript("OnUpdate", OnUpdate)
900 end
901  
902 self:UnregisterAllEvents()
903 self:CancelAllScheduledEvents()
904  
905 registeringFromAceEvent = true
906 self:RegisterEvent("LOOT_OPENED", function()
907 SendAddonMessage("LOOT_OPENED", "", "RAID")
908 end)
909 registeringFromAceEvent = nil
910  
911 if not self.playerLogin then
912 registeringFromAceEvent = true
913 self:RegisterEvent("PLAYER_LOGIN", function()
914 self.playerLogin = true
915 end, true)
916 registeringFromAceEvent = nil
917 end
918  
919 if not self.postInit then
920 local isReload = true
921 local function func()
922 self.postInit = true
923 self:TriggerEvent("AceEvent_FullyInitialized")
924 if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
925 self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
926 end
927 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
928 self:UnregisterEvent("MEETINGSTONE_CHANGED")
929 end
930 if self.registry["MINIMAP_ZONE_CHANGED"] and self.registry["MINIMAP_ZONE_CHANGED"][self] then
931 self:UnregisterEvent("MINIMAP_ZONE_CHANGED")
932 end
933 if self.registry["LANGUAGE_LIST_CHANGED"] and self.registry["LANGUAGE_LIST_CHANGED"][self] then
934 self:UnregisterEvent("LANGUAGE_LIST_CHANGED")
935 end
936 end
937 registeringFromAceEvent = true
938 local f = function()
939 self.playerLogin = true
940 self:ScheduleEvent("AceEvent_FullyInitialized", func, 1)
941 end
942 self:RegisterEvent("MEETINGSTONE_CHANGED", f, true)
943 self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function()
944 self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.05)
945 end)
946 self:RegisterEvent("LANGUAGE_LIST_CHANGED", function()
947 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
948 self:UnregisterEvent("MEETINGSTONE_CHANGED")
949 self:RegisterEvent("MINIMAP_ZONE_CHANGED", f, true)
950 end
951 end)
952 registeringFromAceEvent = nil
953 end
954  
955 self.super.activate(self, oldLib, oldDeactivate)
956 if oldLib then
957 oldDeactivate(oldLib)
958 end
959 end
960  
961 AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, AceEvent.activate)
962 AceEvent = AceLibrary(MAJOR_VERSION)