annotate 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
rev   line source
flickerstreak@1 1 --[[
flickerstreak@1 2 Name: AceModuleCore-2.0
flickerstreak@1 3 Revision: $Rev: 18708 $
flickerstreak@1 4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
flickerstreak@1 5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
flickerstreak@1 6 Website: http://www.wowace.com/
flickerstreak@1 7 Documentation: http://www.wowace.com/index.php/AceModuleCore-2.0
flickerstreak@1 8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceModuleCore-2.0
flickerstreak@1 9 Description: Mixin to provide a module system so that modules or plugins can
flickerstreak@1 10 use an addon as its core.
flickerstreak@1 11 Dependencies: AceLibrary, AceOO-2.0, AceAddon-2.0, AceEvent-2.0 (optional)
flickerstreak@1 12 ]]
flickerstreak@1 13
flickerstreak@1 14 local MAJOR_VERSION = "AceModuleCore-2.0"
flickerstreak@1 15 local MINOR_VERSION = "$Revision: 18708 $"
flickerstreak@1 16
flickerstreak@1 17 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
flickerstreak@1 18 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
flickerstreak@1 19
flickerstreak@1 20 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
flickerstreak@1 21
flickerstreak@1 22 local function safecall(func, ...)
flickerstreak@1 23 local success, err = pcall(func, ...)
flickerstreak@1 24 if not success then geterrorhandler()(err) end
flickerstreak@1 25 end
flickerstreak@1 26
flickerstreak@1 27 local AceEvent
flickerstreak@1 28 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
flickerstreak@1 29 local AceModuleCore = AceOO.Mixin {
flickerstreak@1 30 "NewModule",
flickerstreak@1 31 "HasModule",
flickerstreak@1 32 "GetModule",
flickerstreak@1 33 "IsModule",
flickerstreak@1 34 "IterateModules",
flickerstreak@1 35 "SetModuleMixins",
flickerstreak@1 36 "SetModuleClass",
flickerstreak@1 37 "IsModuleActive",
flickerstreak@1 38 "ToggleModuleActive"
flickerstreak@1 39 }
flickerstreak@1 40
flickerstreak@1 41 local function getlibrary(lib)
flickerstreak@1 42 if type(lib) == "string" then
flickerstreak@1 43 return AceLibrary(lib)
flickerstreak@1 44 else
flickerstreak@1 45 return lib
flickerstreak@1 46 end
flickerstreak@1 47 end
flickerstreak@1 48
flickerstreak@1 49 local tmp = {}
flickerstreak@1 50 function AceModuleCore:NewModule(name, ...)
flickerstreak@1 51 if not self.modules then
flickerstreak@1 52 AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2)
flickerstreak@1 53 end
flickerstreak@1 54 AceModuleCore:argCheck(name, 2, "string")
flickerstreak@1 55 if string.len(name) == 0 then
flickerstreak@1 56 AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty")
flickerstreak@1 57 end
flickerstreak@1 58 if self.modules[name] then
flickerstreak@1 59 AceModuleCore:error("The module %q has already been registered", name)
flickerstreak@1 60 end
flickerstreak@1 61
flickerstreak@1 62 for i = 1, select('#', ...) do
flickerstreak@1 63 tmp[i] = getlibrary((select(i, ...)))
flickerstreak@1 64 end
flickerstreak@1 65
flickerstreak@1 66 if self.moduleMixins then
flickerstreak@1 67 for _,mixin in ipairs(self.moduleMixins) do
flickerstreak@1 68 local exists = false
flickerstreak@1 69 for _,v in ipairs(tmp) do
flickerstreak@1 70 if mixin == v then
flickerstreak@1 71 exists = true
flickerstreak@1 72 break
flickerstreak@1 73 end
flickerstreak@1 74 end
flickerstreak@1 75 if not exists then
flickerstreak@1 76 table.insert(tmp, mixin)
flickerstreak@1 77 end
flickerstreak@1 78 end
flickerstreak@1 79 end
flickerstreak@1 80
flickerstreak@1 81 local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name)
flickerstreak@1 82 self.modules[name] = module
flickerstreak@1 83 module.name = name
flickerstreak@1 84 module.title = name
flickerstreak@1 85
flickerstreak@1 86 AceModuleCore.totalModules[module] = self
flickerstreak@1 87
flickerstreak@1 88 if AceEvent then
flickerstreak@1 89 AceEvent:TriggerEvent("Ace2_ModuleCreated", module)
flickerstreak@1 90 end
flickerstreak@1 91
flickerstreak@1 92 local num = #tmp
flickerstreak@1 93 for i = 1, num do
flickerstreak@1 94 tmp[i] = nil
flickerstreak@1 95 end
flickerstreak@1 96 return module
flickerstreak@1 97 end
flickerstreak@1 98
flickerstreak@1 99 function AceModuleCore:HasModule(...)
flickerstreak@1 100 for i = 1, select('#', ...) do
flickerstreak@1 101 if not self.modules[select(i, ...)] then
flickerstreak@1 102 return false
flickerstreak@1 103 end
flickerstreak@1 104 end
flickerstreak@1 105
flickerstreak@1 106 return true
flickerstreak@1 107 end
flickerstreak@1 108
flickerstreak@1 109 function AceModuleCore:GetModule(name)
flickerstreak@1 110 if not self.modules then
flickerstreak@1 111 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@1 112 end
flickerstreak@1 113 if not self.modules[name] then
flickerstreak@1 114 AceModuleCore:error("Cannot find module %q.", name)
flickerstreak@1 115 end
flickerstreak@1 116 return self.modules[name]
flickerstreak@1 117 end
flickerstreak@1 118
flickerstreak@1 119 function AceModuleCore:IsModule(module)
flickerstreak@1 120 if self == AceModuleCore then
flickerstreak@1 121 return AceModuleCore.totalModules[module]
flickerstreak@1 122 else
flickerstreak@1 123 for k,v in pairs(self.modules) do
flickerstreak@1 124 if v == module then
flickerstreak@1 125 return true
flickerstreak@1 126 end
flickerstreak@1 127 end
flickerstreak@1 128 return false
flickerstreak@1 129 end
flickerstreak@1 130 end
flickerstreak@1 131
flickerstreak@1 132 function AceModuleCore:IterateModules()
flickerstreak@1 133 local t = {}
flickerstreak@1 134 for k in pairs(self.modules) do
flickerstreak@1 135 table.insert(t, k)
flickerstreak@1 136 end
flickerstreak@1 137 table.sort(t)
flickerstreak@1 138 local i = 0
flickerstreak@1 139 return function()
flickerstreak@1 140 i = i + 1
flickerstreak@1 141 local x = t[i]
flickerstreak@1 142 if x then
flickerstreak@1 143 return x, self.modules[x]
flickerstreak@1 144 else
flickerstreak@1 145 t = nil
flickerstreak@1 146 return nil
flickerstreak@1 147 end
flickerstreak@1 148 end, nil, nil
flickerstreak@1 149 end
flickerstreak@1 150
flickerstreak@1 151 function AceModuleCore:SetModuleMixins(...)
flickerstreak@1 152 if self.moduleMixins then
flickerstreak@1 153 AceModuleCore:error('Cannot call "SetModuleMixins" twice')
flickerstreak@1 154 elseif not self.modules then
flickerstreak@1 155 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@1 156 elseif next(self.modules) then
flickerstreak@1 157 AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.')
flickerstreak@1 158 end
flickerstreak@1 159
flickerstreak@1 160 self.moduleMixins = { ... }
flickerstreak@1 161 for i,v in ipairs(self.moduleMixins) do
flickerstreak@1 162 self.moduleMixins[i] = getlibrary(v)
flickerstreak@1 163 end
flickerstreak@1 164 end
flickerstreak@1 165
flickerstreak@1 166 function AceModuleCore:SetModuleClass(class)
flickerstreak@1 167 class = getlibrary(class)
flickerstreak@1 168 AceModuleCore:assert(AceOO.inherits(class, AceOO.Class), "Bad argument #2 to `SetModuleClass' (Class expected)")
flickerstreak@1 169 if not self.modules then
flickerstreak@1 170 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@1 171 end
flickerstreak@1 172 if self.customModuleClass then
flickerstreak@1 173 AceModuleCore:error("Cannot call `SetModuleClass' twice.")
flickerstreak@1 174 end
flickerstreak@1 175 self.customModuleClass = true
flickerstreak@1 176 self.moduleClass = class
flickerstreak@1 177 self.modulePrototype = class.prototype
flickerstreak@1 178 end
flickerstreak@1 179
flickerstreak@1 180 function AceModuleCore:ToggleModuleActive(module, state)
flickerstreak@1 181 AceModuleCore:argCheck(module, 2, "table", "string")
flickerstreak@1 182 AceModuleCore:argCheck(state, 3, "nil", "boolean")
flickerstreak@1 183
flickerstreak@1 184 if type(module) == "string" then
flickerstreak@1 185 if not self:HasModule(module) then
flickerstreak@1 186 AceModuleCore:error("Cannot find module %q", module)
flickerstreak@1 187 end
flickerstreak@1 188 module = self:GetModule(module)
flickerstreak@1 189 else
flickerstreak@1 190 if not self:IsModule(module) then
flickerstreak@1 191 AceModuleCore:error("%q is not a module", module)
flickerstreak@1 192 end
flickerstreak@1 193 end
flickerstreak@1 194
flickerstreak@1 195 local disable
flickerstreak@1 196 if state == nil then
flickerstreak@1 197 disable = self:IsModuleActive(module)
flickerstreak@1 198 else
flickerstreak@1 199 disable = not state
flickerstreak@1 200 if disable ~= self:IsModuleActive(module) then
flickerstreak@1 201 return
flickerstreak@1 202 end
flickerstreak@1 203 end
flickerstreak@1 204
flickerstreak@1 205 if type(module.ToggleActive) == "function" then
flickerstreak@1 206 return module:ToggleActive(not disable)
flickerstreak@1 207 elseif AceOO.inherits(self, "AceDB-2.0") then
flickerstreak@1 208 if not self.db or not self.db.raw then
flickerstreak@1 209 AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fired.")
flickerstreak@1 210 end
flickerstreak@1 211 if type(self.db.raw.disabledModules) ~= "table" then
flickerstreak@1 212 self.db.raw.disabledModules = {}
flickerstreak@1 213 end
flickerstreak@1 214 local _,profile = self:GetProfile()
flickerstreak@1 215 if type(self.db.raw.disabledModules[profile]) ~= "table" then
flickerstreak@1 216 self.db.raw.disabledModules[profile] = {}
flickerstreak@1 217 end
flickerstreak@1 218 if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then
flickerstreak@1 219 self.db.raw.disabledModules[profile][module.name] = disable or nil
flickerstreak@1 220 end
flickerstreak@1 221 if not disable then
flickerstreak@1 222 if not next(self.db.raw.disabledModules[profile]) then
flickerstreak@1 223 self.db.raw.disabledModules[profile] = nil
flickerstreak@1 224 end
flickerstreak@1 225 if not next(self.db.raw.disabledModules) then
flickerstreak@1 226 self.db.raw.disabledModules = nil
flickerstreak@1 227 end
flickerstreak@1 228 end
flickerstreak@1 229 else
flickerstreak@1 230 if type(self.disabledModules) ~= "table" then
flickerstreak@1 231 self.disabledModules = {}
flickerstreak@1 232 end
flickerstreak@1 233 self.disabledModules[module.name] = disable or nil
flickerstreak@1 234 end
flickerstreak@1 235 if AceOO.inherits(module, "AceAddon-2.0") then
flickerstreak@1 236 local AceAddon = AceLibrary("AceAddon-2.0")
flickerstreak@1 237 if not AceAddon.addonsStarted[module] then
flickerstreak@1 238 return
flickerstreak@1 239 end
flickerstreak@1 240 end
flickerstreak@1 241 if not disable then
flickerstreak@1 242 local current = module.class
flickerstreak@1 243 while true do
flickerstreak@1 244 if current == AceOO.Class then
flickerstreak@1 245 break
flickerstreak@1 246 end
flickerstreak@1 247 if current.mixins then
flickerstreak@1 248 for mixin in pairs(current.mixins) do
flickerstreak@1 249 if type(mixin.OnEmbedEnable) == "function" then
flickerstreak@1 250 safecall(mixin.OnEmbedEnable, mixin, module)
flickerstreak@1 251 end
flickerstreak@1 252 end
flickerstreak@1 253 end
flickerstreak@1 254 current = current.super
flickerstreak@1 255 end
flickerstreak@1 256 if type(module.OnEnable) == "function" then
flickerstreak@1 257 safecall(module.OnEnable, module)
flickerstreak@1 258 end
flickerstreak@1 259 if AceEvent then
flickerstreak@1 260 AceEvent:TriggerEvent("Ace2_AddonEnabled", module)
flickerstreak@1 261 end
flickerstreak@1 262 else
flickerstreak@1 263 local current = module.class
flickerstreak@1 264 while true do
flickerstreak@1 265 if current == AceOO.Class then
flickerstreak@1 266 break
flickerstreak@1 267 end
flickerstreak@1 268 if current.mixins then
flickerstreak@1 269 for mixin in pairs(current.mixins) do
flickerstreak@1 270 if type(mixin.OnEmbedDisable) == "function" then
flickerstreak@1 271 safecall(mixin.OnEmbedDisable, mixin, module)
flickerstreak@1 272 end
flickerstreak@1 273 end
flickerstreak@1 274 end
flickerstreak@1 275 current = current.super
flickerstreak@1 276 end
flickerstreak@1 277 if type(module.OnDisable) == "function" then
flickerstreak@1 278 safecall(module.OnDisable, module)
flickerstreak@1 279 end
flickerstreak@1 280 if AceEvent then
flickerstreak@1 281 AceEvent:TriggerEvent("Ace2_AddonDisabled", module)
flickerstreak@1 282 end
flickerstreak@1 283 end
flickerstreak@1 284 return not disable
flickerstreak@1 285 end
flickerstreak@1 286
flickerstreak@1 287 function AceModuleCore:IsModuleActive(module)
flickerstreak@1 288 AceModuleCore:argCheck(module, 2, "table", "string")
flickerstreak@1 289
flickerstreak@1 290 if AceModuleCore == self then
flickerstreak@1 291 self:argCheck(module, 2, "table")
flickerstreak@1 292
flickerstreak@1 293 local core = AceModuleCore.totalModules[module]
flickerstreak@1 294 if not core then
flickerstreak@1 295 self:error("Bad argument #2 to `IsModuleActive'. Not a module")
flickerstreak@1 296 end
flickerstreak@1 297 return core:IsModuleActive(module)
flickerstreak@1 298 end
flickerstreak@1 299
flickerstreak@1 300 if type(module) == "string" then
flickerstreak@1 301 if not self:HasModule(module) then
flickerstreak@1 302 AceModuleCore:error("Cannot find module %q", module)
flickerstreak@1 303 end
flickerstreak@1 304 module = self:GetModule(module)
flickerstreak@1 305 else
flickerstreak@1 306 if not self:IsModule(module) then
flickerstreak@1 307 AceModuleCore:error("%q is not a module", module)
flickerstreak@1 308 end
flickerstreak@1 309 end
flickerstreak@1 310
flickerstreak@1 311 if type(module.IsActive) == "function" then
flickerstreak@1 312 return module:IsActive()
flickerstreak@1 313 elseif AceOO.inherits(self, "AceDB-2.0") then
flickerstreak@1 314 local _,profile = self:GetProfile()
flickerstreak@1 315 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]
flickerstreak@1 316 else
flickerstreak@1 317 return not self.disabledModules or not self.disabledModules[module.name]
flickerstreak@1 318 end
flickerstreak@1 319 end
flickerstreak@1 320
flickerstreak@1 321 function AceModuleCore:OnInstanceInit(target)
flickerstreak@1 322 if target.modules then
flickerstreak@1 323 AceModuleCore:error("OnInstanceInit cannot be called twice")
flickerstreak@1 324 end
flickerstreak@1 325 target.modules = {}
flickerstreak@1 326
flickerstreak@1 327 target.moduleClass = AceOO.Class("AceAddon-2.0")
flickerstreak@1 328 target.modulePrototype = target.moduleClass.prototype
flickerstreak@1 329 end
flickerstreak@1 330
flickerstreak@1 331 AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit
flickerstreak@1 332
flickerstreak@1 333 function AceModuleCore.OnEmbedProfileDisable(AceModuleCore, self, newProfile)
flickerstreak@1 334 if not AceOO.inherits(self, "AceDB-2.0") then
flickerstreak@1 335 return
flickerstreak@1 336 end
flickerstreak@1 337 local _,currentProfile = self:GetProfile()
flickerstreak@1 338 for k, module in pairs(self.modules) do
flickerstreak@1 339 if type(module.IsActive) == "function" or type(module.ToggleActive) == "function" then
flickerstreak@1 340 -- continue
flickerstreak@1 341 else
flickerstreak@1 342 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@1 343 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@1 344 if currentActive ~= newActive then
flickerstreak@1 345 self:ToggleModuleActive(module)
flickerstreak@1 346 if not self.db.raw.disabledModules then
flickerstreak@1 347 self.db.raw.disabledModules = {}
flickerstreak@1 348 end
flickerstreak@1 349 if not self.db.raw.disabledModules[currentProfile] then
flickerstreak@1 350 self.db.raw.disabledModules[currentProfile] = {}
flickerstreak@1 351 end
flickerstreak@1 352 self.db.raw.disabledModules[currentProfile][module.name] = not currentActive or nil
flickerstreak@1 353 end
flickerstreak@1 354 end
flickerstreak@1 355 end
flickerstreak@1 356 end
flickerstreak@1 357
flickerstreak@1 358 local function activate(self, oldLib, oldDeactivate)
flickerstreak@1 359 AceModuleCore = self
flickerstreak@1 360
flickerstreak@1 361 self.totalModules = oldLib and oldLib.totalModules or {}
flickerstreak@1 362
flickerstreak@1 363 self:activate(oldLib, oldDeactivate)
flickerstreak@1 364
flickerstreak@1 365 if oldDeactivate then
flickerstreak@1 366 oldDeactivate(oldLib)
flickerstreak@1 367 end
flickerstreak@1 368 end
flickerstreak@1 369
flickerstreak@1 370 local function external(self, major, instance)
flickerstreak@1 371 if major == "AceEvent-2.0" then
flickerstreak@1 372 AceEvent = instance
flickerstreak@1 373 end
flickerstreak@1 374 end
flickerstreak@1 375
flickerstreak@1 376 AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
flickerstreak@1 377 AceModuleCore = AceLibrary(MAJOR_VERSION)