/libs/AceEvent-2.0/AceEvent-2.0.lua

http://vanillaguide.googlecode.com/ · Lua · 969 lines · 924 code · 30 blank · 15 comment · 138 complexity · e90bb29771c17c68975d06cfe70cf7ce MD5 · raw file

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