flickerstreak@28: --[[ flickerstreak@28: Name: AceEvent-2.0 flickerstreak@28: Revision: $Rev: 49307 $ flickerstreak@28: Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) flickerstreak@28: Inspired By: Ace 1.x by Turan (turan@gryphon.com) flickerstreak@28: Website: http://www.wowace.com/ flickerstreak@28: Documentation: http://www.wowace.com/index.php/AceEvent-2.0 flickerstreak@28: SVN: http://svn.wowace.com/root/trunk/Ace2/AceEvent-2.0 flickerstreak@28: Description: Mixin to allow for event handling, scheduling, and inter-addon flickerstreak@28: communication. flickerstreak@28: Dependencies: AceLibrary, AceOO-2.0 flickerstreak@28: License: LGPL v2.1 flickerstreak@28: ]] flickerstreak@28: flickerstreak@28: local MAJOR_VERSION = "AceEvent-2.0" flickerstreak@28: local MINOR_VERSION = "$Revision: 49307 $" flickerstreak@28: flickerstreak@28: if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end flickerstreak@28: if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end flickerstreak@28: flickerstreak@28: if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end flickerstreak@28: flickerstreak@28: local AceOO = AceLibrary:GetInstance("AceOO-2.0") flickerstreak@28: local Mixin = AceOO.Mixin flickerstreak@28: local AceEvent = Mixin { flickerstreak@28: "RegisterEvent", flickerstreak@28: "RegisterAllEvents", flickerstreak@28: "UnregisterEvent", flickerstreak@28: "UnregisterAllEvents", flickerstreak@28: "TriggerEvent", flickerstreak@28: "ScheduleEvent", flickerstreak@28: "ScheduleRepeatingEvent", flickerstreak@28: "CancelScheduledEvent", flickerstreak@28: "CancelAllScheduledEvents", flickerstreak@28: "IsEventRegistered", flickerstreak@28: "IsEventScheduled", flickerstreak@28: "RegisterBucketEvent", flickerstreak@28: "UnregisterBucketEvent", flickerstreak@28: "UnregisterAllBucketEvents", flickerstreak@28: "IsBucketEventRegistered", flickerstreak@28: "ScheduleLeaveCombatAction", flickerstreak@28: "CancelAllCombatSchedules", flickerstreak@28: } flickerstreak@28: flickerstreak@28: local weakKey = {__mode="k"} flickerstreak@28: flickerstreak@28: local FAKE_NIL flickerstreak@28: local RATE flickerstreak@28: flickerstreak@28: local eventsWhichHappenOnce = { flickerstreak@28: PLAYER_LOGIN = true, flickerstreak@28: AceEvent_FullyInitialized = true, flickerstreak@28: VARIABLES_LOADED = true, flickerstreak@28: PLAYER_LOGOUT = true, flickerstreak@28: } flickerstreak@28: local next = next flickerstreak@28: local pairs = pairs flickerstreak@28: local pcall = pcall flickerstreak@28: local type = type flickerstreak@28: local GetTime = GetTime flickerstreak@28: local gcinfo = gcinfo flickerstreak@28: local unpack = unpack flickerstreak@28: local geterrorhandler = geterrorhandler flickerstreak@28: flickerstreak@28: local build = GetBuildInfo() flickerstreak@28: local useTablesAsIDs = build:find("^2%.0%.") or build:find("^2%.1%.") or build:find("^0%.1%.") flickerstreak@28: flickerstreak@28: local new, del flickerstreak@28: do flickerstreak@28: local cache = setmetatable({}, {__mode='k'}) flickerstreak@28: function new(...) flickerstreak@28: local t = next(cache) flickerstreak@28: if t then flickerstreak@28: cache[t] = nil flickerstreak@28: for i = 1, select('#', ...) do flickerstreak@28: t[i] = select(i, ...) flickerstreak@28: end flickerstreak@28: return t flickerstreak@28: else flickerstreak@28: return { ... } flickerstreak@28: end flickerstreak@28: end flickerstreak@28: function del(t) flickerstreak@28: for k in pairs(t) do flickerstreak@28: t[k] = nil flickerstreak@28: end flickerstreak@28: cache[t] = true flickerstreak@28: return nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local registeringFromAceEvent flickerstreak@28: --[[---------------------------------------------------------------------------------- flickerstreak@28: Notes: flickerstreak@28: * 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: Arguments: flickerstreak@28: string - name of the event to register flickerstreak@28: [optional] string or function - name of the method or function to call. Default: same name as "event". flickerstreak@28: [optional] boolean - whether to have method called only once. Default: false flickerstreak@28: ------------------------------------------------------------------------------------]] flickerstreak@28: function AceEvent:RegisterEvent(event, method, once) flickerstreak@28: AceEvent:argCheck(event, 2, "string") flickerstreak@28: if self == AceEvent and not registeringFromAceEvent then flickerstreak@28: AceEvent:argCheck(method, 3, "function") flickerstreak@28: self = method flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(method, 3, "string", "function", "nil", "boolean", "number") flickerstreak@28: if type(method) == "boolean" or type(method) == "number" then flickerstreak@28: AceEvent:argCheck(once, 4, "nil") flickerstreak@28: once, method = method, event flickerstreak@28: end flickerstreak@28: end flickerstreak@28: AceEvent:argCheck(once, 4, "number", "boolean", "nil") flickerstreak@28: if eventsWhichHappenOnce[event] then flickerstreak@28: once = true flickerstreak@28: end flickerstreak@28: local throttleRate flickerstreak@28: if type(once) == "number" then flickerstreak@28: throttleRate, once = once flickerstreak@28: end flickerstreak@28: if not method then flickerstreak@28: method = event flickerstreak@28: end flickerstreak@28: if type(method) == "string" and type(self[method]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method) flickerstreak@28: else flickerstreak@28: assert(type(method) == "function" or type(method) == "string") flickerstreak@28: end flickerstreak@28: flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: if not AceEvent_registry[event] then flickerstreak@28: AceEvent_registry[event] = new() flickerstreak@28: AceEvent.frame:RegisterEvent(event) flickerstreak@28: end flickerstreak@28: flickerstreak@28: local remember = true flickerstreak@28: if AceEvent_registry[event][self] then flickerstreak@28: remember = false flickerstreak@28: end flickerstreak@28: AceEvent_registry[event][self] = method flickerstreak@28: flickerstreak@28: local AceEvent_onceRegistry = AceEvent.onceRegistry flickerstreak@28: if once then flickerstreak@28: if not AceEvent_onceRegistry then flickerstreak@28: AceEvent.onceRegistry = {} flickerstreak@28: AceEvent_onceRegistry = AceEvent.onceRegistry flickerstreak@28: end flickerstreak@28: if not AceEvent_onceRegistry[event] then flickerstreak@28: AceEvent_onceRegistry[event] = new() flickerstreak@28: end flickerstreak@28: AceEvent_onceRegistry[event][self] = true flickerstreak@28: else flickerstreak@28: if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then flickerstreak@28: AceEvent_onceRegistry[event][self] = nil flickerstreak@28: if not next(AceEvent_onceRegistry[event]) then flickerstreak@28: AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event]) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local AceEvent_throttleRegistry = AceEvent.throttleRegistry flickerstreak@28: if throttleRate then flickerstreak@28: if not AceEvent_throttleRegistry then flickerstreak@28: AceEvent.throttleRegistry = {} flickerstreak@28: AceEvent_throttleRegistry = AceEvent.throttleRegistry flickerstreak@28: end flickerstreak@28: if not AceEvent_throttleRegistry[event] then flickerstreak@28: AceEvent_throttleRegistry[event] = new() flickerstreak@28: end flickerstreak@28: if AceEvent_throttleRegistry[event][self] then flickerstreak@28: AceEvent_throttleRegistry[event][self] = nil flickerstreak@28: end flickerstreak@28: AceEvent_throttleRegistry[event][self] = setmetatable(new(), weakKey) flickerstreak@28: local t = AceEvent_throttleRegistry[event][self] flickerstreak@28: t[RATE] = throttleRate flickerstreak@28: else flickerstreak@28: if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] then flickerstreak@28: if AceEvent_throttleRegistry[event][self] then flickerstreak@28: AceEvent_throttleRegistry[event][self] = nil flickerstreak@28: end flickerstreak@28: if not next(AceEvent_throttleRegistry[event]) then flickerstreak@28: AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event]) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: if remember then flickerstreak@28: AceEvent:TriggerEvent("AceEvent_EventRegistered", self, event) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local ALL_EVENTS flickerstreak@28: flickerstreak@28: --[[---------------------------------------------------------------------------------- flickerstreak@28: Notes: flickerstreak@28: * Registers all events to the given method flickerstreak@28: * To access the current event, check AceEvent.currentEvent flickerstreak@28: * To access the current event's unique identifier, check AceEvent.currentEventUID flickerstreak@28: * This is only for debugging purposes. flickerstreak@28: Arguments: flickerstreak@28: [optional] string or function - name of the method or function to call. Default: same name as "event". flickerstreak@28: ------------------------------------------------------------------------------------]] flickerstreak@28: function AceEvent:RegisterAllEvents(method) flickerstreak@28: if self == AceEvent then flickerstreak@28: AceEvent:argCheck(method, 1, "function") flickerstreak@28: self = method flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(method, 1, "string", "function") flickerstreak@28: if type(method) == "string" and type(self[method]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot register all events to method %q, it does not exist", method) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: if not AceEvent_registry[ALL_EVENTS] then flickerstreak@28: AceEvent_registry[ALL_EVENTS] = new() flickerstreak@28: AceEvent.frame:RegisterAllEvents() flickerstreak@28: end flickerstreak@28: flickerstreak@28: local remember = not AceEvent_registry[ALL_EVENTS][self] flickerstreak@28: AceEvent_registry[ALL_EVENTS][self] = method flickerstreak@28: if remember then flickerstreak@28: AceEvent:TriggerEvent("AceEvent_EventRegistered", self, "all") flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: --[[---------------------------------------------------------------------------------- flickerstreak@28: Notes: flickerstreak@28: * Trigger a custom AceEvent. flickerstreak@28: * This should never be called to simulate fake Blizzard events. flickerstreak@28: * Custom events should be in the form of AddonName_SpecificEvent flickerstreak@28: Arguments: flickerstreak@28: string - name of the event flickerstreak@28: tuple - list of arguments to pass along flickerstreak@28: ------------------------------------------------------------------------------------]] flickerstreak@28: function AceEvent:TriggerEvent(event, ...) flickerstreak@28: if type(event) ~= "string" then flickerstreak@28: DEFAULT_CHAT_FRAME:AddMessage(debugstack()) flickerstreak@28: end flickerstreak@28: AceEvent:argCheck(event, 2, "string") flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: 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: return flickerstreak@28: end flickerstreak@28: local lastEvent = AceEvent.currentEvent flickerstreak@28: AceEvent.currentEvent = event flickerstreak@28: local lastEventUID = AceEvent.currentEventUID flickerstreak@28: local uid = AceEvent.UID_NUM + 1 flickerstreak@28: AceEvent.UID_NUM = uid flickerstreak@28: AceEvent.currentEventUID = uid flickerstreak@28: flickerstreak@28: local tmp = new() flickerstreak@28: flickerstreak@28: local AceEvent_onceRegistry = AceEvent.onceRegistry flickerstreak@28: if AceEvent_onceRegistry and AceEvent_onceRegistry[event] then flickerstreak@28: for obj, method in pairs(AceEvent_onceRegistry[event]) do flickerstreak@28: tmp[obj] = AceEvent_registry[event] and AceEvent_registry[event][obj] or nil flickerstreak@28: end flickerstreak@28: local obj = next(tmp) flickerstreak@28: while obj do flickerstreak@28: local method = tmp[obj] flickerstreak@28: AceEvent.UnregisterEvent(obj, event) flickerstreak@28: if type(method) == "string" then flickerstreak@28: local obj_method = obj[method] flickerstreak@28: if obj_method then flickerstreak@28: local success, err = pcall(obj_method, obj, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: elseif method then -- function flickerstreak@28: local success, err = pcall(method, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: tmp[obj] = nil flickerstreak@28: obj = next(tmp) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local AceEvent_throttleRegistry = AceEvent.throttleRegistry flickerstreak@28: local throttleTable = AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] flickerstreak@28: if AceEvent_registry[event] then flickerstreak@28: for obj, method in pairs(AceEvent_registry[event]) do flickerstreak@28: tmp[obj] = method flickerstreak@28: end flickerstreak@28: local obj = next(tmp) flickerstreak@28: while obj do flickerstreak@28: local method = tmp[obj] flickerstreak@28: local continue = false flickerstreak@28: if throttleTable and throttleTable[obj] then flickerstreak@28: local a1 = ... flickerstreak@28: if a1 == nil then flickerstreak@28: a1 = FAKE_NIL flickerstreak@28: end flickerstreak@28: if not throttleTable[obj][a1] or GetTime() - throttleTable[obj][a1] >= throttleTable[obj][RATE] then flickerstreak@28: throttleTable[obj][a1] = GetTime() flickerstreak@28: else flickerstreak@28: continue = true flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if not continue then flickerstreak@28: if type(method) == "string" then flickerstreak@28: local obj_method = obj[method] flickerstreak@28: if obj_method then flickerstreak@28: local success, err = pcall(obj_method, obj, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: elseif method then -- function flickerstreak@28: local success, err = pcall(method, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: tmp[obj] = nil flickerstreak@28: obj = next(tmp) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if AceEvent_registry[ALL_EVENTS] then flickerstreak@28: for obj, method in pairs(AceEvent_registry[ALL_EVENTS]) do flickerstreak@28: tmp[obj] = method flickerstreak@28: end flickerstreak@28: local obj = next(tmp) flickerstreak@28: while obj do flickerstreak@28: local method = tmp[obj] flickerstreak@28: if type(method) == "string" then flickerstreak@28: local obj_method = obj[method] flickerstreak@28: if obj_method then flickerstreak@28: local success, err = pcall(obj_method, obj, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: elseif method then -- function flickerstreak@28: local success, err = pcall(method, ...) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: tmp[obj] = nil flickerstreak@28: obj = next(tmp) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: tmp = del(tmp) flickerstreak@28: AceEvent.currentEvent = lastEvent flickerstreak@28: AceEvent.currentEventUID = lastEventUID flickerstreak@28: end flickerstreak@28: flickerstreak@28: local delayRegistry flickerstreak@28: local OnUpdate flickerstreak@28: do flickerstreak@28: local tmp = {} flickerstreak@28: OnUpdate = function() flickerstreak@28: local t = GetTime() flickerstreak@28: for k,v in pairs(delayRegistry) do flickerstreak@28: tmp[k] = true flickerstreak@28: end flickerstreak@28: for k in pairs(tmp) do flickerstreak@28: local v = delayRegistry[k] flickerstreak@28: if v then flickerstreak@28: local v_time = v.time flickerstreak@28: if not v_time then flickerstreak@28: delayRegistry[k] = nil flickerstreak@28: elseif v_time <= t then flickerstreak@28: local v_repeatDelay = v.repeatDelay flickerstreak@28: if v_repeatDelay then flickerstreak@28: -- use the event time, not the current time, else timing inaccuracies add up over time flickerstreak@28: v.time = v_time + v_repeatDelay flickerstreak@28: end flickerstreak@28: local event = v.event flickerstreak@28: if type(event) == "function" then flickerstreak@28: local uid = AceEvent.UID_NUM + 1 flickerstreak@28: AceEvent.UID_NUM = uid flickerstreak@28: AceEvent.currentEventUID = uid flickerstreak@28: local success, err = pcall(event, unpack(v, 1, v.n)) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: AceEvent.currentEventUID = nil flickerstreak@28: else flickerstreak@28: AceEvent:TriggerEvent(event, unpack(v, 1, v.n)) flickerstreak@28: end flickerstreak@28: if not v_repeatDelay then flickerstreak@28: local x = delayRegistry[k] flickerstreak@28: if x and x.time == v_time then -- check if it was manually reset flickerstreak@28: if not useTablesAsIDs or type(k) == "string" then flickerstreak@28: del(delayRegistry[k]) flickerstreak@28: end flickerstreak@28: delayRegistry[k] = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: for k in pairs(tmp) do flickerstreak@28: tmp[k] = nil flickerstreak@28: end flickerstreak@28: if not next(delayRegistry) then flickerstreak@28: AceEvent.frame:Hide() flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local function ScheduleEvent(self, repeating, event, delay, ...) flickerstreak@28: local id flickerstreak@28: if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then flickerstreak@28: if useTablesAsIDs and type(event) == "table" then flickerstreak@28: if not delayRegistry or not delayRegistry[event] then flickerstreak@28: AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.") flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if type(delay) ~= "number" then flickerstreak@28: id, event, delay = event, delay, ... flickerstreak@28: AceEvent:argCheck(event, 3, "string", "function", --[[ so message is right ]] "number") flickerstreak@28: AceEvent:argCheck(delay, 4, "number") flickerstreak@28: self:CancelScheduledEvent(id) flickerstreak@28: end flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(event, 2, "string", "function") flickerstreak@28: AceEvent:argCheck(delay, 3, "number") flickerstreak@28: end flickerstreak@28: flickerstreak@28: if not delayRegistry then flickerstreak@28: AceEvent.delayRegistry = {} flickerstreak@28: delayRegistry = AceEvent.delayRegistry flickerstreak@28: AceEvent.frame:SetScript("OnUpdate", OnUpdate) flickerstreak@28: end flickerstreak@28: local t flickerstreak@28: if useTablesAsIDs and type(id) == "table" then flickerstreak@28: for k in pairs(id) do flickerstreak@28: id[k] = nil flickerstreak@28: end flickerstreak@28: t = id flickerstreak@28: for i = 2, select('#', ...) do flickerstreak@28: t[i-1] = select(i, ...) flickerstreak@28: end flickerstreak@28: t.n = select('#', ...) - 1 flickerstreak@28: elseif id then flickerstreak@28: t = new(select(2, ...)) flickerstreak@28: t.n = select('#', ...) - 1 flickerstreak@28: else flickerstreak@28: t = new(...) flickerstreak@28: t.n = select('#', ...) flickerstreak@28: end flickerstreak@28: t.event = event flickerstreak@28: t.time = GetTime() + delay flickerstreak@28: t.self = self flickerstreak@28: t.id = id or t flickerstreak@28: t.repeatDelay = repeating and delay flickerstreak@28: delayRegistry[t.id] = t flickerstreak@28: AceEvent.frame:Show() flickerstreak@28: if useTablesAsIDs then flickerstreak@28: return t.id flickerstreak@28: else flickerstreak@28: return flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: --[[---------------------------------------------------------------------------------- flickerstreak@28: Notes: flickerstreak@28: * Schedule an event to fire. flickerstreak@28: * To fire on the next frame, specify a delay of 0. flickerstreak@28: Arguments: flickerstreak@28: string or function - name of the event to fire, or a function to call. flickerstreak@28: number - the amount of time to wait until calling. flickerstreak@28: tuple - a list of arguments to pass along. flickerstreak@28: ------------------------------------------------------------------------------------]] flickerstreak@28: function AceEvent:ScheduleEvent(event, delay, ...) flickerstreak@28: if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then flickerstreak@28: if useTablesAsIDs and type(event) == "table" then flickerstreak@28: if not delayRegistry or not delayRegistry[event] then flickerstreak@28: AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.") flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if type(delay) ~= "number" then flickerstreak@28: AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number") flickerstreak@28: AceEvent:argCheck(..., 4, "number") flickerstreak@28: end flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(event, 2, "string", "function") flickerstreak@28: AceEvent:argCheck(delay, 3, "number") flickerstreak@28: end flickerstreak@28: flickerstreak@28: return ScheduleEvent(self, false, event, delay, ...) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:ScheduleRepeatingEvent(event, delay, ...) flickerstreak@28: if type(event) == "string" or (useTablesAsIDs and type(event) == "table") then flickerstreak@28: if useTablesAsIDs and type(event) == "table" then flickerstreak@28: if not delayRegistry or not delayRegistry[event] then flickerstreak@28: AceEvent:error("Bad argument #2 to `ScheduleEvent'. Improper id table fed in.") flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if type(delay) ~= "number" then flickerstreak@28: AceEvent:argCheck(delay, 3, "string", "function", --[[ so message is right ]] "number") flickerstreak@28: AceEvent:argCheck(..., 4, "number") flickerstreak@28: end flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(event, 2, "string", "function") flickerstreak@28: AceEvent:argCheck(delay, 3, "number") flickerstreak@28: end flickerstreak@28: flickerstreak@28: return ScheduleEvent(self, true, event, delay, ...) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:CancelScheduledEvent(t) flickerstreak@28: if useTablesAsIDs then flickerstreak@28: AceEvent:argCheck(t, 2, "string", "table") flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(t, 2, "string") flickerstreak@28: end flickerstreak@28: if delayRegistry then flickerstreak@28: local v = delayRegistry[t] flickerstreak@28: if v then flickerstreak@28: if not useTablesAsIDs or type(t) == "string" then flickerstreak@28: del(delayRegistry[t]) flickerstreak@28: end flickerstreak@28: delayRegistry[t] = nil flickerstreak@28: if not next(delayRegistry) then flickerstreak@28: AceEvent.frame:Hide() flickerstreak@28: end flickerstreak@28: return true flickerstreak@28: end flickerstreak@28: end flickerstreak@28: return false flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:IsEventScheduled(t) flickerstreak@28: if useTablesAsIDs then flickerstreak@28: AceEvent:argCheck(t, 2, "string", "table") flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(t, 2, "string") flickerstreak@28: end flickerstreak@28: if delayRegistry then flickerstreak@28: local v = delayRegistry[t] flickerstreak@28: if v then flickerstreak@28: return true, v.time - GetTime() flickerstreak@28: end flickerstreak@28: end flickerstreak@28: return false, nil flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:UnregisterEvent(event) flickerstreak@28: AceEvent:argCheck(event, 2, "string") flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: if AceEvent_registry[event] and AceEvent_registry[event][self] then flickerstreak@28: AceEvent_registry[event][self] = nil flickerstreak@28: local AceEvent_onceRegistry = AceEvent.onceRegistry flickerstreak@28: if AceEvent_onceRegistry and AceEvent_onceRegistry[event] and AceEvent_onceRegistry[event][self] then flickerstreak@28: AceEvent_onceRegistry[event][self] = nil flickerstreak@28: if not next(AceEvent_onceRegistry[event]) then flickerstreak@28: AceEvent_onceRegistry[event] = del(AceEvent_onceRegistry[event]) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: local AceEvent_throttleRegistry = AceEvent.throttleRegistry flickerstreak@28: if AceEvent_throttleRegistry and AceEvent_throttleRegistry[event] and AceEvent_throttleRegistry[event][self] then flickerstreak@28: AceEvent_throttleRegistry[event][self] = nil flickerstreak@28: if not next(AceEvent_throttleRegistry[event]) then flickerstreak@28: AceEvent_throttleRegistry[event] = del(AceEvent_throttleRegistry[event]) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if not next(AceEvent_registry[event]) then flickerstreak@28: AceEvent_registry[event] = del(AceEvent_registry[event]) flickerstreak@28: if not AceEvent_registry[ALL_EVENTS] or not next(AceEvent_registry[ALL_EVENTS]) then flickerstreak@28: AceEvent.frame:UnregisterEvent(event) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: else flickerstreak@28: if self == AceEvent then flickerstreak@28: error(("Cannot unregister event %q. Improperly unregistering from AceEvent-2.0."):format(event), 2) flickerstreak@28: else flickerstreak@28: AceEvent:error("Cannot unregister event %q. %q is not registered with it.", event, self) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:UnregisterAllEvents() flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then flickerstreak@28: AceEvent_registry[ALL_EVENTS][self] = nil flickerstreak@28: if not next(AceEvent_registry[ALL_EVENTS]) then flickerstreak@28: AceEvent_registry[ALL_EVENTS] = del(AceEvent_registry[ALL_EVENTS]) flickerstreak@28: AceEvent.frame:UnregisterAllEvents() flickerstreak@28: for k,v in pairs(AceEvent_registry) do flickerstreak@28: AceEvent.frame:RegisterEvent(k) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if AceEvent_registry.AceEvent_EventUnregistered then flickerstreak@28: local event, data = "AceEvent_EventUnregistered", AceEvent_registry.AceEvent_EventUnregistered flickerstreak@28: local x = data[self] flickerstreak@28: data[self] = nil flickerstreak@28: if x then flickerstreak@28: if not next(data) then flickerstreak@28: if not AceEvent_registry[ALL_EVENTS] then flickerstreak@28: AceEvent.frame:UnregisterEvent(event) flickerstreak@28: end flickerstreak@28: AceEvent_registry[event] = del(AceEvent_registry[event]) flickerstreak@28: end flickerstreak@28: AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: for event, data in pairs(AceEvent_registry) do flickerstreak@28: local x = data[self] flickerstreak@28: data[self] = nil flickerstreak@28: if x and event ~= ALL_EVENTS then flickerstreak@28: if not next(data) then flickerstreak@28: if not AceEvent_registry[ALL_EVENTS] then flickerstreak@28: AceEvent.frame:UnregisterEvent(event) flickerstreak@28: end flickerstreak@28: AceEvent_registry[event] = del(AceEvent_registry[event]) flickerstreak@28: end flickerstreak@28: AceEvent:TriggerEvent("AceEvent_EventUnregistered", self, event) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if AceEvent.onceRegistry then flickerstreak@28: for event, data in pairs(AceEvent.onceRegistry) do flickerstreak@28: data[self] = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:CancelAllScheduledEvents() flickerstreak@28: if delayRegistry then flickerstreak@28: for k,v in pairs(delayRegistry) do flickerstreak@28: if v.self == self then flickerstreak@28: if not useTablesAsIDs or type(k) == "string" then flickerstreak@28: del(delayRegistry[k]) flickerstreak@28: end flickerstreak@28: delayRegistry[k] = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if not next(delayRegistry) then flickerstreak@28: AceEvent.frame:Hide() flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:IsEventRegistered(event) flickerstreak@28: AceEvent:argCheck(event, 2, "string") flickerstreak@28: local AceEvent_registry = AceEvent.registry flickerstreak@28: if self == AceEvent then flickerstreak@28: 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: end flickerstreak@28: if AceEvent_registry[event] and AceEvent_registry[event][self] then flickerstreak@28: return true, AceEvent_registry[event][self] flickerstreak@28: end flickerstreak@28: if AceEvent_registry[ALL_EVENTS] and AceEvent_registry[ALL_EVENTS][self] then flickerstreak@28: return true, AceEvent_registry[ALL_EVENTS][self] flickerstreak@28: end flickerstreak@28: return false, nil flickerstreak@28: end flickerstreak@28: flickerstreak@28: local UnitExists = UnitExists flickerstreak@28: local bucketfunc flickerstreak@28: function AceEvent:RegisterBucketEvent(event, delay, method, ...) flickerstreak@28: AceEvent:argCheck(event, 2, "string", "table") flickerstreak@28: if type(event) == "table" then flickerstreak@28: for k,v in pairs(event) do flickerstreak@28: if type(k) ~= "number" then flickerstreak@28: AceEvent:error("All keys to argument #2 to `RegisterBucketEvent' must be numbers.") flickerstreak@28: elseif type(v) ~= "string" then flickerstreak@28: AceEvent:error("All values to argument #2 to `RegisterBucketEvent' must be strings.") flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: AceEvent:argCheck(delay, 3, "number") flickerstreak@28: if AceEvent == self then flickerstreak@28: AceEvent:argCheck(method, 4, "function") flickerstreak@28: self = method flickerstreak@28: else flickerstreak@28: if type(event) == "string" then flickerstreak@28: AceEvent:argCheck(method, 4, "string", "function", "nil") flickerstreak@28: if not method then flickerstreak@28: method = event flickerstreak@28: end flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(method, 4, "string", "function") flickerstreak@28: end flickerstreak@28: flickerstreak@28: if type(method) == "string" and type(self[method]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot register event %q to method %q, it does not exist", event, method) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: local buckets = AceEvent.buckets flickerstreak@28: if not buckets[event] then flickerstreak@28: buckets[event] = new() flickerstreak@28: end flickerstreak@28: if not buckets[event][self] then flickerstreak@28: local t = new() flickerstreak@28: t.current = new() flickerstreak@28: t.self = self flickerstreak@28: buckets[event][self] = t flickerstreak@28: else flickerstreak@28: AceEvent.CancelScheduledEvent(self, buckets[event][self].id) flickerstreak@28: end flickerstreak@28: local bucket = buckets[event][self] flickerstreak@28: bucket.method = method flickerstreak@28: flickerstreak@28: local n = select('#', ...) flickerstreak@28: if n > 0 then flickerstreak@28: for i = 1, n do flickerstreak@28: bucket[i] = select(i, ...) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: bucket.n = n flickerstreak@28: flickerstreak@28: local func = function(arg1) flickerstreak@28: bucket.run = true flickerstreak@28: if arg1 then flickerstreak@28: bucket.current[arg1] = true flickerstreak@28: end flickerstreak@28: end flickerstreak@28: buckets[event][self].func = func flickerstreak@28: local isUnitBucket = true flickerstreak@28: if type(event) == "string" then flickerstreak@28: AceEvent.RegisterEvent(self, event, func) flickerstreak@28: if not event:find("^UNIT_") then flickerstreak@28: isUnitBucket = false flickerstreak@28: end flickerstreak@28: else flickerstreak@28: for _,v in ipairs(event) do flickerstreak@28: AceEvent.RegisterEvent(self, v, func) flickerstreak@28: if isUnitBucket and not v:find("^UNIT_") then flickerstreak@28: isUnitBucket = false flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: bucket.unit = isUnitBucket flickerstreak@28: if not bucketfunc then flickerstreak@28: bucketfunc = function(bucket) flickerstreak@28: local current = bucket.current flickerstreak@28: local method = bucket.method flickerstreak@28: local self = bucket.self flickerstreak@28: if bucket.run then flickerstreak@28: if bucket.unit then flickerstreak@28: for unit in pairs(current) do flickerstreak@28: if not UnitExists(unit) then flickerstreak@28: current[unit] = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: if type(method) == "string" then flickerstreak@28: self[method](self, current, unpack(bucket, 1, bucket.n)) flickerstreak@28: elseif method then -- function flickerstreak@28: method(current, unpack(bucket, 1, bucket.n)) flickerstreak@28: end flickerstreak@28: for k in pairs(current) do flickerstreak@28: current[k] = nil flickerstreak@28: k = nil flickerstreak@28: end flickerstreak@28: bucket.run = false flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: bucket.id = "AceEvent-Bucket-" .. tostring(bucket) flickerstreak@28: AceEvent.ScheduleRepeatingEvent(self, bucket.id, bucketfunc, delay, bucket) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:IsBucketEventRegistered(event) flickerstreak@28: AceEvent:argCheck(event, 2, "string", "table") flickerstreak@28: return AceEvent.buckets and AceEvent.buckets[event] and AceEvent.buckets[event][self] flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:UnregisterBucketEvent(event) flickerstreak@28: AceEvent:argCheck(event, 2, "string", "table") flickerstreak@28: if not AceEvent.buckets or not AceEvent.buckets[event] or not AceEvent.buckets[event][self] then flickerstreak@28: AceEvent:error("Cannot unregister bucket event %q. %q is not registered with it.", event, self) flickerstreak@28: end flickerstreak@28: flickerstreak@28: local bucket = AceEvent.buckets[event][self] flickerstreak@28: flickerstreak@28: if type(event) == "string" then flickerstreak@28: AceEvent.UnregisterEvent(self, event) flickerstreak@28: else flickerstreak@28: for _,v in ipairs(event) do flickerstreak@28: AceEvent.UnregisterEvent(self, v) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: AceEvent:CancelScheduledEvent(bucket.id) flickerstreak@28: flickerstreak@28: bucket.current = del(bucket.current) flickerstreak@28: AceEvent.buckets[event][self] = del(bucket) flickerstreak@28: if not next(AceEvent.buckets[event]) then flickerstreak@28: AceEvent.buckets[event] = del(AceEvent.buckets[event]) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:UnregisterAllBucketEvents() flickerstreak@28: if not AceEvent.buckets or not next(AceEvent.buckets) then flickerstreak@28: return flickerstreak@28: end flickerstreak@28: for k,v in pairs(AceEvent.buckets) do flickerstreak@28: if v == self then flickerstreak@28: AceEvent.UnregisterBucketEvent(self, k) flickerstreak@28: k = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local combatSchedules flickerstreak@28: function AceEvent:CancelAllCombatSchedules() flickerstreak@28: local i = 0 flickerstreak@28: while true do flickerstreak@28: i = i + 1 flickerstreak@28: if not combatSchedules[i] then flickerstreak@28: break flickerstreak@28: end flickerstreak@28: local v = combatSchedules[i] flickerstreak@28: if v.self == self then flickerstreak@28: v = del(v) flickerstreak@28: table.remove(combatSchedules, i) flickerstreak@28: i = i - 1 flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: local inCombat = false flickerstreak@28: flickerstreak@28: function AceEvent:PLAYER_REGEN_DISABLED() flickerstreak@28: inCombat = true flickerstreak@28: end flickerstreak@28: flickerstreak@28: do flickerstreak@28: local tmp = {} flickerstreak@28: function AceEvent:PLAYER_REGEN_ENABLED() flickerstreak@28: inCombat = false flickerstreak@28: for i, v in ipairs(combatSchedules) do flickerstreak@28: tmp[i] = v flickerstreak@28: combatSchedules[i] = nil flickerstreak@28: end flickerstreak@28: for i, v in ipairs(tmp) do flickerstreak@28: local func = v.func flickerstreak@28: if func then flickerstreak@28: local success, err = pcall(func, unpack(v, 1, v.n)) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: else flickerstreak@28: local obj = v.obj or v.self flickerstreak@28: local method = v.method flickerstreak@28: local obj_method = obj[method] flickerstreak@28: if obj_method then flickerstreak@28: local success, err = pcall(obj_method, obj, unpack(v, 1, v.n)) flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: tmp[i] = del(v) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:ScheduleLeaveCombatAction(method, ...) flickerstreak@28: local style = type(method) flickerstreak@28: if self == AceEvent then flickerstreak@28: if style == "table" then flickerstreak@28: local func = (...) flickerstreak@28: AceEvent:argCheck(func, 3, "string") flickerstreak@28: if type(method[func]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func) flickerstreak@28: end flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(method, 2, "function", --[[so message is right]] "table") flickerstreak@28: end flickerstreak@28: self = method flickerstreak@28: else flickerstreak@28: AceEvent:argCheck(method, 2, "function", "string", "table") flickerstreak@28: if style == "string" and type(self[method]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", method) flickerstreak@28: elseif style == "table" then flickerstreak@28: local func = (...) flickerstreak@28: AceEvent:argCheck(func, 3, "string") flickerstreak@28: if type(method[func]) ~= "function" then flickerstreak@28: AceEvent:error("Cannot schedule a combat action to method %q, it does not exist", func) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: if not inCombat then flickerstreak@28: local success, err flickerstreak@28: if type(method) == "function" then flickerstreak@28: success, err = pcall(method, ...) flickerstreak@28: elseif type(method) == "table" then flickerstreak@28: local func = (...) flickerstreak@28: success, err = pcall(method[func], method, select(2, ...)) flickerstreak@28: else flickerstreak@28: success, err = pcall(self[method], self, ...) flickerstreak@28: end flickerstreak@28: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("(.-: )in.-\n") or "") .. err) end flickerstreak@28: return flickerstreak@28: end flickerstreak@28: local t flickerstreak@28: local n = select('#', ...) flickerstreak@28: if style == "table" then flickerstreak@28: t = new(select(2, ...)) flickerstreak@28: t.obj = method flickerstreak@28: t.method = (...) flickerstreak@28: t.n = n-1 flickerstreak@28: else flickerstreak@28: t = new(...) flickerstreak@28: t.n = n flickerstreak@28: if style == "function" then flickerstreak@28: t.func = method flickerstreak@28: else flickerstreak@28: t.method = method flickerstreak@28: end flickerstreak@28: end flickerstreak@28: t.self = self flickerstreak@28: table.insert(combatSchedules, t) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:OnEmbedDisable(target) flickerstreak@28: self.UnregisterAllEvents(target) flickerstreak@28: flickerstreak@28: self.CancelAllScheduledEvents(target) flickerstreak@28: flickerstreak@28: self.UnregisterAllBucketEvents(target) flickerstreak@28: flickerstreak@28: self.CancelAllCombatSchedules(target) flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:IsFullyInitialized() flickerstreak@28: return self.postInit or false flickerstreak@28: end flickerstreak@28: flickerstreak@28: function AceEvent:IsPostPlayerLogin() flickerstreak@28: return IsLoggedIn() and true or false flickerstreak@28: end flickerstreak@28: flickerstreak@28: local function activate(self, oldLib, oldDeactivate) flickerstreak@28: AceEvent = self flickerstreak@28: flickerstreak@28: self.onceRegistry = oldLib and oldLib.onceRegistry or {} flickerstreak@28: self.throttleRegistry = oldLib and oldLib.throttleRegistry or {} flickerstreak@28: self.delayRegistry = oldLib and oldLib.delayRegistry or {} flickerstreak@28: self.buckets = oldLib and oldLib.buckets or {} flickerstreak@28: self.registry = oldLib and oldLib.registry or {} flickerstreak@28: self.frame = oldLib and oldLib.frame or CreateFrame("Frame", "AceEvent20Frame") flickerstreak@28: self.playerLogin = IsLoggedIn() and true flickerstreak@28: self.postInit = oldLib and oldLib.postInit or self.playerLogin and ChatTypeInfo and ChatTypeInfo.WHISPER and ChatTypeInfo.WHISPER.r and true flickerstreak@28: self.ALL_EVENTS = oldLib and oldLib.ALL_EVENTS or _G.newproxy() flickerstreak@28: self.FAKE_NIL = oldLib and oldLib.FAKE_NIL or _G.newproxy() flickerstreak@28: self.RATE = oldLib and oldLib.RATE or _G.newproxy() flickerstreak@28: self.combatSchedules = oldLib and oldLib.combatSchedules or {} flickerstreak@28: self.UID_NUM = oldLib and oldLib.UID_NUM or 0 flickerstreak@28: flickerstreak@28: -- Delete this down the road. Makes sure that the addonframes from revisions 33121 - 36174 get their events unregistered. flickerstreak@28: local addonframes = oldLib and oldLib.addonframes flickerstreak@28: if addonframes then flickerstreak@28: for _, v in pairs(addonframes) do flickerstreak@28: v:UnregisterAllEvents() flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: combatSchedules = self.combatSchedules flickerstreak@28: ALL_EVENTS = self.ALL_EVENTS flickerstreak@28: FAKE_NIL = self.FAKE_NIL flickerstreak@28: RATE = self.RATE flickerstreak@28: local inPlw = false flickerstreak@28: local blacklist = { flickerstreak@28: UNIT_INVENTORY_CHANGED = true, flickerstreak@28: BAG_UPDATE = true, flickerstreak@28: ITEM_LOCK_CHANGED = true, flickerstreak@28: ACTIONBAR_SLOT_CHANGED = true, flickerstreak@28: } flickerstreak@28: self.frame:SetScript("OnEvent", function(_, event, ...) flickerstreak@28: if event == "PLAYER_ENTERING_WORLD" then flickerstreak@28: inPlw = false flickerstreak@28: elseif event == "PLAYER_LEAVING_WORLD" then flickerstreak@28: inPlw = true flickerstreak@28: end flickerstreak@28: if event and (not inPlw or not blacklist[event]) then flickerstreak@28: self:TriggerEvent(event, ...) flickerstreak@28: end flickerstreak@28: end) flickerstreak@28: if self.delayRegistry then flickerstreak@28: delayRegistry = self.delayRegistry flickerstreak@28: self.frame:SetScript("OnUpdate", OnUpdate) flickerstreak@28: end flickerstreak@28: flickerstreak@28: self:UnregisterAllEvents() flickerstreak@28: self:CancelAllScheduledEvents() flickerstreak@28: flickerstreak@28: registeringFromAceEvent = true flickerstreak@28: self:RegisterEvent("LOOT_OPENED", function() flickerstreak@28: SendAddonMessage("LOOT_OPENED", "", "RAID") flickerstreak@28: end) flickerstreak@28: registeringFromAceEvent = nil flickerstreak@28: flickerstreak@28: local function handleFullInit() flickerstreak@28: if not self.postInit then flickerstreak@28: local function func() flickerstreak@28: self.postInit = true flickerstreak@28: self:TriggerEvent("AceEvent_FullyInitialized") flickerstreak@28: if self.registry["CHAT_MSG_CHANNEL_NOTICE"] and self.registry["CHAT_MSG_CHANNEL_NOTICE"][self] then flickerstreak@28: self:UnregisterEvent("CHAT_MSG_CHANNEL_NOTICE") flickerstreak@28: end flickerstreak@28: if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then flickerstreak@28: self:UnregisterEvent("MEETINGSTONE_CHANGED") flickerstreak@28: end flickerstreak@28: if self.registry["MINIMAP_ZONE_CHANGED"] and self.registry["MINIMAP_ZONE_CHANGED"][self] then flickerstreak@28: self:UnregisterEvent("MINIMAP_ZONE_CHANGED") flickerstreak@28: end flickerstreak@28: if self.registry["LANGUAGE_LIST_CHANGED"] and self.registry["LANGUAGE_LIST_CHANGED"][self] then flickerstreak@28: self:UnregisterEvent("LANGUAGE_LIST_CHANGED") flickerstreak@28: end flickerstreak@28: collectgarbage('collect') flickerstreak@28: end flickerstreak@28: registeringFromAceEvent = true flickerstreak@28: local f = function() flickerstreak@28: self.playerLogin = true flickerstreak@28: self:ScheduleEvent("AceEvent_FullyInitialized", func, 1) flickerstreak@28: end flickerstreak@28: self:RegisterEvent("MEETINGSTONE_CHANGED", f, true) flickerstreak@28: self:RegisterEvent("CHAT_MSG_CHANNEL_NOTICE", function() flickerstreak@28: self:ScheduleEvent("AceEvent_FullyInitialized", func, 0.15) flickerstreak@28: end) flickerstreak@28: self:RegisterEvent("LANGUAGE_LIST_CHANGED", function() flickerstreak@28: if self.registry["MEETINGSTONE_CHANGED"] and self.registry["MEETINGSTONE_CHANGED"][self] then flickerstreak@28: registeringFromAceEvent = true flickerstreak@28: self:UnregisterEvent("MEETINGSTONE_CHANGED") flickerstreak@28: self:RegisterEvent("MINIMAP_ZONE_CHANGED", fd, true) flickerstreak@28: registeringFromAceEvent = nil flickerstreak@28: end flickerstreak@28: end) flickerstreak@28: self:ScheduleEvent("AceEvent_FullyInitialized", func, 10) flickerstreak@28: registeringFromAceEvent = nil flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: if not self.playerLogin then flickerstreak@28: registeringFromAceEvent = true flickerstreak@28: self:RegisterEvent("PLAYER_LOGIN", function() flickerstreak@28: self.playerLogin = true flickerstreak@28: handleFullInit() flickerstreak@28: handleFullInit = nil flickerstreak@28: collectgarbage('collect') flickerstreak@28: end, true) flickerstreak@28: registeringFromAceEvent = nil flickerstreak@28: else flickerstreak@28: handleFullInit() flickerstreak@28: handleFullInit = nil flickerstreak@28: end flickerstreak@28: flickerstreak@28: if not AceEvent20EditBox then flickerstreak@28: CreateFrame("Editbox", "AceEvent20EditBox") flickerstreak@28: end flickerstreak@28: local editbox = AceEvent20EditBox flickerstreak@28: function editbox:Execute(line) flickerstreak@28: local defaulteditbox = DEFAULT_CHAT_FRAME.editBox flickerstreak@28: self:SetAttribute("chatType", defaulteditbox:GetAttribute("chatType")) flickerstreak@28: self:SetAttribute("tellTarget", defaulteditbox:GetAttribute("tellTarget")) flickerstreak@28: self:SetAttribute("channelTarget", defaulteditbox:GetAttribute("channelTarget")) flickerstreak@28: self:SetText(line) flickerstreak@28: ChatEdit_SendText(self) flickerstreak@28: end flickerstreak@28: editbox:Hide() flickerstreak@28: _G["SLASH_IN1"] = "/in" flickerstreak@28: SlashCmdList["IN"] = function(msg) flickerstreak@28: local seconds, command, rest = msg:match("^([^%s]+)%s+(/[^%s]+)(.*)$") flickerstreak@28: seconds = tonumber(seconds) flickerstreak@28: if not seconds then flickerstreak@28: DEFAULT_CHAT_FRAME:AddMessage("Error, bad arguments to /in. Must be in the form of `/in 5 /say hi'") flickerstreak@28: return flickerstreak@28: end flickerstreak@28: if IsSecureCmd(command) then flickerstreak@28: DEFAULT_CHAT_FRAME:AddMessage(("Error, /in cannot call secure command: %s"):format(command)) flickerstreak@28: return flickerstreak@28: end flickerstreak@28: self:ScheduleEvent("AceEventSlashIn-" .. math.random(1, 1000000000), editbox.Execute, seconds, editbox, command .. rest) flickerstreak@28: end flickerstreak@28: registeringFromAceEvent = true flickerstreak@28: self:RegisterEvent("PLAYER_REGEN_ENABLED") flickerstreak@28: self:RegisterEvent("PLAYER_REGEN_DISABLED") flickerstreak@28: inCombat = InCombatLockdown() flickerstreak@28: registeringFromAceEvent = nil flickerstreak@28: flickerstreak@28: -- another hack to make sure that we clean up properly from rev 33121 - 36174 flickerstreak@28: if self.registry[ALL_EVENTS] then flickerstreak@28: self.frame:RegisterAllEvents() flickerstreak@28: else flickerstreak@28: for event in pairs(self.registry) do flickerstreak@28: self.frame:RegisterEvent(event) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: self:activate(oldLib, oldDeactivate) flickerstreak@28: if oldLib then flickerstreak@28: oldDeactivate(oldLib) flickerstreak@28: end flickerstreak@28: end flickerstreak@28: flickerstreak@28: AceLibrary:Register(AceEvent, MAJOR_VERSION, MINOR_VERSION, activate)