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