Mercurial > wow > reaction
diff libs/AceModuleCore-2.0/AceModuleCore-2.0.lua @ 1:c11ca1d8ed91
Version 0.1
author | Flick <flickerstreak@gmail.com> |
---|---|
date | Tue, 20 Mar 2007 21:03:57 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libs/AceModuleCore-2.0/AceModuleCore-2.0.lua Tue Mar 20 21:03:57 2007 +0000 @@ -0,0 +1,377 @@ +--[[ +Name: AceModuleCore-2.0 +Revision: $Rev: 18708 $ +Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team) +Inspired By: Ace 1.x by Turan (turan@gryphon.com) +Website: http://www.wowace.com/ +Documentation: http://www.wowace.com/index.php/AceModuleCore-2.0 +SVN: http://svn.wowace.com/root/trunk/Ace2/AceModuleCore-2.0 +Description: Mixin to provide a module system so that modules or plugins can + use an addon as its core. +Dependencies: AceLibrary, AceOO-2.0, AceAddon-2.0, AceEvent-2.0 (optional) +]] + +local MAJOR_VERSION = "AceModuleCore-2.0" +local MINOR_VERSION = "$Revision: 18708 $" + +if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end +if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end + +if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end + +local function safecall(func, ...) + local success, err = pcall(func, ...) + if not success then geterrorhandler()(err) end +end + +local AceEvent +local AceOO = AceLibrary:GetInstance("AceOO-2.0") +local AceModuleCore = AceOO.Mixin { + "NewModule", + "HasModule", + "GetModule", + "IsModule", + "IterateModules", + "SetModuleMixins", + "SetModuleClass", + "IsModuleActive", + "ToggleModuleActive" + } + +local function getlibrary(lib) + if type(lib) == "string" then + return AceLibrary(lib) + else + return lib + end +end + +local tmp = {} +function AceModuleCore:NewModule(name, ...) + if not self.modules then + AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2) + end + AceModuleCore:argCheck(name, 2, "string") + if string.len(name) == 0 then + AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty") + end + if self.modules[name] then + AceModuleCore:error("The module %q has already been registered", name) + end + + for i = 1, select('#', ...) do + tmp[i] = getlibrary((select(i, ...))) + end + + if self.moduleMixins then + for _,mixin in ipairs(self.moduleMixins) do + local exists = false + for _,v in ipairs(tmp) do + if mixin == v then + exists = true + break + end + end + if not exists then + table.insert(tmp, mixin) + end + end + end + + local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name) + self.modules[name] = module + module.name = name + module.title = name + + AceModuleCore.totalModules[module] = self + + if AceEvent then + AceEvent:TriggerEvent("Ace2_ModuleCreated", module) + end + + local num = #tmp + for i = 1, num do + tmp[i] = nil + end + return module +end + +function AceModuleCore:HasModule(...) + for i = 1, select('#', ...) do + if not self.modules[select(i, ...)] then + return false + end + end + + return true +end + +function AceModuleCore:GetModule(name) + if not self.modules then + AceModuleCore:error("Error initializing class. Please report error.") + end + if not self.modules[name] then + AceModuleCore:error("Cannot find module %q.", name) + end + return self.modules[name] +end + +function AceModuleCore:IsModule(module) + if self == AceModuleCore then + return AceModuleCore.totalModules[module] + else + for k,v in pairs(self.modules) do + if v == module then + return true + end + end + return false + end +end + +function AceModuleCore:IterateModules() + local t = {} + for k in pairs(self.modules) do + table.insert(t, k) + end + table.sort(t) + local i = 0 + return function() + i = i + 1 + local x = t[i] + if x then + return x, self.modules[x] + else + t = nil + return nil + end + end, nil, nil +end + +function AceModuleCore:SetModuleMixins(...) + if self.moduleMixins then + AceModuleCore:error('Cannot call "SetModuleMixins" twice') + elseif not self.modules then + AceModuleCore:error("Error initializing class. Please report error.") + elseif next(self.modules) then + AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.') + end + + self.moduleMixins = { ... } + for i,v in ipairs(self.moduleMixins) do + self.moduleMixins[i] = getlibrary(v) + end +end + +function AceModuleCore:SetModuleClass(class) + class = getlibrary(class) + AceModuleCore:assert(AceOO.inherits(class, AceOO.Class), "Bad argument #2 to `SetModuleClass' (Class expected)") + if not self.modules then + AceModuleCore:error("Error initializing class. Please report error.") + end + if self.customModuleClass then + AceModuleCore:error("Cannot call `SetModuleClass' twice.") + end + self.customModuleClass = true + self.moduleClass = class + self.modulePrototype = class.prototype +end + +function AceModuleCore:ToggleModuleActive(module, state) + AceModuleCore:argCheck(module, 2, "table", "string") + AceModuleCore:argCheck(state, 3, "nil", "boolean") + + if type(module) == "string" then + if not self:HasModule(module) then + AceModuleCore:error("Cannot find module %q", module) + end + module = self:GetModule(module) + else + if not self:IsModule(module) then + AceModuleCore:error("%q is not a module", module) + end + end + + local disable + if state == nil then + disable = self:IsModuleActive(module) + else + disable = not state + if disable ~= self:IsModuleActive(module) then + return + end + end + + if type(module.ToggleActive) == "function" then + return module:ToggleActive(not disable) + elseif AceOO.inherits(self, "AceDB-2.0") then + if not self.db or not self.db.raw then + AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fired.") + end + if type(self.db.raw.disabledModules) ~= "table" then + self.db.raw.disabledModules = {} + end + local _,profile = self:GetProfile() + if type(self.db.raw.disabledModules[profile]) ~= "table" then + self.db.raw.disabledModules[profile] = {} + end + if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then + self.db.raw.disabledModules[profile][module.name] = disable or nil + end + if not disable then + if not next(self.db.raw.disabledModules[profile]) then + self.db.raw.disabledModules[profile] = nil + end + if not next(self.db.raw.disabledModules) then + self.db.raw.disabledModules = nil + end + end + else + if type(self.disabledModules) ~= "table" then + self.disabledModules = {} + end + self.disabledModules[module.name] = disable or nil + end + if AceOO.inherits(module, "AceAddon-2.0") then + local AceAddon = AceLibrary("AceAddon-2.0") + if not AceAddon.addonsStarted[module] then + return + end + end + if not disable then + local current = module.class + while true do + if current == AceOO.Class then + break + end + if current.mixins then + for mixin in pairs(current.mixins) do + if type(mixin.OnEmbedEnable) == "function" then + safecall(mixin.OnEmbedEnable, mixin, module) + end + end + end + current = current.super + end + if type(module.OnEnable) == "function" then + safecall(module.OnEnable, module) + end + if AceEvent then + AceEvent:TriggerEvent("Ace2_AddonEnabled", module) + end + else + local current = module.class + while true do + if current == AceOO.Class then + break + end + if current.mixins then + for mixin in pairs(current.mixins) do + if type(mixin.OnEmbedDisable) == "function" then + safecall(mixin.OnEmbedDisable, mixin, module) + end + end + end + current = current.super + end + if type(module.OnDisable) == "function" then + safecall(module.OnDisable, module) + end + if AceEvent then + AceEvent:TriggerEvent("Ace2_AddonDisabled", module) + end + end + return not disable +end + +function AceModuleCore:IsModuleActive(module) + AceModuleCore:argCheck(module, 2, "table", "string") + + if AceModuleCore == self then + self:argCheck(module, 2, "table") + + local core = AceModuleCore.totalModules[module] + if not core then + self:error("Bad argument #2 to `IsModuleActive'. Not a module") + end + return core:IsModuleActive(module) + end + + if type(module) == "string" then + if not self:HasModule(module) then + AceModuleCore:error("Cannot find module %q", module) + end + module = self:GetModule(module) + else + if not self:IsModule(module) then + AceModuleCore:error("%q is not a module", module) + end + end + + if type(module.IsActive) == "function" then + return module:IsActive() + elseif AceOO.inherits(self, "AceDB-2.0") then + local _,profile = self:GetProfile() + return not self.db or not self.db.raw or not self.db.raw.disabledModules or not self.db.raw.disabledModules[profile] or not self.db.raw.disabledModules[profile][module.name] + else + return not self.disabledModules or not self.disabledModules[module.name] + end +end + +function AceModuleCore:OnInstanceInit(target) + if target.modules then + AceModuleCore:error("OnInstanceInit cannot be called twice") + end + target.modules = {} + + target.moduleClass = AceOO.Class("AceAddon-2.0") + target.modulePrototype = target.moduleClass.prototype +end + +AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit + +function AceModuleCore.OnEmbedProfileDisable(AceModuleCore, self, newProfile) + if not AceOO.inherits(self, "AceDB-2.0") then + return + end + local _,currentProfile = self:GetProfile() + for k, module in pairs(self.modules) do + if type(module.IsActive) == "function" or type(module.ToggleActive) == "function" then + -- continue + else + 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] + 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] + if currentActive ~= newActive then + self:ToggleModuleActive(module) + if not self.db.raw.disabledModules then + self.db.raw.disabledModules = {} + end + if not self.db.raw.disabledModules[currentProfile] then + self.db.raw.disabledModules[currentProfile] = {} + end + self.db.raw.disabledModules[currentProfile][module.name] = not currentActive or nil + end + end + end +end + +local function activate(self, oldLib, oldDeactivate) + AceModuleCore = self + + self.totalModules = oldLib and oldLib.totalModules or {} + + self:activate(oldLib, oldDeactivate) + + if oldDeactivate then + oldDeactivate(oldLib) + end +end + +local function external(self, major, instance) + if major == "AceEvent-2.0" then + AceEvent = instance + end +end + +AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate, nil, external) +AceModuleCore = AceLibrary(MAJOR_VERSION)