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