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