flickerstreak@28
|
1 --[[
|
flickerstreak@28
|
2 Name: AceEvent-2.0
|
flickerstreak@28
|
3 Revision: $Rev: 49307 $
|
flickerstreak@28
|
4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
|
flickerstreak@28
|
5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
|
flickerstreak@28
|
6 Website: http://www.wowace.com/
|
flickerstreak@28
|
7 Documentation: http://www.wowace.com/index.php/AceEvent-2.0
|
flickerstreak@28
|
8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceEvent-2.0
|
flickerstreak@28
|
9 Description: Mixin to allow for event handling, scheduling, and inter-addon
|
flickerstreak@28
|
10 communication.
|
flickerstreak@28
|
11 Dependencies: AceLibrary, AceOO-2.0
|
flickerstreak@28
|
12 License: LGPL v2.1
|
flickerstreak@28
|
13 ]]
|
flickerstreak@28
|
14
|
flickerstreak@28
|
15 local MAJOR_VERSION = "AceEvent-2.0"
|
flickerstreak@28
|
16 local MINOR_VERSION = "$Revision: 49307 $"
|
flickerstreak@28
|
17
|
flickerstreak@28
|
18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
|
flickerstreak@28
|
19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
|
flickerstreak@28
|
20
|
flickerstreak@28
|
21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
|
flickerstreak@28
|
22
|
flickerstreak@28
|
23 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
|
flickerstreak@28
|
24 local Mixin = AceOO.Mixin
|
flickerstreak@28
|
25 local AceEvent = Mixin {
|
flickerstreak@28
|
26 "RegisterEvent",
|
flickerstreak@28
|
27 "RegisterAllEvents",
|
flickerstreak@28
|
28 "UnregisterEvent",
|
flickerstreak@28
|
29 "UnregisterAllEvents",
|
flickerstreak@28
|
30 "TriggerEvent",
|
flickerstreak@28
|
31 "ScheduleEvent",
|
flickerstreak@28
|
32 "ScheduleRepeatingEvent",
|
flickerstreak@28
|
33 "CancelScheduledEvent",
|
flickerstreak@28
|
34 "CancelAllScheduledEvents",
|
flickerstreak@28
|
35 "IsEventRegistered",
|
flickerstreak@28
|
36 "IsEventScheduled",
|
flickerstreak@28
|
37 "RegisterBucketEvent",
|
flickerstreak@28
|
38 "UnregisterBucketEvent",
|
flickerstreak@28
|
39 "UnregisterAllBucketEvents",
|
flickerstreak@28
|
40 "IsBucketEventRegistered",
|
flickerstreak@28
|
41 "ScheduleLeaveCombatAction",
|
flickerstreak@28
|
42 "CancelAllCombatSchedules",
|
flickerstreak@28
|
43 }
|
flickerstreak@28
|
44
|
flickerstreak@28
|
45 local weakKey = {__mode="k"}
|
flickerstreak@28
|
46
|
flickerstreak@28
|
47 local FAKE_NIL
|
flickerstreak@28
|
48 local RATE
|
flickerstreak@28
|
49
|
flickerstreak@28
|
50 local eventsWhichHappenOnce = {
|
flickerstreak@28
|
51 PLAYER_LOGIN = true,
|
flickerstreak@28
|
52 AceEvent_FullyInitialized = true,
|
flickerstreak@28
|
53 VARIABLES_LOADED = true,
|
flickerstreak@28
|
54 PLAYER_LOGOUT = true,
|
flickerstreak@28
|
55 }
|
flickerstreak@28
|
56 local next = next
|
flickerstreak@28
|
57 local pairs = pairs
|
flickerstreak@28
|
58 local pcall = pcall
|
flickerstreak@28
|
59 local type = type
|
flickerstreak@28
|
60 local GetTime = GetTime
|
flickerstreak@28
|
61 local gcinfo = gcinfo
|
flickerstreak@28
|
62 local unpack = unpack
|
flickerstreak@28
|
63 local geterrorhandler = geterrorhandler
|
flickerstreak@28
|
64
|
flickerstreak@28
|
65 local build = GetBuildInfo()
|
flickerstreak@28
|
66 local useTablesAsIDs = build:find("^2%.0%.") or build:find("^2%.1%.") or build:find("^0%.1%.")
|
flickerstreak@28
|
67
|
flickerstreak@28
|
68 local new, del
|
flickerstreak@28
|
69 do
|
flickerstreak@28
|
70 local cache = setmetatable({}, {__mode='k'})
|
flickerstreak@28
|
71 function new(...)
|
flickerstreak@28
|
72 local t = next(cache)
|
flickerstreak@28
|
73 if t then
|
flickerstreak@28
|
74 cache[t] = nil
|
flickerstreak@28
|
75 for i = 1, select('#', ...) do
|
flickerstreak@28
|
76 t[i] = select(i, ...)
|
flickerstreak@28
|
77 end
|
flickerstreak@28
|
78 return t
|
flickerstreak@28
|
79 else
|
flickerstreak@28
|
80 return { ... }
|
flickerstreak@28
|
81 end
|
flickerstreak@28
|
82 end
|
flickerstreak@28
|
83 function del(t)
|
flickerstreak@28
|
84 for k in pairs(t) do
|
flickerstreak@28
|
85 t[k] = nil
|
flickerstreak@28
|
86 end
|
flickerstreak@28
|
87 cache[t] = true
|
flickerstreak@28
|
88 return nil
|
flickerstreak@28
|
89 end
|
flickerstreak@28
|
90 end
|
flickerstreak@28
|
91
|
flickerstreak@28
|
92 local registeringFromAceEvent
|
flickerstreak@28
|
93 --[[----------------------------------------------------------------------------------
|
flickerstreak@28
|
94 Notes:
|
flickerstreak@28
|
95 * Registers the addon with a Blizzard event or a custom AceEvent, which will cause the given method to be called when that is triggered.
|
flickerstreak@28
|
96 Arguments:
|
flickerstreak@28
|
97 string - name of the event to register
|
flickerstreak@28
|
98 [optional] string or function - name of the method or function to call. Default: same name as "event".
|
flickerstreak@28
|
99 [optional] boolean - whether to have method called only once. Default: false
|
flickerstreak@28
|
100 ------------------------------------------------------------------------------------]]
|
flickerstreak@28
|
101 function AceEvent:RegisterEvent(event, method, once)
|
flickerstreak@28
|
102 AceEvent:argCheck(event, 2, "string")
|
flickerstreak@28
|
103 if self == AceEvent and not registeringFromAceEvent then
|
flickerstreak@28
|
104 AceEvent:argCheck(method, 3, "function")
|
flickerstreak@28
|
105 self = method
|
flickerstreak@28
|
106 else
|
flickerstreak@28
|
107 AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number")
|
flickerstreak@28
|
108 if type(method) == "boolean" or type(method) == "number" then
|
flickerstreak@28
|
109 AceEvent:argCheck(once, 4, "nil")
|
flickerstreak@28
|
110 once, method = method, event
|
flickerstreak@28
|
111 end
|
flickerstreak@28
|
112 end
|
flickerstreak@28
|
113 AceEvent:argCheck(once, 4, "number", "boolean", "nil")
|
flickerstreak@28
|
114 if eventsWhichHappenOnce[event] then
|
flickerstreak@28
|
115 once = true
|
flickerstreak@28
|
116 end
|
flickerstreak@28
|
117 local throttleRate
|
flickerstreak@28
|
118 if type(once) == "number" then
|
flickerstreak@28
|
119 throttleRate, once = once
|
flickerstreak@28
|
120 end
|
flickerstreak@28
|
121 if not method then
|
flickerstreak@28
|
122 method = event
|
flickerstreak@28
|
123 end
|
flickerstreak@28
|
124 if type(method) == "string" and type(self[method]) ~= "function" then
|
flickerstreak@28
|
125 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
|
flickerstreak@28
|
126 else
|
flickerstreak@28
|
127 assert(type(method) == "function" or type(method) == "string")
|
flickerstreak@28
|
128 end
|
flickerstreak@28
|
129
|
flickerstreak@28
|
130 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
131 if not AceEvent_registry[event] then
|
flickerstreak@28
|
132 AceEvent_registry[event] = new()
|
flickerstreak@28
|
133 AceEvent.frame:RegisterEvent(event)
|
flickerstreak@28
|
134 end
|
flickerstreak@28
|
135
|
flickerstreak@28
|
136 local remember = true
|
flickerstreak@28
|
137 if AceEvent_registry[event][self] then
|
flickerstreak@28
|
138 remember = false
|
flickerstreak@28
|
139 end
|
flickerstreak@28
|
140 AceEvent_registry[event][self] = method
|
flickerstreak@28
|
141
|
flickerstreak@28
|
142 local AceEvent_onceRegistry = AceEvent.onceRegistry
|
flickerstreak@28
|
143 if once then
|
flickerstreak@28
|
144 if not AceEvent_onceRegistry then
|
flickerstreak@28
|
145 AceEvent.onceRegistry = {}
|
flickerstreak@28
|
146 AceEvent_onceRegistry = AceEvent.onceRegistry
|
flickerstreak@28
|
147 end
|
flickerstreak@28
|
148 if not AceEvent_onceRegistry[event] then
|
flickerstreak@28
|
149 AceEvent_onceRegistry[event] = new()
|
flickerstreak@28
|
150 end
|
flickerstreak@28
|
151 AceEvent_onceRegistry[event][self] = true
|
flickerstreak@28
|
152 else
|
flickerstreak@28
|
153 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
|
flickerstreak@28
|
154 AceEvent_onceRegistry[event][self] = nil
|
flickerstreak@28
|
155 if not next(AceEvent_onceRegistry[event]) then
|
flickerstreak@28
|
156 AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
|
flickerstreak@28
|
157 end
|
flickerstreak@28
|
158 end
|
flickerstreak@28
|
159 end
|
flickerstreak@28
|
160
|
flickerstreak@28
|
161 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
flickerstreak@28
|
162 if throttleRate then
|
flickerstreak@28
|
163 if not AceEvent_throttleRegistry then
|
flickerstreak@28
|
164 AceEvent.throttleRegistry = {}
|
flickerstreak@28
|
165 AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
flickerstreak@28
|
166 end
|
flickerstreak@28
|
167 if not AceEvent_throttleRegistry[event] then
|
flickerstreak@28
|
168 AceEvent_throttleRegistry[event] = new()
|
flickerstreak@28
|
169 end
|
flickerstreak@28
|
170 if AceEvent_throttleRegistry[event][self] then
|
flickerstreak@28
|
171 AceEvent_throttleRegistry[event][self] = nil
|
flickerstreak@28
|
172 end
|
flickerstreak@28
|
173 AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey)
|
flickerstreak@28
|
174 local t = AceEvent_throttleRegistry[event][self]
|
flickerstreak@28
|
175 t[RATE] = throttleRate
|
flickerstreak@28
|
176 else
|
flickerstreak@28
|
177 if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then
|
flickerstreak@28
|
178 if AceEvent_throttleRegistry[event][self] then
|
flickerstreak@28
|
179 AceEvent_throttleRegistry[event][self] = nil
|
flickerstreak@28
|
180 end
|
flickerstreak@28
|
181 if not next(AceEvent_throttleRegistry[event]) then
|
flickerstreak@28
|
182 AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
|
flickerstreak@28
|
183 end
|
flickerstreak@28
|
184 end
|
flickerstreak@28
|
185 end
|
flickerstreak@28
|
186
|
flickerstreak@28
|
187 if remember then
|
flickerstreak@28
|
188 AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event)
|
flickerstreak@28
|
189 end
|
flickerstreak@28
|
190 end
|
flickerstreak@28
|
191
|
flickerstreak@28
|
192 local ALL_EVENTS
|
flickerstreak@28
|
193
|
flickerstreak@28
|
194 --[[----------------------------------------------------------------------------------
|
flickerstreak@28
|
195 Notes:
|
flickerstreak@28
|
196 * Registers all events to the given method
|
flickerstreak@28
|
197 * To access the current event, check AceEvent.currentEvent
|
flickerstreak@28
|
198 * To access the current event's unique identifier, check AceEvent.currentEventUID
|
flickerstreak@28
|
199 * This is only for debugging purposes.
|
flickerstreak@28
|
200 Arguments:
|
flickerstreak@28
|
201 [optional] string or function - name of the method or function to call. Default: same name as "event".
|
flickerstreak@28
|
202 ------------------------------------------------------------------------------------]]
|
flickerstreak@28
|
203 function AceEvent:RegisterAllEvents(method)
|
flickerstreak@28
|
204 if self == AceEvent then
|
flickerstreak@28
|
205 AceEvent:argCheck(method, 1, "function")
|
flickerstreak@28
|
206 self = method
|
flickerstreak@28
|
207 else
|
flickerstreak@28
|
208 AceEvent:argCheck(method, 1, "string", "function")
|
flickerstreak@28
|
209 if type(method) == "string" and type(self[method]) ~= "function" then
|
flickerstreak@28
|
210 AceEvent:error("Cannot register all events to method %q, it does not exist", method)
|
flickerstreak@28
|
211 end
|
flickerstreak@28
|
212 end
|
flickerstreak@28
|
213
|
flickerstreak@28
|
214 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
215 if not AceEvent_registry[ALL_EVENTS] then
|
flickerstreak@28
|
216 AceEvent_registry[ALL_EVENTS] = new()
|
flickerstreak@28
|
217 AceEvent.frame:RegisterAllEvents()
|
flickerstreak@28
|
218 end
|
flickerstreak@28
|
219
|
flickerstreak@28
|
220 local remember = not AceEvent_registry[ALL_EVENTS][self]
|
flickerstreak@28
|
221 AceEvent_registry[ALL_EVENTS][self] = method
|
flickerstreak@28
|
222 if remember then
|
flickerstreak@28
|
223 AceEvent:TriggerEvent("AceEvent_EventRegistered", self, "all")
|
flickerstreak@28
|
224 end
|
flickerstreak@28
|
225 end
|
flickerstreak@28
|
226
|
flickerstreak@28
|
227 --[[----------------------------------------------------------------------------------
|
flickerstreak@28
|
228 Notes:
|
flickerstreak@28
|
229 * Trigger a custom AceEvent.
|
flickerstreak@28
|
230 * This should never be called to simulate fake Blizzard events.
|
flickerstreak@28
|
231 * Custom events should be in the form of AddonName_SpecificEvent
|
flickerstreak@28
|
232 Arguments:
|
flickerstreak@28
|
233 string - name of the event
|
flickerstreak@28
|
234 tuple - list of arguments to pass along
|
flickerstreak@28
|
235 ------------------------------------------------------------------------------------]]
|
flickerstreak@28
|
236 function AceEvent:TriggerEvent(event, ...)
|
flickerstreak@28
|
237 if type(event) ~= "string" then
|
flickerstreak@28
|
238 DEFAULT_CHAT_FRAME:AddMessage(debugstack())
|
flickerstreak@28
|
239 end
|
flickerstreak@28
|
240 AceEvent:argCheck(event, 2, "string")
|
flickerstreak@28
|
241 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
242 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
|
flickerstreak@28
|
243 return
|
flickerstreak@28
|
244 end
|
flickerstreak@28
|
245 local lastEvent = AceEvent.currentEvent
|
flickerstreak@28
|
246 AceEvent.currentEvent = event
|
flickerstreak@28
|
247 local lastEventUID = AceEvent.currentEventUID
|
flickerstreak@28
|
248 local uid = AceEvent.UID_NUM + 1
|
flickerstreak@28
|
249 AceEvent.UID_NUM = uid
|
flickerstreak@28
|
250 AceEvent.currentEventUID = uid
|
flickerstreak@28
|
251
|
flickerstreak@28
|
252 local tmp = new()
|
flickerstreak@28
|
253
|
flickerstreak@28
|
254 local AceEvent_onceRegistry = AceEvent.onceRegistry
|
flickerstreak@28
|
255 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then
|
flickerstreak@28
|
256 for obj, method in pairs(AceEvent_onceRegistry[event]) do
|
flickerstreak@28
|
257 tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil
|
flickerstreak@28
|
258 end
|
flickerstreak@28
|
259 local obj = next(tmp)
|
flickerstreak@28
|
260 while obj do
|
flickerstreak@28
|
261 local method = tmp[obj]
|
flickerstreak@28
|
262 AceEvent.UnregisterEvent(obj, event)
|
flickerstreak@28
|
263 if type(method) == "string" then
|
flickerstreak@28
|
264 local obj_method = obj[method]
|
flickerstreak@28
|
265 if obj_method then
|
flickerstreak@28
|
266 local success, err = pcall(obj_method, obj, ...)
|
flickerstreak@28
|
267 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
268 end
|
flickerstreak@28
|
269 elseif method then -- function
|
flickerstreak@28
|
270 local success, err = pcall(method, ...)
|
flickerstreak@28
|
271 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
272 end
|
flickerstreak@28
|
273 tmp[obj] = nil
|
flickerstreak@28
|
274 obj = next(tmp)
|
flickerstreak@28
|
275 end
|
flickerstreak@28
|
276 end
|
flickerstreak@28
|
277
|
flickerstreak@28
|
278 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
flickerstreak@28
|
279 local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event]
|
flickerstreak@28
|
280 if AceEvent_registry[event] then
|
flickerstreak@28
|
281 for obj, method in pairs(AceEvent_registry[event]) do
|
flickerstreak@28
|
282 tmp[obj] = method
|
flickerstreak@28
|
283 end
|
flickerstreak@28
|
284 local obj = next(tmp)
|
flickerstreak@28
|
285 while obj do
|
flickerstreak@28
|
286 local method = tmp[obj]
|
flickerstreak@28
|
287 local continue = false
|
flickerstreak@28
|
288 if throttleTable and throttleTable[obj] then
|
flickerstreak@28
|
289 local a1 = ...
|
flickerstreak@28
|
290 if a1 == nil then
|
flickerstreak@28
|
291 a1 = FAKE_NIL
|
flickerstreak@28
|
292 end
|
flickerstreak@28
|
293 if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then
|
flickerstreak@28
|
294 throttleTable[obj][a1] = GetTime()
|
flickerstreak@28
|
295 else
|
flickerstreak@28
|
296 continue = true
|
flickerstreak@28
|
297 end
|
flickerstreak@28
|
298 end
|
flickerstreak@28
|
299 if not continue then
|
flickerstreak@28
|
300 if type(method) == "string" then
|
flickerstreak@28
|
301 local obj_method = obj[method]
|
flickerstreak@28
|
302 if obj_method then
|
flickerstreak@28
|
303 local success, err = pcall(obj_method, obj, ...)
|
flickerstreak@28
|
304 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
305 end
|
flickerstreak@28
|
306 elseif method then -- function
|
flickerstreak@28
|
307 local success, err = pcall(method, ...)
|
flickerstreak@28
|
308 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
309 end
|
flickerstreak@28
|
310 end
|
flickerstreak@28
|
311 tmp[obj] = nil
|
flickerstreak@28
|
312 obj = next(tmp)
|
flickerstreak@28
|
313 end
|
flickerstreak@28
|
314 end
|
flickerstreak@28
|
315 if AceEvent_registry[ALL_EVENTS] then
|
flickerstreak@28
|
316 for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do
|
flickerstreak@28
|
317 tmp[obj] = method
|
flickerstreak@28
|
318 end
|
flickerstreak@28
|
319 local obj = next(tmp)
|
flickerstreak@28
|
320 while obj do
|
flickerstreak@28
|
321 local method = tmp[obj]
|
flickerstreak@28
|
322 if type(method) == "string" then
|
flickerstreak@28
|
323 local obj_method = obj[method]
|
flickerstreak@28
|
324 if obj_method then
|
flickerstreak@28
|
325 local success, err = pcall(obj_method, obj, ...)
|
flickerstreak@28
|
326 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
327 end
|
flickerstreak@28
|
328 elseif method then -- function
|
flickerstreak@28
|
329 local success, err = pcall(method, ...)
|
flickerstreak@28
|
330 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
331 end
|
flickerstreak@28
|
332 tmp[obj] = nil
|
flickerstreak@28
|
333 obj = next(tmp)
|
flickerstreak@28
|
334 end
|
flickerstreak@28
|
335 end
|
flickerstreak@28
|
336 tmp = del(tmp)
|
flickerstreak@28
|
337 AceEvent.currentEvent = lastEvent
|
flickerstreak@28
|
338 AceEvent.currentEventUID = lastEventUID
|
flickerstreak@28
|
339 end
|
flickerstreak@28
|
340
|
flickerstreak@28
|
341 local delayRegistry
|
flickerstreak@28
|
342 local OnUpdate
|
flickerstreak@28
|
343 do
|
flickerstreak@28
|
344 local tmp = {}
|
flickerstreak@28
|
345 OnUpdate = function()
|
flickerstreak@28
|
346 local t = GetTime()
|
flickerstreak@28
|
347 for k,v in pairs(delayRegistry) do
|
flickerstreak@28
|
348 tmp[k] = true
|
flickerstreak@28
|
349 end
|
flickerstreak@28
|
350 for k in pairs(tmp) do
|
flickerstreak@28
|
351 local v = delayRegistry[k]
|
flickerstreak@28
|
352 if v then
|
flickerstreak@28
|
353 local v_time = v.time
|
flickerstreak@28
|
354 if not v_time then
|
flickerstreak@28
|
355 delayRegistry[k] = nil
|
flickerstreak@28
|
356 elseif v_time <= t then
|
flickerstreak@28
|
357 local v_repeatDelay = v.repeatDelay
|
flickerstreak@28
|
358 if v_repeatDelay then
|
flickerstreak@28
|
359 -- use the event time, not the current time, else timing inaccuracies add up over time
|
flickerstreak@28
|
360 v.time = v_time + v_repeatDelay
|
flickerstreak@28
|
361 end
|
flickerstreak@28
|
362 local event = v.event
|
flickerstreak@28
|
363 if type(event) == "function" then
|
flickerstreak@28
|
364 local uid = AceEvent.UID_NUM + 1
|
flickerstreak@28
|
365 AceEvent.UID_NUM = uid
|
flickerstreak@28
|
366 AceEvent.currentEventUID = uid
|
flickerstreak@28
|
367 local success, err = pcall(event, unpack(v, 1, v.n))
|
flickerstreak@28
|
368 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
369 AceEvent.currentEventUID = nil
|
flickerstreak@28
|
370 else
|
flickerstreak@28
|
371 AceEvent:TriggerEvent(event, unpack(v, 1, v.n))
|
flickerstreak@28
|
372 end
|
flickerstreak@28
|
373 if not v_repeatDelay then
|
flickerstreak@28
|
374 local x = delayRegistry[k]
|
flickerstreak@28
|
375 if x and x.time == v_time then -- check if it was manually reset
|
flickerstreak@28
|
376 if not useTablesAsIDs or type(k) == "string" then
|
flickerstreak@28
|
377 del(delayRegistry[k])
|
flickerstreak@28
|
378 end
|
flickerstreak@28
|
379 delayRegistry[k] = nil
|
flickerstreak@28
|
380 end
|
flickerstreak@28
|
381 end
|
flickerstreak@28
|
382 end
|
flickerstreak@28
|
383 end
|
flickerstreak@28
|
384 end
|
flickerstreak@28
|
385 for k in pairs(tmp) do
|
flickerstreak@28
|
386 tmp[k] = nil
|
flickerstreak@28
|
387 end
|
flickerstreak@28
|
388 if not next(delayRegistry) then
|
flickerstreak@28
|
389 AceEvent.frame:Hide()
|
flickerstreak@28
|
390 end
|
flickerstreak@28
|
391 end
|
flickerstreak@28
|
392 end
|
flickerstreak@28
|
393
|
flickerstreak@28
|
394 local function ScheduleEvent(self, repeating, event, delay, ...)
|
flickerstreak@28
|
395 local id
|
flickerstreak@28
|
396 if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then
|
flickerstreak@28
|
397 if useTablesAsIDs and type(event) == "table" then
|
flickerstreak@28
|
398 if not delayRegistry or not delayRegistry[event] then
|
flickerstreak@28
|
399 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
flickerstreak@28
|
400 end
|
flickerstreak@28
|
401 end
|
flickerstreak@28
|
402 if type(delay) ~= "number" then
|
flickerstreak@28
|
403 id, event, delay = event, delay, ...
|
flickerstreak@28
|
404 AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number")
|
flickerstreak@28
|
405 AceEvent:argCheck(delay, 4, "number")
|
flickerstreak@28
|
406 self:CancelScheduledEvent(id)
|
flickerstreak@28
|
407 end
|
flickerstreak@28
|
408 else
|
flickerstreak@28
|
409 AceEvent:argCheck(event, 2, "string", "function")
|
flickerstreak@28
|
410 AceEvent:argCheck(delay, 3, "number")
|
flickerstreak@28
|
411 end
|
flickerstreak@28
|
412
|
flickerstreak@28
|
413 if not delayRegistry then
|
flickerstreak@28
|
414 AceEvent.delayRegistry = {}
|
flickerstreak@28
|
415 delayRegistry = AceEvent.delayRegistry
|
flickerstreak@28
|
416 AceEvent.frame:SetScript("OnUpdate", OnUpdate)
|
flickerstreak@28
|
417 end
|
flickerstreak@28
|
418 local t
|
flickerstreak@28
|
419 if useTablesAsIDs and type(id) == "table" then
|
flickerstreak@28
|
420 for k in pairs(id) do
|
flickerstreak@28
|
421 id[k] = nil
|
flickerstreak@28
|
422 end
|
flickerstreak@28
|
423 t = id
|
flickerstreak@28
|
424 for i = 2, select('#', ...) do
|
flickerstreak@28
|
425 t[i-1] = select(i, ...)
|
flickerstreak@28
|
426 end
|
flickerstreak@28
|
427 t.n = select('#', ...) - 1
|
flickerstreak@28
|
428 elseif id then
|
flickerstreak@28
|
429 t = new(select(2, ...))
|
flickerstreak@28
|
430 t.n = select('#', ...) - 1
|
flickerstreak@28
|
431 else
|
flickerstreak@28
|
432 t = new(...)
|
flickerstreak@28
|
433 t.n = select('#', ...)
|
flickerstreak@28
|
434 end
|
flickerstreak@28
|
435 t.event = event
|
flickerstreak@28
|
436 t.time = GetTime() + delay
|
flickerstreak@28
|
437 t.self = self
|
flickerstreak@28
|
438 t.id = id or t
|
flickerstreak@28
|
439 t.repeatDelay = repeating and delay
|
flickerstreak@28
|
440 delayRegistry[t.id] = t
|
flickerstreak@28
|
441 AceEvent.frame:Show()
|
flickerstreak@28
|
442 if useTablesAsIDs then
|
flickerstreak@28
|
443 return t.id
|
flickerstreak@28
|
444 else
|
flickerstreak@28
|
445 return
|
flickerstreak@28
|
446 end
|
flickerstreak@28
|
447 end
|
flickerstreak@28
|
448
|
flickerstreak@28
|
449 --[[----------------------------------------------------------------------------------
|
flickerstreak@28
|
450 Notes:
|
flickerstreak@28
|
451 * Schedule an event to fire.
|
flickerstreak@28
|
452 * To fire on the next frame, specify a delay of 0.
|
flickerstreak@28
|
453 Arguments:
|
flickerstreak@28
|
454 string or function - name of the event to fire, or a function to call.
|
flickerstreak@28
|
455 number - the amount of time to wait until calling.
|
flickerstreak@28
|
456 tuple - a list of arguments to pass along.
|
flickerstreak@28
|
457 ------------------------------------------------------------------------------------]]
|
flickerstreak@28
|
458 function AceEvent:ScheduleEvent(event, delay, ...)
|
flickerstreak@28
|
459 if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then
|
flickerstreak@28
|
460 if useTablesAsIDs and type(event) == "table" then
|
flickerstreak@28
|
461 if not delayRegistry or not delayRegistry[event] then
|
flickerstreak@28
|
462 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
flickerstreak@28
|
463 end
|
flickerstreak@28
|
464 end
|
flickerstreak@28
|
465 if type(delay) ~= "number" then
|
flickerstreak@28
|
466 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
|
flickerstreak@28
|
467 AceEvent:argCheck(..., 4, "number")
|
flickerstreak@28
|
468 end
|
flickerstreak@28
|
469 else
|
flickerstreak@28
|
470 AceEvent:argCheck(event, 2, "string", "function")
|
flickerstreak@28
|
471 AceEvent:argCheck(delay, 3, "number")
|
flickerstreak@28
|
472 end
|
flickerstreak@28
|
473
|
flickerstreak@28
|
474 return ScheduleEvent(self, false, event, delay, ...)
|
flickerstreak@28
|
475 end
|
flickerstreak@28
|
476
|
flickerstreak@28
|
477 function AceEvent:ScheduleRepeatingEvent(event, delay, ...)
|
flickerstreak@28
|
478 if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then
|
flickerstreak@28
|
479 if useTablesAsIDs and type(event) == "table" then
|
flickerstreak@28
|
480 if not delayRegistry or not delayRegistry[event] then
|
flickerstreak@28
|
481 AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.")
|
flickerstreak@28
|
482 end
|
flickerstreak@28
|
483 end
|
flickerstreak@28
|
484 if type(delay) ~= "number" then
|
flickerstreak@28
|
485 AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number")
|
flickerstreak@28
|
486 AceEvent:argCheck(..., 4, "number")
|
flickerstreak@28
|
487 end
|
flickerstreak@28
|
488 else
|
flickerstreak@28
|
489 AceEvent:argCheck(event, 2, "string", "function")
|
flickerstreak@28
|
490 AceEvent:argCheck(delay, 3, "number")
|
flickerstreak@28
|
491 end
|
flickerstreak@28
|
492
|
flickerstreak@28
|
493 return ScheduleEvent(self, true, event, delay, ...)
|
flickerstreak@28
|
494 end
|
flickerstreak@28
|
495
|
flickerstreak@28
|
496 function AceEvent:CancelScheduledEvent(t)
|
flickerstreak@28
|
497 if useTablesAsIDs then
|
flickerstreak@28
|
498 AceEvent:argCheck(t, 2, "string", "table")
|
flickerstreak@28
|
499 else
|
flickerstreak@28
|
500 AceEvent:argCheck(t, 2, "string")
|
flickerstreak@28
|
501 end
|
flickerstreak@28
|
502 if delayRegistry then
|
flickerstreak@28
|
503 local v = delayRegistry[t]
|
flickerstreak@28
|
504 if v then
|
flickerstreak@28
|
505 if not useTablesAsIDs or type(t) == "string" then
|
flickerstreak@28
|
506 del(delayRegistry[t])
|
flickerstreak@28
|
507 end
|
flickerstreak@28
|
508 delayRegistry[t] = nil
|
flickerstreak@28
|
509 if not next(delayRegistry) then
|
flickerstreak@28
|
510 AceEvent.frame:Hide()
|
flickerstreak@28
|
511 end
|
flickerstreak@28
|
512 return true
|
flickerstreak@28
|
513 end
|
flickerstreak@28
|
514 end
|
flickerstreak@28
|
515 return false
|
flickerstreak@28
|
516 end
|
flickerstreak@28
|
517
|
flickerstreak@28
|
518 function AceEvent:IsEventScheduled(t)
|
flickerstreak@28
|
519 if useTablesAsIDs then
|
flickerstreak@28
|
520 AceEvent:argCheck(t, 2, "string", "table")
|
flickerstreak@28
|
521 else
|
flickerstreak@28
|
522 AceEvent:argCheck(t, 2, "string")
|
flickerstreak@28
|
523 end
|
flickerstreak@28
|
524 if delayRegistry then
|
flickerstreak@28
|
525 local v = delayRegistry[t]
|
flickerstreak@28
|
526 if v then
|
flickerstreak@28
|
527 return true, v.time - GetTime()
|
flickerstreak@28
|
528 end
|
flickerstreak@28
|
529 end
|
flickerstreak@28
|
530 return false, nil
|
flickerstreak@28
|
531 end
|
flickerstreak@28
|
532
|
flickerstreak@28
|
533 function AceEvent:UnregisterEvent(event)
|
flickerstreak@28
|
534 AceEvent:argCheck(event, 2, "string")
|
flickerstreak@28
|
535 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
536 if AceEvent_registry[event] and AceEvent_registry[event][self] then
|
flickerstreak@28
|
537 AceEvent_registry[event][self] = nil
|
flickerstreak@28
|
538 local AceEvent_onceRegistry = AceEvent.onceRegistry
|
flickerstreak@28
|
539 if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then
|
flickerstreak@28
|
540 AceEvent_onceRegistry[event][self] = nil
|
flickerstreak@28
|
541 if not next(AceEvent_onceRegistry[event]) then
|
flickerstreak@28
|
542 AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event])
|
flickerstreak@28
|
543 end
|
flickerstreak@28
|
544 end
|
flickerstreak@28
|
545 local AceEvent_throttleRegistry = AceEvent.throttleRegistry
|
flickerstreak@28
|
546 if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then
|
flickerstreak@28
|
547 AceEvent_throttleRegistry[event][self] = nil
|
flickerstreak@28
|
548 if not next(AceEvent_throttleRegistry[event]) then
|
flickerstreak@28
|
549 AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event])
|
flickerstreak@28
|
550 end
|
flickerstreak@28
|
551 end
|
flickerstreak@28
|
552 if not next(AceEvent_registry[event]) then
|
flickerstreak@28
|
553 AceEvent_registry[event] = del(AceEvent_registry[event])
|
flickerstreak@28
|
554 if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then
|
flickerstreak@28
|
555 AceEvent.frame:UnregisterEvent(event)
|
flickerstreak@28
|
556 end
|
flickerstreak@28
|
557 end
|
flickerstreak@28
|
558 else
|
flickerstreak@28
|
559 if self == AceEvent then
|
flickerstreak@28
|
560 error(("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0."):format(event), 2)
|
flickerstreak@28
|
561 else
|
flickerstreak@28
|
562 AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self)
|
flickerstreak@28
|
563 end
|
flickerstreak@28
|
564 end
|
flickerstreak@28
|
565 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
|
flickerstreak@28
|
566 end
|
flickerstreak@28
|
567
|
flickerstreak@28
|
568 function AceEvent:UnregisterAllEvents()
|
flickerstreak@28
|
569 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
570 if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
|
flickerstreak@28
|
571 AceEvent_registry[ALL_EVENTS][self] = nil
|
flickerstreak@28
|
572 if not next(AceEvent_registry[ALL_EVENTS]) then
|
flickerstreak@28
|
573 AceEvent_registry[ALL_EVENTS] = del(AceEvent_registry[ALL_EVENTS])
|
flickerstreak@28
|
574 AceEvent.frame:UnregisterAllEvents()
|
flickerstreak@28
|
575 for k,v in pairs(AceEvent_registry) do
|
flickerstreak@28
|
576 AceEvent.frame:RegisterEvent(k)
|
flickerstreak@28
|
577 end
|
flickerstreak@28
|
578 end
|
flickerstreak@28
|
579 end
|
flickerstreak@28
|
580 if AceEvent_registry.AceEvent_EventUnregistered then
|
flickerstreak@28
|
581 local event, data = "AceEvent_EventUnregistered", AceEvent_registry.AceEvent_EventUnregistered
|
flickerstreak@28
|
582 local x = data[self]
|
flickerstreak@28
|
583 data[self] = nil
|
flickerstreak@28
|
584 if x then
|
flickerstreak@28
|
585 if not next(data) then
|
flickerstreak@28
|
586 if not AceEvent_registry[ALL_EVENTS] then
|
flickerstreak@28
|
587 AceEvent.frame:UnregisterEvent(event)
|
flickerstreak@28
|
588 end
|
flickerstreak@28
|
589 AceEvent_registry[event] = del(AceEvent_registry[event])
|
flickerstreak@28
|
590 end
|
flickerstreak@28
|
591 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
|
flickerstreak@28
|
592 end
|
flickerstreak@28
|
593 end
|
flickerstreak@28
|
594 for event, data in pairs(AceEvent_registry) do
|
flickerstreak@28
|
595 local x = data[self]
|
flickerstreak@28
|
596 data[self] = nil
|
flickerstreak@28
|
597 if x and event ~= ALL_EVENTS then
|
flickerstreak@28
|
598 if not next(data) then
|
flickerstreak@28
|
599 if not AceEvent_registry[ALL_EVENTS] then
|
flickerstreak@28
|
600 AceEvent.frame:UnregisterEvent(event)
|
flickerstreak@28
|
601 end
|
flickerstreak@28
|
602 AceEvent_registry[event] = del(AceEvent_registry[event])
|
flickerstreak@28
|
603 end
|
flickerstreak@28
|
604 AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event)
|
flickerstreak@28
|
605 end
|
flickerstreak@28
|
606 end
|
flickerstreak@28
|
607 if AceEvent.onceRegistry then
|
flickerstreak@28
|
608 for event, data in pairs(AceEvent.onceRegistry) do
|
flickerstreak@28
|
609 data[self] = nil
|
flickerstreak@28
|
610 end
|
flickerstreak@28
|
611 end
|
flickerstreak@28
|
612 end
|
flickerstreak@28
|
613
|
flickerstreak@28
|
614 function AceEvent:CancelAllScheduledEvents()
|
flickerstreak@28
|
615 if delayRegistry then
|
flickerstreak@28
|
616 for k,v in pairs(delayRegistry) do
|
flickerstreak@28
|
617 if v.self == self then
|
flickerstreak@28
|
618 if not useTablesAsIDs or type(k) == "string" then
|
flickerstreak@28
|
619 del(delayRegistry[k])
|
flickerstreak@28
|
620 end
|
flickerstreak@28
|
621 delayRegistry[k] = nil
|
flickerstreak@28
|
622 end
|
flickerstreak@28
|
623 end
|
flickerstreak@28
|
624 if not next(delayRegistry) then
|
flickerstreak@28
|
625 AceEvent.frame:Hide()
|
flickerstreak@28
|
626 end
|
flickerstreak@28
|
627 end
|
flickerstreak@28
|
628 end
|
flickerstreak@28
|
629
|
flickerstreak@28
|
630 function AceEvent:IsEventRegistered(event)
|
flickerstreak@28
|
631 AceEvent:argCheck(event, 2, "string")
|
flickerstreak@28
|
632 local AceEvent_registry = AceEvent.registry
|
flickerstreak@28
|
633 if self == AceEvent then
|
flickerstreak@28
|
634 return AceEvent_registry[event] and next(AceEvent_registry[event]) or AceEvent_registry[ALL_EVENTS] and next(AceEvent_registry[ALL_EVENTS]) and true or false
|
flickerstreak@28
|
635 end
|
flickerstreak@28
|
636 if AceEvent_registry[event] and AceEvent_registry[event][self] then
|
flickerstreak@28
|
637 return true, AceEvent_registry[event][self]
|
flickerstreak@28
|
638 end
|
flickerstreak@28
|
639 if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then
|
flickerstreak@28
|
640 return true, AceEvent_registry[ALL_EVENTS][self]
|
flickerstreak@28
|
641 end
|
flickerstreak@28
|
642 return false, nil
|
flickerstreak@28
|
643 end
|
flickerstreak@28
|
644
|
flickerstreak@28
|
645 local UnitExists = UnitExists
|
flickerstreak@28
|
646 local bucketfunc
|
flickerstreak@28
|
647 function AceEvent:RegisterBucketEvent(event, delay, method, ...)
|
flickerstreak@28
|
648 AceEvent:argCheck(event, 2, "string", "table")
|
flickerstreak@28
|
649 if type(event) == "table" then
|
flickerstreak@28
|
650 for k,v in pairs(event) do
|
flickerstreak@28
|
651 if type(k) ~= "number" then
|
flickerstreak@28
|
652 AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.")
|
flickerstreak@28
|
653 elseif type(v) ~= "string" then
|
flickerstreak@28
|
654 AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.")
|
flickerstreak@28
|
655 end
|
flickerstreak@28
|
656 end
|
flickerstreak@28
|
657 end
|
flickerstreak@28
|
658 AceEvent:argCheck(delay, 3, "number")
|
flickerstreak@28
|
659 if AceEvent == self then
|
flickerstreak@28
|
660 AceEvent:argCheck(method, 4, "function")
|
flickerstreak@28
|
661 self = method
|
flickerstreak@28
|
662 else
|
flickerstreak@28
|
663 if type(event) == "string" then
|
flickerstreak@28
|
664 AceEvent:argCheck(method, 4, "string", "function", "nil")
|
flickerstreak@28
|
665 if not method then
|
flickerstreak@28
|
666 method = event
|
flickerstreak@28
|
667 end
|
flickerstreak@28
|
668 else
|
flickerstreak@28
|
669 AceEvent:argCheck(method, 4, "string", "function")
|
flickerstreak@28
|
670 end
|
flickerstreak@28
|
671
|
flickerstreak@28
|
672 if type(method) == "string" and type(self[method]) ~= "function" then
|
flickerstreak@28
|
673 AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method)
|
flickerstreak@28
|
674 end
|
flickerstreak@28
|
675 end
|
flickerstreak@28
|
676 local buckets = AceEvent.buckets
|
flickerstreak@28
|
677 if not buckets[event] then
|
flickerstreak@28
|
678 buckets[event] = new()
|
flickerstreak@28
|
679 end
|
flickerstreak@28
|
680 if not buckets[event][self] then
|
flickerstreak@28
|
681 local t = new()
|
flickerstreak@28
|
682 t.current = new()
|
flickerstreak@28
|
683 t.self = self
|
flickerstreak@28
|
684 buckets[event][self] = t
|
flickerstreak@28
|
685 else
|
flickerstreak@28
|
686 AceEvent.CancelScheduledEvent(self, buckets[event][self].id)
|
flickerstreak@28
|
687 end
|
flickerstreak@28
|
688 local bucket = buckets[event][self]
|
flickerstreak@28
|
689 bucket.method = method
|
flickerstreak@28
|
690
|
flickerstreak@28
|
691 local n = select('#', ...)
|
flickerstreak@28
|
692 if n > 0 then
|
flickerstreak@28
|
693 for i = 1, n do
|
flickerstreak@28
|
694 bucket[i] = select(i, ...)
|
flickerstreak@28
|
695 end
|
flickerstreak@28
|
696 end
|
flickerstreak@28
|
697 bucket.n = n
|
flickerstreak@28
|
698
|
flickerstreak@28
|
699 local func = function(arg1)
|
flickerstreak@28
|
700 bucket.run = true
|
flickerstreak@28
|
701 if arg1 then
|
flickerstreak@28
|
702 bucket.current[arg1] = true
|
flickerstreak@28
|
703 end
|
flickerstreak@28
|
704 end
|
flickerstreak@28
|
705 buckets[event][self].func = func
|
flickerstreak@28
|
706 local isUnitBucket = true
|
flickerstreak@28
|
707 if type(event) == "string" then
|
flickerstreak@28
|
708 AceEvent.RegisterEvent(self, event, func)
|
flickerstreak@28
|
709 if not event:find("^UNIT_") then
|
flickerstreak@28
|
710 isUnitBucket = false
|
flickerstreak@28
|
711 end
|
flickerstreak@28
|
712 else
|
flickerstreak@28
|
713 for _,v in ipairs(event) do
|
flickerstreak@28
|
714 AceEvent.RegisterEvent(self, v, func)
|
flickerstreak@28
|
715 if isUnitBucket and not v:find("^UNIT_") then
|
flickerstreak@28
|
716 isUnitBucket = false
|
flickerstreak@28
|
717 end
|
flickerstreak@28
|
718 end
|
flickerstreak@28
|
719 end
|
flickerstreak@28
|
720 bucket.unit = isUnitBucket
|
flickerstreak@28
|
721 if not bucketfunc then
|
flickerstreak@28
|
722 bucketfunc = function(bucket)
|
flickerstreak@28
|
723 local current = bucket.current
|
flickerstreak@28
|
724 local method = bucket.method
|
flickerstreak@28
|
725 local self = bucket.self
|
flickerstreak@28
|
726 if bucket.run then
|
flickerstreak@28
|
727 if bucket.unit then
|
flickerstreak@28
|
728 for unit in pairs(current) do
|
flickerstreak@28
|
729 if not UnitExists(unit) then
|
flickerstreak@28
|
730 current[unit] = nil
|
flickerstreak@28
|
731 end
|
flickerstreak@28
|
732 end
|
flickerstreak@28
|
733 end
|
flickerstreak@28
|
734 if type(method) == "string" then
|
flickerstreak@28
|
735 self[method](self, current, unpack(bucket, 1, bucket.n))
|
flickerstreak@28
|
736 elseif method then -- function
|
flickerstreak@28
|
737 method(current, unpack(bucket, 1, bucket.n))
|
flickerstreak@28
|
738 end
|
flickerstreak@28
|
739 for k in pairs(current) do
|
flickerstreak@28
|
740 current[k] = nil
|
flickerstreak@28
|
741 k = nil
|
flickerstreak@28
|
742 end
|
flickerstreak@28
|
743 bucket.run = false
|
flickerstreak@28
|
744 end
|
flickerstreak@28
|
745 end
|
flickerstreak@28
|
746 end
|
flickerstreak@28
|
747 bucket.id = "AceEvent-Bucket-" .. tostring(bucket)
|
flickerstreak@28
|
748 AceEvent.ScheduleRepeatingEvent(self, bucket.id, bucketfunc, delay, bucket)
|
flickerstreak@28
|
749 end
|
flickerstreak@28
|
750
|
flickerstreak@28
|
751 function AceEvent:IsBucketEventRegistered(event)
|
flickerstreak@28
|
752 AceEvent:argCheck(event, 2, "string", "table")
|
flickerstreak@28
|
753 return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self]
|
flickerstreak@28
|
754 end
|
flickerstreak@28
|
755
|
flickerstreak@28
|
756 function AceEvent:UnregisterBucketEvent(event)
|
flickerstreak@28
|
757 AceEvent:argCheck(event, 2, "string", "table")
|
flickerstreak@28
|
758 if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then
|
flickerstreak@28
|
759 AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self)
|
flickerstreak@28
|
760 end
|
flickerstreak@28
|
761
|
flickerstreak@28
|
762 local bucket = AceEvent.buckets[event][self]
|
flickerstreak@28
|
763
|
flickerstreak@28
|
764 if type(event) == "string" then
|
flickerstreak@28
|
765 AceEvent.UnregisterEvent(self, event)
|
flickerstreak@28
|
766 else
|
flickerstreak@28
|
767 for _,v in ipairs(event) do
|
flickerstreak@28
|
768 AceEvent.UnregisterEvent(self, v)
|
flickerstreak@28
|
769 end
|
flickerstreak@28
|
770 end
|
flickerstreak@28
|
771 AceEvent:CancelScheduledEvent(bucket.id)
|
flickerstreak@28
|
772
|
flickerstreak@28
|
773 bucket.current = del(bucket.current)
|
flickerstreak@28
|
774 AceEvent.buckets[event][self] = del(bucket)
|
flickerstreak@28
|
775 if not next(AceEvent.buckets[event]) then
|
flickerstreak@28
|
776 AceEvent.buckets[event] = del(AceEvent.buckets[event])
|
flickerstreak@28
|
777 end
|
flickerstreak@28
|
778 end
|
flickerstreak@28
|
779
|
flickerstreak@28
|
780 function AceEvent:UnregisterAllBucketEvents()
|
flickerstreak@28
|
781 if not AceEvent.buckets or not next(AceEvent.buckets) then
|
flickerstreak@28
|
782 return
|
flickerstreak@28
|
783 end
|
flickerstreak@28
|
784 for k,v in pairs(AceEvent.buckets) do
|
flickerstreak@28
|
785 if v == self then
|
flickerstreak@28
|
786 AceEvent.UnregisterBucketEvent(self, k)
|
flickerstreak@28
|
787 k = nil
|
flickerstreak@28
|
788 end
|
flickerstreak@28
|
789 end
|
flickerstreak@28
|
790 end
|
flickerstreak@28
|
791
|
flickerstreak@28
|
792 local combatSchedules
|
flickerstreak@28
|
793 function AceEvent:CancelAllCombatSchedules()
|
flickerstreak@28
|
794 local i = 0
|
flickerstreak@28
|
795 while true do
|
flickerstreak@28
|
796 i = i + 1
|
flickerstreak@28
|
797 if not combatSchedules[i] then
|
flickerstreak@28
|
798 break
|
flickerstreak@28
|
799 end
|
flickerstreak@28
|
800 local v = combatSchedules[i]
|
flickerstreak@28
|
801 if v.self == self then
|
flickerstreak@28
|
802 v = del(v)
|
flickerstreak@28
|
803 table.remove(combatSchedules, i)
|
flickerstreak@28
|
804 i = i - 1
|
flickerstreak@28
|
805 end
|
flickerstreak@28
|
806 end
|
flickerstreak@28
|
807 end
|
flickerstreak@28
|
808
|
flickerstreak@28
|
809 local inCombat = false
|
flickerstreak@28
|
810
|
flickerstreak@28
|
811 function AceEvent:PLAYER_REGEN_DISABLED()
|
flickerstreak@28
|
812 inCombat = true
|
flickerstreak@28
|
813 end
|
flickerstreak@28
|
814
|
flickerstreak@28
|
815 do
|
flickerstreak@28
|
816 local tmp = {}
|
flickerstreak@28
|
817 function AceEvent:PLAYER_REGEN_ENABLED()
|
flickerstreak@28
|
818 inCombat = false
|
flickerstreak@28
|
819 for i, v in ipairs(combatSchedules) do
|
flickerstreak@28
|
820 tmp[i] = v
|
flickerstreak@28
|
821 combatSchedules[i] = nil
|
flickerstreak@28
|
822 end
|
flickerstreak@28
|
823 for i, v in ipairs(tmp) do
|
flickerstreak@28
|
824 local func = v.func
|
flickerstreak@28
|
825 if func then
|
flickerstreak@28
|
826 local success, err = pcall(func, unpack(v, 1, v.n))
|
flickerstreak@28
|
827 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
828 else
|
flickerstreak@28
|
829 local obj = v.obj or v.self
|
flickerstreak@28
|
830 local method = v.method
|
flickerstreak@28
|
831 local obj_method = obj[method]
|
flickerstreak@28
|
832 if obj_method then
|
flickerstreak@28
|
833 local success, err = pcall(obj_method, obj, unpack(v, 1, v.n))
|
flickerstreak@28
|
834 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
835 end
|
flickerstreak@28
|
836 end
|
flickerstreak@28
|
837 tmp[i] = del(v)
|
flickerstreak@28
|
838 end
|
flickerstreak@28
|
839 end
|
flickerstreak@28
|
840 end
|
flickerstreak@28
|
841
|
flickerstreak@28
|
842 function AceEvent:ScheduleLeaveCombatAction(method, ...)
|
flickerstreak@28
|
843 local style = type(method)
|
flickerstreak@28
|
844 if self == AceEvent then
|
flickerstreak@28
|
845 if style == "table" then
|
flickerstreak@28
|
846 local func = (...)
|
flickerstreak@28
|
847 AceEvent:argCheck(func, 3, "string")
|
flickerstreak@28
|
848 if type(method[func]) ~= "function" then
|
flickerstreak@28
|
849 AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
|
flickerstreak@28
|
850 end
|
flickerstreak@28
|
851 else
|
flickerstreak@28
|
852 AceEvent:argCheck(method, 2, "function", --[[so message is right]] "table")
|
flickerstreak@28
|
853 end
|
flickerstreak@28
|
854 self = method
|
flickerstreak@28
|
855 else
|
flickerstreak@28
|
856 AceEvent:argCheck(method, 2, "function", "string", "table")
|
flickerstreak@28
|
857 if style == "string" and type(self[method]) ~= "function" then
|
flickerstreak@28
|
858 AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", method)
|
flickerstreak@28
|
859 elseif style == "table" then
|
flickerstreak@28
|
860 local func = (...)
|
flickerstreak@28
|
861 AceEvent:argCheck(func, 3, "string")
|
flickerstreak@28
|
862 if type(method[func]) ~= "function" then
|
flickerstreak@28
|
863 AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func)
|
flickerstreak@28
|
864 end
|
flickerstreak@28
|
865 end
|
flickerstreak@28
|
866 end
|
flickerstreak@28
|
867
|
flickerstreak@28
|
868 if not inCombat then
|
flickerstreak@28
|
869 local success, err
|
flickerstreak@28
|
870 if type(method) == "function" then
|
flickerstreak@28
|
871 success, err = pcall(method, ...)
|
flickerstreak@28
|
872 elseif type(method) == "table" then
|
flickerstreak@28
|
873 local func = (...)
|
flickerstreak@28
|
874 success, err = pcall(method[func], method, select(2, ...))
|
flickerstreak@28
|
875 else
|
flickerstreak@28
|
876 success, err = pcall(self[method], self, ...)
|
flickerstreak@28
|
877 end
|
flickerstreak@28
|
878 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end
|
flickerstreak@28
|
879 return
|
flickerstreak@28
|
880 end
|
flickerstreak@28
|
881 local t
|
flickerstreak@28
|
882 local n = select('#', ...)
|
flickerstreak@28
|
883 if style == "table" then
|
flickerstreak@28
|
884 t = new(select(2, ...))
|
flickerstreak@28
|
885 t.obj = method
|
flickerstreak@28
|
886 t.method = (...)
|
flickerstreak@28
|
887 t.n = n-1
|
flickerstreak@28
|
888 else
|
flickerstreak@28
|
889 t = new(...)
|
flickerstreak@28
|
890 t.n = n
|
flickerstreak@28
|
891 if style == "function" then
|
flickerstreak@28
|
892 t.func = method
|
flickerstreak@28
|
893 else
|
flickerstreak@28
|
894 t.method = method
|
flickerstreak@28
|
895 end
|
flickerstreak@28
|
896 end
|
flickerstreak@28
|
897 t.self = self
|
flickerstreak@28
|
898 table.insert(combatSchedules, t)
|
flickerstreak@28
|
899 end
|
flickerstreak@28
|
900
|
flickerstreak@28
|
901 function AceEvent:OnEmbedDisable(target)
|
flickerstreak@28
|
902 self.UnregisterAllEvents(target)
|
flickerstreak@28
|
903
|
flickerstreak@28
|
904 self.CancelAllScheduledEvents(target)
|
flickerstreak@28
|
905
|
flickerstreak@28
|
906 self.UnregisterAllBucketEvents(target)
|
flickerstreak@28
|
907
|
flickerstreak@28
|
908 self.CancelAllCombatSchedules(target)
|
flickerstreak@28
|
909 end
|
flickerstreak@28
|
910
|
flickerstreak@28
|
911 function AceEvent:IsFullyInitialized()
|
flickerstreak@28
|
912 return self.postInit or false
|
flickerstreak@28
|
913 end
|
flickerstreak@28
|
914
|
flickerstreak@28
|
915 function AceEvent:IsPostPlayerLogin()
|
flickerstreak@28
|
916 return IsLoggedIn() and true or false
|
flickerstreak@28
|
917 end
|
flickerstreak@28
|
918
|
flickerstreak@28
|
919 local function activate(self, oldLib, oldDeactivate)
|
flickerstreak@28
|
920 AceEvent = self
|
flickerstreak@28
|
921
|
flickerstreak@28
|
922 self.onceRegistry = oldLib and oldLib.onceRegistry or {}
|
flickerstreak@28
|
923 self.throttleRegistry = oldLib and oldLib.throttleRegistry or {}
|
flickerstreak@28
|
924 self.delayRegistry = oldLib and oldLib.delayRegistry or {}
|
flickerstreak@28
|
925 self.buckets = oldLib and oldLib.buckets or {}
|
flickerstreak@28
|
926 self.registry = oldLib and oldLib.registry or {}
|
flickerstreak@28
|
927 self.frame = oldLib and oldLib.frame or CreateFrame("Frame", "AceEvent20Frame")
|
flickerstreak@28
|
928 self.playerLogin = IsLoggedIn() and true
|
flickerstreak@28
|
929 self.postInit = oldLib and oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true
|
flickerstreak@28
|
930 self.ALL_EVENTS = oldLib and oldLib.ALL_EVENTS or _G.newproxy()
|
flickerstreak@28
|
931 self.FAKE_NIL = oldLib and oldLib.FAKE_NIL or _G.newproxy()
|
flickerstreak@28
|
932 self.RATE = oldLib and oldLib.RATE or _G.newproxy()
|
flickerstreak@28
|
933 self.combatSchedules = oldLib and oldLib.combatSchedules or {}
|
flickerstreak@28
|
934 self.UID_NUM = oldLib and oldLib.UID_NUM or 0
|
flickerstreak@28
|
935
|
flickerstreak@28
|
936 -- Delete this down the road. Makes sure that the addonframes from revisions 33121 - 36174 get their events unregistered.
|
flickerstreak@28
|
937 local addonframes = oldLib and oldLib.addonframes
|
flickerstreak@28
|
938 if addonframes then
|
flickerstreak@28
|
939 for _, v in pairs(addonframes) do
|
flickerstreak@28
|
940 v:UnregisterAllEvents()
|
flickerstreak@28
|
941 end
|
flickerstreak@28
|
942 end
|
flickerstreak@28
|
943
|
flickerstreak@28
|
944 combatSchedules = self.combatSchedules
|
flickerstreak@28
|
945 ALL_EVENTS = self.ALL_EVENTS
|
flickerstreak@28
|
946 FAKE_NIL = self.FAKE_NIL
|
flickerstreak@28
|
947 RATE = self.RATE
|
flickerstreak@28
|
948 local inPlw = false
|
flickerstreak@28
|
949 local blacklist = {
|
flickerstreak@28
|
950 UNIT_INVENTORY_CHANGED = true,
|
flickerstreak@28
|
951 BAG_UPDATE = true,
|
flickerstreak@28
|
952 ITEM_LOCK_CHANGED = true,
|
flickerstreak@28
|
953 ACTIONBAR_SLOT_CHANGED = true,
|
flickerstreak@28
|
954 }
|
flickerstreak@28
|
955 self.frame:SetScript("OnEvent", function(_, event, ...)
|
flickerstreak@28
|
956 if event == "PLAYER_ENTERING_WORLD" then
|
flickerstreak@28
|
957 inPlw = false
|
flickerstreak@28
|
958 elseif event == "PLAYER_LEAVING_WORLD" then
|
flickerstreak@28
|
959 inPlw = true
|
flickerstreak@28
|
960 end
|
flickerstreak@28
|
961 if event and (not inPlw or not blacklist[event]) then
|
flickerstreak@28
|
962 self:TriggerEvent(event, ...)
|
flickerstreak@28
|
963 end
|
flickerstreak@28
|
964 end)
|
flickerstreak@28
|
965 if self.delayRegistry then
|
flickerstreak@28
|
966 delayRegistry = self.delayRegistry
|
flickerstreak@28
|
967 self.frame:SetScript("OnUpdate", OnUpdate)
|
flickerstreak@28
|
968 end
|
flickerstreak@28
|
969
|
flickerstreak@28
|
970 self:UnregisterAllEvents()
|
flickerstreak@28
|
971 self:CancelAllScheduledEvents()
|
flickerstreak@28
|
972
|
flickerstreak@28
|
973 registeringFromAceEvent = true
|
flickerstreak@28
|
974 self:RegisterEvent("LOOT_OPENED", function()
|
flickerstreak@28
|
975 SendAddonMessage("LOOT_OPENED", "", "RAID")
|
flickerstreak@28
|
976 end)
|
flickerstreak@28
|
977 registeringFromAceEvent = nil
|
flickerstreak@28
|
978
|
flickerstreak@28
|
979 local function handleFullInit()
|
flickerstreak@28
|
980 if not self.postInit then
|
flickerstreak@28
|
981 local function func()
|
flickerstreak@28
|
982 self.postInit = true
|
flickerstreak@28
|
983 self:TriggerEvent("AceEvent_FullyInitialized")
|
flickerstreak@28
|
984 if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then
|
flickerstreak@28
|
985 self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE")
|
flickerstreak@28
|
986 end
|
flickerstreak@28
|
987 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
|
flickerstreak@28
|
988 self:UnregisterEvent("MEETINGSTONE_CHANGED")
|
flickerstreak@28
|
989 end
|
flickerstreak@28
|
990 if self.registry["MINIMAP_ZONE_CHANGED"] and self.registry["MINIMAP_ZONE_CHANGED"][self] then
|
flickerstreak@28
|
991 self:UnregisterEvent("MINIMAP_ZONE_CHANGED")
|
flickerstreak@28
|
992 end
|
flickerstreak@28
|
993 if self.registry["LANGUAGE_LIST_CHANGED"] and self.registry["LANGUAGE_LIST_CHANGED"][self] then
|
flickerstreak@28
|
994 self:UnregisterEvent("LANGUAGE_LIST_CHANGED")
|
flickerstreak@28
|
995 end
|
flickerstreak@28
|
996 collectgarbage('collect')
|
flickerstreak@28
|
997 end
|
flickerstreak@28
|
998 registeringFromAceEvent = true
|
flickerstreak@28
|
999 local f = function()
|
flickerstreak@28
|
1000 self.playerLogin = true
|
flickerstreak@28
|
1001 self:ScheduleEvent("AceEvent_FullyInitialized", func, 1)
|
flickerstreak@28
|
1002 end
|
flickerstreak@28
|
1003 self:RegisterEvent("MEETINGSTONE_CHANGED", f, true)
|
flickerstreak@28
|
1004 self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function()
|
flickerstreak@28
|
1005 self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.15)
|
flickerstreak@28
|
1006 end)
|
flickerstreak@28
|
1007 self:RegisterEvent("LANGUAGE_LIST_CHANGED", function()
|
flickerstreak@28
|
1008 if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then
|
flickerstreak@28
|
1009 registeringFromAceEvent = true
|
flickerstreak@28
|
1010 self:UnregisterEvent("MEETINGSTONE_CHANGED")
|
flickerstreak@28
|
1011 self:RegisterEvent("MINIMAP_ZONE_CHANGED", fd, true)
|
flickerstreak@28
|
1012 registeringFromAceEvent = nil
|
flickerstreak@28
|
1013 end
|
flickerstreak@28
|
1014 end)
|
flickerstreak@28
|
1015 self:ScheduleEvent("AceEvent_FullyInitialized", func, 10)
|
flickerstreak@28
|
1016 registeringFromAceEvent = nil
|
flickerstreak@28
|
1017 end
|
flickerstreak@28
|
1018 end
|
flickerstreak@28
|
1019
|
flickerstreak@28
|
1020 if not self.playerLogin then
|
flickerstreak@28
|
1021 registeringFromAceEvent = true
|
flickerstreak@28
|
1022 self:RegisterEvent("PLAYER_LOGIN", function()
|
flickerstreak@28
|
1023 self.playerLogin = true
|
flickerstreak@28
|
1024 handleFullInit()
|
flickerstreak@28
|
1025 handleFullInit = nil
|
flickerstreak@28
|
1026 collectgarbage('collect')
|
flickerstreak@28
|
1027 end, true)
|
flickerstreak@28
|
1028 registeringFromAceEvent = nil
|
flickerstreak@28
|
1029 else
|
flickerstreak@28
|
1030 handleFullInit()
|
flickerstreak@28
|
1031 handleFullInit = nil
|
flickerstreak@28
|
1032 end
|
flickerstreak@28
|
1033
|
flickerstreak@28
|
1034 if not AceEvent20EditBox then
|
flickerstreak@28
|
1035 CreateFrame("Editbox", "AceEvent20EditBox")
|
flickerstreak@28
|
1036 end
|
flickerstreak@28
|
1037 local editbox = AceEvent20EditBox
|
flickerstreak@28
|
1038 function editbox:Execute(line)
|
flickerstreak@28
|
1039 local defaulteditbox = DEFAULT_CHAT_FRAME.editBox
|
flickerstreak@28
|
1040 self:SetAttribute("chatType", defaulteditbox:GetAttribute("chatType"))
|
flickerstreak@28
|
1041 self:SetAttribute("tellTarget", defaulteditbox:GetAttribute("tellTarget"))
|
flickerstreak@28
|
1042 self:SetAttribute("channelTarget", defaulteditbox:GetAttribute("channelTarget"))
|
flickerstreak@28
|
1043 self:SetText(line)
|
flickerstreak@28
|
1044 ChatEdit_SendText(self)
|
flickerstreak@28
|
1045 end
|
flickerstreak@28
|
1046 editbox:Hide()
|
flickerstreak@28
|
1047 _G["SLASH_IN1"] = "/in"
|
flickerstreak@28
|
1048 SlashCmdList["IN"] = function(msg)
|
flickerstreak@28
|
1049 local seconds, command, rest = msg:match("^([^%s]+)%s+(/[^%s]+)(.*)$")
|
flickerstreak@28
|
1050 seconds = tonumber(seconds)
|
flickerstreak@28
|
1051 if not seconds then
|
flickerstreak@28
|
1052 DEFAULT_CHAT_FRAME:AddMessage("Error, bad arguments to /in. Must be in the form of `/in 5 /say hi'")
|
flickerstreak@28
|
1053 return
|
flickerstreak@28
|
1054 end
|
flickerstreak@28
|
1055 if IsSecureCmd(command) then
|
flickerstreak@28
|
1056 DEFAULT_CHAT_FRAME:AddMessage(("Error, /in cannot call secure command: %s"):format(command))
|
flickerstreak@28
|
1057 return
|
flickerstreak@28
|
1058 end
|
flickerstreak@28
|
1059 self:ScheduleEvent("AceEventSlashIn-" .. math.random(1, 1000000000), editbox.Execute, seconds, editbox, command .. rest)
|
flickerstreak@28
|
1060 end
|
flickerstreak@28
|
1061 registeringFromAceEvent = true
|
flickerstreak@28
|
1062 self:RegisterEvent("PLAYER_REGEN_ENABLED")
|
flickerstreak@28
|
1063 self:RegisterEvent("PLAYER_REGEN_DISABLED")
|
flickerstreak@28
|
1064 inCombat = InCombatLockdown()
|
flickerstreak@28
|
1065 registeringFromAceEvent = nil
|
flickerstreak@28
|
1066
|
flickerstreak@28
|
1067 -- another hack to make sure that we clean up properly from rev 33121 - 36174
|
flickerstreak@28
|
1068 if self.registry[ALL_EVENTS] then
|
flickerstreak@28
|
1069 self.frame:RegisterAllEvents()
|
flickerstreak@28
|
1070 else
|
flickerstreak@28
|
1071 for event in pairs(self.registry) do
|
flickerstreak@28
|
1072 self.frame:RegisterEvent(event)
|
flickerstreak@28
|
1073 end
|
flickerstreak@28
|
1074 end
|
flickerstreak@28
|
1075
|
flickerstreak@28
|
1076 self:activate(oldLib, oldDeactivate)
|
flickerstreak@28
|
1077 if oldLib then
|
flickerstreak@28
|
1078 oldDeactivate(oldLib)
|
flickerstreak@28
|
1079 end
|
flickerstreak@28
|
1080 end
|
flickerstreak@28
|
1081
|
flickerstreak@28
|
1082 AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, activate)
|