flickerstreak@23: --[[ flickerstreak@23: Name: AceModuleCore-2.0 flickerstreak@23: Revision: $Rev: 43318 $ flickerstreak@23: Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) flickerstreak@23: Inspired By: Ace 1.x by Turan (turan@gryphon.com) flickerstreak@23: Website: http://www.wowace.com/ flickerstreak@23: Documentation: http://www.wowace.com/index.php/AceModuleCore-2.0 flickerstreak@23: SVN: http://svn.wowace.com/root/trunk/Ace2/AceModuleCore-2.0 flickerstreak@23: Description: Mixin to provide a module system so that modules or plugins can flickerstreak@23: use an addon as its core. flickerstreak@23: Dependencies: AceLibrary, AceOO-2.0, AceAddon-2.0, AceEvent-2.0 (optional) flickerstreak@23: License: LGPL v2.1 flickerstreak@23: ]] flickerstreak@23: flickerstreak@23: local MAJOR_VERSION = "AceModuleCore-2.0" flickerstreak@23: local MINOR_VERSION = "$Revision: 43318 $" flickerstreak@23: flickerstreak@23: if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end flickerstreak@23: if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end flickerstreak@23: flickerstreak@23: if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end flickerstreak@23: flickerstreak@23: local function safecall(func, ...) flickerstreak@23: local success, err = pcall(func, ...) flickerstreak@23: if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local AceEvent flickerstreak@23: local AceOO = AceLibrary:GetInstance("AceOO-2.0") flickerstreak@23: local AceModuleCore = AceOO.Mixin { flickerstreak@23: "NewModule", flickerstreak@23: "HasModule", flickerstreak@23: "GetModule", flickerstreak@23: "IsModule", flickerstreak@23: "IterateModules", flickerstreak@23: "IterateModulesWithMethod", flickerstreak@23: "CallMethodOnAllModules", flickerstreak@23: "SetModuleMixins", flickerstreak@23: "SetModuleClass", flickerstreak@23: "IsModuleActive", flickerstreak@23: "ToggleModuleActive", flickerstreak@23: "SetModuleDefaultState", flickerstreak@23: } flickerstreak@23: local AceAddon flickerstreak@23: flickerstreak@23: local function getlibrary(lib) flickerstreak@23: if type(lib) == "string" then flickerstreak@23: return AceLibrary(lib) flickerstreak@23: else flickerstreak@23: return lib flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local new, del flickerstreak@23: do flickerstreak@23: local list = setmetatable({}, {__mode='k'}) flickerstreak@23: function new() flickerstreak@23: local t = next(list) flickerstreak@23: if t then flickerstreak@23: list[t] = nil flickerstreak@23: return t flickerstreak@23: else flickerstreak@23: return {} flickerstreak@23: end flickerstreak@23: end flickerstreak@23: function del(t) flickerstreak@23: for k in pairs(t) do flickerstreak@23: t[k] = nil flickerstreak@23: end flickerstreak@23: list[t] = true flickerstreak@23: return nil flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local iterList = setmetatable({}, {__mode='v'}) flickerstreak@23: local modulesWithMethod = setmetatable({}, {__mode='kv'}) flickerstreak@23: do flickerstreak@23: local function func(t) flickerstreak@23: local i = t.i + 1 flickerstreak@23: local l = t.l flickerstreak@23: local k = l[i] flickerstreak@23: if k then flickerstreak@23: t.i = i flickerstreak@23: return k, l.m[k] flickerstreak@23: else flickerstreak@23: t = del(t) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: function AceModuleCore:IterateModules() flickerstreak@23: local list = iterList[self] flickerstreak@23: if not list then flickerstreak@23: list = new() flickerstreak@23: for k in pairs(self.modules) do flickerstreak@23: list[#list+1] = k flickerstreak@23: end flickerstreak@23: table.sort(list) flickerstreak@23: list.m = self.modules flickerstreak@23: iterList[self] = list flickerstreak@23: end flickerstreak@23: local t = new() flickerstreak@23: t.i = 0 flickerstreak@23: t.l = list flickerstreak@23: return func, t, nil flickerstreak@23: end flickerstreak@23: flickerstreak@23: function AceModuleCore:IterateModulesWithMethod(method) flickerstreak@23: local masterList = modulesWithMethod[self] flickerstreak@23: if not masterList then flickerstreak@23: masterList = new() flickerstreak@23: modulesWithMethod[self] = masterList flickerstreak@23: end flickerstreak@23: local list = masterList[method] flickerstreak@23: if not list then flickerstreak@23: list = new() flickerstreak@23: for k, v in pairs(self.modules) do flickerstreak@23: if self:IsModuleActive(k) and type(v[method]) == "function" then flickerstreak@23: list[#list+1] = k flickerstreak@23: end flickerstreak@23: end flickerstreak@23: table.sort(list) flickerstreak@23: list.m = self.modules flickerstreak@23: masterList[method] = list flickerstreak@23: end flickerstreak@23: local t = new() flickerstreak@23: t.i = 0 flickerstreak@23: t.l = list flickerstreak@23: return func, t, nil flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Safely calls the given method on all active modules if it exists on said modules. This will automatically subvert any errors that occur in the modules. flickerstreak@23: Arguments: flickerstreak@23: string - the name of the method. flickerstreak@23: tuple - the list of arguments to call the method with. flickerstreak@23: Example: flickerstreak@23: core:CallMethodOnAllModules("OnSomething") flickerstreak@23: core:CallMethodOnAllModules("OnSomethingElse", 1, 2, 3, 4) flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:CallMethodOnAllModules(method, ...) flickerstreak@23: for name, module in self:IterateModulesWithMethod(method) do flickerstreak@23: local success, ret = pcall(module[method], module, ...) flickerstreak@23: if not success then flickerstreak@23: geterrorhandler()(ret) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Create a new module, parented to self. flickerstreak@23: The module created does, in fact, inherit from AceAddon-2.0. flickerstreak@23: Arguments: flickerstreak@23: string - name/title of the Module. flickerstreak@23: list of mixins the module is to inherit from. flickerstreak@23: Example: flickerstreak@23: MyModule = core:NewModule('MyModule', "AceEvent-2.0", "AceHook-2.1") flickerstreak@23: ------------------------------------------------------------------------------]] flickerstreak@23: local tmp = {} flickerstreak@23: function AceModuleCore:NewModule(name, ...) flickerstreak@23: if not self.modules then flickerstreak@23: AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2) flickerstreak@23: end flickerstreak@23: AceModuleCore:argCheck(name, 2, "string") flickerstreak@23: if name:len() == 0 then flickerstreak@23: AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty") flickerstreak@23: end flickerstreak@23: if self.modules[name] then flickerstreak@23: AceModuleCore:error("The module %q has already been registered", name) flickerstreak@23: end flickerstreak@23: flickerstreak@23: if iterList[self] then flickerstreak@23: iterList[self] = del(iterList[self]) flickerstreak@23: end flickerstreak@23: flickerstreak@23: for i = 1, select('#', ...) do flickerstreak@23: tmp[i] = getlibrary((select(i, ...))) flickerstreak@23: end flickerstreak@23: flickerstreak@23: if self.moduleMixins then flickerstreak@23: for _,mixin in ipairs(self.moduleMixins) do flickerstreak@23: local exists = false flickerstreak@23: for _,v in ipairs(tmp) do flickerstreak@23: if mixin == v then flickerstreak@23: exists = true flickerstreak@23: break flickerstreak@23: end flickerstreak@23: end flickerstreak@23: if not exists then flickerstreak@23: tmp[#tmp+1] = mixin flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name) flickerstreak@23: self.modules[name] = module flickerstreak@23: module.name = name flickerstreak@23: module.title = name flickerstreak@23: flickerstreak@23: AceModuleCore.totalModules[module] = self flickerstreak@23: flickerstreak@23: if modulesWithMethod[self] then flickerstreak@23: for k,v in pairs(modulesWithMethod[self]) do flickerstreak@23: modulesWithMethod[self] = del(v) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: if type(self.OnModuleCreated) == "function" then flickerstreak@23: safecall(self.OnModuleCreated, self, name, module) flickerstreak@23: end flickerstreak@23: if AceEvent then flickerstreak@23: AceEvent:TriggerEvent("Ace2_ModuleCreated", module) flickerstreak@23: end flickerstreak@23: flickerstreak@23: local num = #tmp flickerstreak@23: for i = 1, num do flickerstreak@23: tmp[i] = nil flickerstreak@23: end flickerstreak@23: return module flickerstreak@23: end flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Return whether the module names given are all available in the core. flickerstreak@23: Arguments: flickerstreak@23: list of strings that are the names of the modules. (typically you'd only check for one) flickerstreak@23: Returns: flickerstreak@23: * boolean - Whether all the modules are available in the core. flickerstreak@23: Example: flickerstreak@23: if core:HasModule('Bank') then flickerstreak@23: -- do banking flickerstreak@23: end flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:HasModule(...) flickerstreak@23: for i = 1, select('#', ...) do flickerstreak@23: if not self.modules[select(i, ...)] then flickerstreak@23: return false flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: return true flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[------------------------------------------------------------------------------------ flickerstreak@23: Notes: flickerstreak@23: Return the module "name" if it exists. flickerstreak@23: If the module doesnot exist, an error is thrown. flickerstreak@23: Arguments: flickerstreak@23: string - the name of the module. flickerstreak@23: Returns: flickerstreak@23: The module requested, if it exists. flickerstreak@23: Example: flickerstreak@23: local bank = core:GetModule('Bank') flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:GetModule(name) flickerstreak@23: if not self.modules then flickerstreak@23: AceModuleCore:error("Error initializing class. Please report error.") flickerstreak@23: end flickerstreak@23: if not self.modules[name] then flickerstreak@23: AceModuleCore:error("Cannot find module %q.", name) flickerstreak@23: end flickerstreak@23: return self.modules[name] flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Return whether the given module is actually a module. flickerstreak@23: Arguments: flickerstreak@23: reference to the module flickerstreak@23: Returns: flickerstreak@23: * boolean - whether the given module is actually a module. flickerstreak@23: Example: flickerstreak@23: if core:IsModule(module) then flickerstreak@23: -- do something flickerstreak@23: end flickerstreak@23: -- alternatively flickerstreak@23: if AceModuleCore:IsModule(module) then flickerstreak@23: -- checks all modules, no matter the parent flickerstreak@23: end flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:IsModule(module) flickerstreak@23: if self == AceModuleCore then flickerstreak@23: return AceModuleCore.totalModules[module] flickerstreak@23: elseif type(module) == "table" then flickerstreak@23: if module.name and self.modules[module.name] and self.modules[module.name].name == module.name then flickerstreak@23: return true flickerstreak@23: end flickerstreak@23: for k,v in pairs(self.modules) do flickerstreak@23: if v == module then flickerstreak@23: return true flickerstreak@23: end flickerstreak@23: end flickerstreak@23: return false flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: * Sets the default mixins for a given module. flickerstreak@23: * This cannot be called after :NewModule() has been called. flickerstreak@23: * This should really only be called if you use the mixins in your prototype. flickerstreak@23: Arguments: flickerstreak@23: list of mixins (up to 20) flickerstreak@23: Example: flickerstreak@23: core:SetModuleMixins("AceEvent-2.0", "AceHook-2.0") flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:SetModuleMixins(...) flickerstreak@23: if self.moduleMixins then flickerstreak@23: AceModuleCore:error('Cannot call "SetModuleMixins" twice') flickerstreak@23: elseif not self.modules then flickerstreak@23: AceModuleCore:error("Error initializing class. Please report error.") flickerstreak@23: elseif next(self.modules) then flickerstreak@23: AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.') flickerstreak@23: end flickerstreak@23: flickerstreak@23: self.moduleMixins = { ... } flickerstreak@23: for i,v in ipairs(self.moduleMixins) do flickerstreak@23: self.moduleMixins[i] = getlibrary(v) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: -- #NODOC flickerstreak@23: function AceModuleCore:SetModuleClass(class) flickerstreak@23: class = getlibrary(class) flickerstreak@23: if not AceOO.inherits(class, AceOO.Class) then flickerstreak@23: AceModuleCore:error("Bad argument #2 to `SetModuleClass' (Class expected)") flickerstreak@23: end flickerstreak@23: if not self.modules then flickerstreak@23: AceModuleCore:error("Error initializing class. Please report error.") flickerstreak@23: end flickerstreak@23: if self.customModuleClass then flickerstreak@23: AceModuleCore:error("Cannot call `SetModuleClass' twice.") flickerstreak@23: end flickerstreak@23: self.customModuleClass = true flickerstreak@23: self.moduleClass = class flickerstreak@23: self.modulePrototype = class.prototype flickerstreak@23: end flickerstreak@23: flickerstreak@23: local mt = {__index=function(self, key) flickerstreak@23: self[key] = false flickerstreak@23: return false flickerstreak@23: end} flickerstreak@23: local defaultState = setmetatable({}, {__index=function(self, key) flickerstreak@23: local t = setmetatable({}, mt) flickerstreak@23: self[key] = t flickerstreak@23: return t flickerstreak@23: end}) flickerstreak@23: flickerstreak@23: local function isDisabled(core, module) flickerstreak@23: local moduleName flickerstreak@23: if type(module) == "table" then flickerstreak@23: moduleName = module.name flickerstreak@23: else flickerstreak@23: moduleName = module flickerstreak@23: end flickerstreak@23: local disabled flickerstreak@23: if type(module) == "table" and type(module.IsActive) == "function" then flickerstreak@23: return not module:IsActive() flickerstreak@23: elseif AceOO.inherits(core, "AceDB-2.0") then flickerstreak@23: local _,profile = core:GetProfile() flickerstreak@23: disabled = core.db and core.db.raw and core.db.raw.disabledModules and core.db.raw.disabledModules[profile] and core.db.raw.disabledModules[profile][moduleName] flickerstreak@23: else flickerstreak@23: disabled = core.disabledModules and core.disabledModules[moduleName] flickerstreak@23: end flickerstreak@23: if disabled == nil then flickerstreak@23: return defaultState[core][moduleName] flickerstreak@23: else flickerstreak@23: return disabled flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Sets the default active state of a module. This should be called before the ADDON_LOADED of the module. flickerstreak@23: Arguments: flickerstreak@23: string - name of the module. flickerstreak@23: table - reference to the module. flickerstreak@23: boolean - new state. false means disabled by default, true means enabled by default (true is the default). flickerstreak@23: Example: flickerstreak@23: self:SetModuleDefaultState('bank', false) flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:SetModuleDefaultState(module, state) flickerstreak@23: AceModuleCore:argCheck(module, 2, "table", "string") flickerstreak@23: AceModuleCore:argCheck(state, 3, "boolean") flickerstreak@23: flickerstreak@23: if type(module) == "table" then flickerstreak@23: if not self:IsModule(module) then flickerstreak@23: AceModuleCore:error("%q is not a module", module) flickerstreak@23: end flickerstreak@23: module = module.name flickerstreak@23: end flickerstreak@23: flickerstreak@23: defaultState[self][module] = not state flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[---------------------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Toggles the active state of a module. flickerstreak@23: flickerstreak@23: This calls module:ToggleActive([state]) if available. flickerstreak@23: flickerstreak@23: If suspending, This will call :OnDisable() on the module if it is available. Also, it will iterate through the addon's mixins and call :OnEmbedDisable(module) if available. - this in turn will, through AceEvent and others, unregister events/hooks/etc. depending on the mixin. Also, it will call :OnModuleDisable(module) on the core if it is available. flickerstreak@23: flickerstreak@23: If resuming, This will call :OnEnable(first) on the module if it is available. Also, it will iterate through the addon's mixins and call :OnEmbedEnable(module) if available. - this in turn will, through AceEvent and others, unregister events/hooks/etc. depending on the mixin. Also, it will call :OnModuleEnable(module) on the core if it is available. flickerstreak@23: flickerstreak@23: If you call :ToggleModuleActive("name or module, true) and it is already active, it silently returns, same if you pass false and it is inactive. flickerstreak@23: flickerstreak@23: Arguments: flickerstreak@23: string/table - name of the module or a reference to the module flickerstreak@23: [optional] boolean - new state. (default not :IsModuleActive("name" or module)) flickerstreak@23: Returns: flickerstreak@23: * boolean - Whether the module is now in an active (enabled) state. flickerstreak@23: Example: flickerstreak@23: self:ToggleModuleActive('bank') flickerstreak@23: ------------------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:ToggleModuleActive(module, state) flickerstreak@23: AceModuleCore:argCheck(module, 2, "table", "string") flickerstreak@23: AceModuleCore:argCheck(state, 3, "nil", "boolean") flickerstreak@23: flickerstreak@23: if type(module) == "string" then flickerstreak@23: if not self:HasModule(module) then flickerstreak@23: AceModuleCore:error("Cannot find module %q", module) flickerstreak@23: end flickerstreak@23: module = self:GetModule(module) flickerstreak@23: elseif not self:IsModule(module) then flickerstreak@23: AceModuleCore:error("%q is not a module", module) flickerstreak@23: end flickerstreak@23: flickerstreak@23: local disable flickerstreak@23: if state == nil then flickerstreak@23: disable = self:IsModuleActive(module) flickerstreak@23: else flickerstreak@23: disable = not state flickerstreak@23: if disable ~= self:IsModuleActive(module) then flickerstreak@23: return flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: if type(module.ToggleActive) == "function" then flickerstreak@23: return module:ToggleActive(not disable) flickerstreak@23: elseif AceOO.inherits(self, "AceDB-2.0") then flickerstreak@23: if not self.db or not self.db.raw then flickerstreak@23: AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fired.") flickerstreak@23: end flickerstreak@23: if type(self.db.raw.disabledModules) ~= "table" then flickerstreak@23: self.db.raw.disabledModules = {} flickerstreak@23: end flickerstreak@23: local _,profile = self:GetProfile() flickerstreak@23: if type(self.db.raw.disabledModules[profile]) ~= "table" then flickerstreak@23: self.db.raw.disabledModules[profile] = {} flickerstreak@23: end flickerstreak@23: if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then flickerstreak@23: local value = nil flickerstreak@23: if disable ~= defaultState[self][module.name] then flickerstreak@23: value = disable flickerstreak@23: end flickerstreak@23: self.db.raw.disabledModules[profile][module.name] = value flickerstreak@23: end flickerstreak@23: if not disable then flickerstreak@23: if not next(self.db.raw.disabledModules[profile]) then flickerstreak@23: self.db.raw.disabledModules[profile] = nil flickerstreak@23: end flickerstreak@23: if not next(self.db.raw.disabledModules) then flickerstreak@23: self.db.raw.disabledModules = nil flickerstreak@23: end flickerstreak@23: end flickerstreak@23: else flickerstreak@23: if type(self.disabledModules) ~= "table" then flickerstreak@23: self.disabledModules = {} flickerstreak@23: end flickerstreak@23: local value = nil flickerstreak@23: if disable ~= defaultState[self][module.name] then flickerstreak@23: value = disable flickerstreak@23: end flickerstreak@23: self.disabledModules[module.name] = value flickerstreak@23: end flickerstreak@23: if AceOO.inherits(module, "AceAddon-2.0") then flickerstreak@23: if not AceAddon.addonsStarted[module] then flickerstreak@23: return flickerstreak@23: end flickerstreak@23: end flickerstreak@23: if not disable then flickerstreak@23: local first = nil flickerstreak@23: if AceOO.inherits(module, "AceAddon-2.0") then flickerstreak@23: if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[module] then flickerstreak@23: AceAddon.addonsEnabled[module] = true flickerstreak@23: first = true flickerstreak@23: end flickerstreak@23: end flickerstreak@23: local current = module.class flickerstreak@23: while true do flickerstreak@23: if current == AceOO.Class then flickerstreak@23: break flickerstreak@23: end flickerstreak@23: if current.mixins then flickerstreak@23: for mixin in pairs(current.mixins) do flickerstreak@23: if type(mixin.OnEmbedEnable) == "function" then flickerstreak@23: safecall(mixin.OnEmbedEnable, mixin, module, first) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: current = current.super flickerstreak@23: end flickerstreak@23: if type(module.OnEnable) == "function" then flickerstreak@23: safecall(module.OnEnable, module, first) flickerstreak@23: end flickerstreak@23: if AceEvent then flickerstreak@23: AceEvent:TriggerEvent("Ace2_AddonEnabled", module, first) flickerstreak@23: end flickerstreak@23: else flickerstreak@23: local current = module.class flickerstreak@23: while true do flickerstreak@23: if current == AceOO.Class then flickerstreak@23: break flickerstreak@23: end flickerstreak@23: if current.mixins then flickerstreak@23: for mixin in pairs(current.mixins) do flickerstreak@23: if type(mixin.OnEmbedDisable) == "function" then flickerstreak@23: safecall(mixin.OnEmbedDisable, mixin, module) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: current = current.super flickerstreak@23: end flickerstreak@23: if type(module.OnDisable) == "function" then flickerstreak@23: safecall(module.OnDisable, module) flickerstreak@23: end flickerstreak@23: if AceEvent then flickerstreak@23: AceEvent:TriggerEvent("Ace2_AddonDisabled", module) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: return not disable flickerstreak@23: end flickerstreak@23: flickerstreak@23: --[[----------------------------------------------------------------------- flickerstreak@23: Notes: flickerstreak@23: Returns whether the module is in an active (enabled) state. This calls module:IsActive() if available. if notLoaded is set, then "name" must be a string. flickerstreak@23: Arguments: flickerstreak@23: string/table - name of the module or a reference to the module flickerstreak@23: [optional] - boolean - if set, this will check modules that are not loaded as well. (default: false) flickerstreak@23: Returns: flickerstreak@23: * boolean - Whether the module is in an active (enabled) state. flickerstreak@23: Example: flickerstreak@23: assert(self:IsModuleActive('bank')) flickerstreak@23: ------------------------------------------------------------------------]] flickerstreak@23: function AceModuleCore:IsModuleActive(module, notLoaded) flickerstreak@23: AceModuleCore:argCheck(module, 2, "table", "string") flickerstreak@23: AceModuleCore:argCheck(notLoaded, 3, "nil", "boolean") flickerstreak@23: if notLoaded then flickerstreak@23: AceModuleCore:argCheck(module, 2, "string") flickerstreak@23: end flickerstreak@23: flickerstreak@23: if AceModuleCore == self then flickerstreak@23: self:argCheck(module, 2, "table") flickerstreak@23: flickerstreak@23: local core = AceModuleCore.totalModules[module] flickerstreak@23: if not core then flickerstreak@23: self:error("Bad argument #2 to `IsModuleActive'. Not a module") flickerstreak@23: end flickerstreak@23: return core:IsModuleActive(module) flickerstreak@23: end flickerstreak@23: flickerstreak@23: if type(module) == "string" then flickerstreak@23: if not notLoaded and not self:HasModule(module) then flickerstreak@23: AceModuleCore:error("Cannot find module %q", module) flickerstreak@23: end flickerstreak@23: if not notLoaded then flickerstreak@23: module = self:GetModule(module) flickerstreak@23: else flickerstreak@23: module = self:HasModule(module) and self:GetModule(module) or module flickerstreak@23: end flickerstreak@23: else flickerstreak@23: if not self:IsModule(module) then flickerstreak@23: AceModuleCore:error("%q is not a module", module) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: return not isDisabled(self, module) flickerstreak@23: end flickerstreak@23: flickerstreak@23: -- #NODOC flickerstreak@23: function AceModuleCore:OnInstanceInit(target) flickerstreak@23: if target.modules then flickerstreak@23: do return end flickerstreak@23: AceModuleCore:error("OnInstanceInit cannot be called twice") flickerstreak@23: end flickerstreak@23: flickerstreak@23: if not AceAddon then flickerstreak@23: if AceLibrary:HasInstance("AceAddon-2.0") then flickerstreak@23: AceAddon = AceLibrary("AceAddon-2.0") flickerstreak@23: else flickerstreak@23: self:error(MAJOR_VERSION .. " requires AceAddon-2.0") flickerstreak@23: end flickerstreak@23: end flickerstreak@23: target.modules = {} flickerstreak@23: flickerstreak@23: target.moduleClass = AceOO.Class("AceAddon-2.0") flickerstreak@23: target.modulePrototype = target.moduleClass.prototype flickerstreak@23: end flickerstreak@23: flickerstreak@23: AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit flickerstreak@23: flickerstreak@23: function AceModuleCore.OnEmbedProfileDisable(AceModuleCore, self, newProfile) flickerstreak@23: if not AceOO.inherits(self, "AceDB-2.0") then flickerstreak@23: return flickerstreak@23: end flickerstreak@23: local _,currentProfile = self:GetProfile() flickerstreak@23: for k, module in pairs(self.modules) do flickerstreak@23: if type(module.IsActive) == "function" or type(module.ToggleActive) == "function" then flickerstreak@23: -- continue flickerstreak@23: else flickerstreak@23: local currentActive = not self.db or not self.db.raw or not self.db.raw.disabledModules or not self.db.raw.disabledModules[currentProfile] or not self.db.raw.disabledModules[currentProfile][module.name] flickerstreak@23: local newActive = not self.db or not self.db.raw or not self.db.raw.disabledModules or not self.db.raw.disabledModules[newProfile] or not self.db.raw.disabledModules[newProfile][module.name] flickerstreak@23: if currentActive ~= newActive then flickerstreak@23: self:ToggleModuleActive(module) flickerstreak@23: if not self.db.raw.disabledModules then flickerstreak@23: self.db.raw.disabledModules = {} flickerstreak@23: end flickerstreak@23: if not self.db.raw.disabledModules[currentProfile] then flickerstreak@23: self.db.raw.disabledModules[currentProfile] = {} flickerstreak@23: end flickerstreak@23: self.db.raw.disabledModules[currentProfile][module.name] = not currentActive or nil flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: -- #NODOC flickerstreak@23: function AceModuleCore:Ace2_AddonEnabled(module, first) flickerstreak@23: local addon = self.totalModules[module] flickerstreak@23: if not addon then flickerstreak@23: return flickerstreak@23: end flickerstreak@23: flickerstreak@23: if modulesWithMethod[addon] then flickerstreak@23: for k,v in pairs(modulesWithMethod[addon]) do flickerstreak@23: modulesWithMethod[addon] = del(v) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: if type(addon.OnModuleEnable) == "function" then flickerstreak@23: safecall(addon.OnModuleEnable, addon, module, first) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: -- #NODOC flickerstreak@23: function AceModuleCore:Ace2_AddonDisabled(module) flickerstreak@23: local addon = self.totalModules[module] flickerstreak@23: if not addon then flickerstreak@23: return flickerstreak@23: end flickerstreak@23: flickerstreak@23: if modulesWithMethod[addon] then flickerstreak@23: for k,v in pairs(modulesWithMethod[addon]) do flickerstreak@23: modulesWithMethod[addon] = del(v) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: if type(addon.OnModuleDisable) == "function" then flickerstreak@23: safecall(addon.OnModuleDisable, addon, module) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local function activate(self, oldLib, oldDeactivate) flickerstreak@23: AceModuleCore = self flickerstreak@23: flickerstreak@23: self.totalModules = oldLib and oldLib.totalModules or {} flickerstreak@23: flickerstreak@23: self:activate(oldLib, oldDeactivate) flickerstreak@23: flickerstreak@23: if oldDeactivate then flickerstreak@23: oldDeactivate(oldLib) flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: local function external(self, major, instance) flickerstreak@23: if major == "AceEvent-2.0" then flickerstreak@23: AceEvent = instance flickerstreak@23: AceEvent:embed(self) flickerstreak@23: flickerstreak@23: self:UnregisterAllEvents() flickerstreak@23: self:RegisterEvent("Ace2_AddonEnabled") flickerstreak@23: self:RegisterEvent("Ace2_AddonDisabled") flickerstreak@23: elseif major == "AceAddon-2.0" then flickerstreak@23: AceAddon = instance flickerstreak@23: end flickerstreak@23: end flickerstreak@23: flickerstreak@23: AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate, nil, external) flickerstreak@23: AceModuleCore = AceLibrary(MAJOR_VERSION)