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