annotate lib/AceModuleCore-2.0/AceModuleCore-2.0.lua @ 26:261f0f6bd68a

rearranged file include XMLs
author Flick <flickerstreak@gmail.com>
date Fri, 07 Mar 2008 22:20:30 +0000
parents dba04d85c799
children
rev   line source
flickerstreak@23 1 --[[
flickerstreak@23 2 Name: AceModuleCore-2.0
flickerstreak@23 3 Revision: $Rev: 43318 $
flickerstreak@23 4 Developed by: The Ace Development Team (http://www.wowace.com/index.php/The_Ace_Development_Team)
flickerstreak@23 5 Inspired By: Ace 1.x by Turan (turan@gryphon.com)
flickerstreak@23 6 Website: http://www.wowace.com/
flickerstreak@23 7 Documentation: http://www.wowace.com/index.php/AceModuleCore-2.0
flickerstreak@23 8 SVN: http://svn.wowace.com/root/trunk/Ace2/AceModuleCore-2.0
flickerstreak@23 9 Description: Mixin to provide a module system so that modules or plugins can
flickerstreak@23 10 use an addon as its core.
flickerstreak@23 11 Dependencies: AceLibrary, AceOO-2.0, AceAddon-2.0, AceEvent-2.0 (optional)
flickerstreak@23 12 License: LGPL v2.1
flickerstreak@23 13 ]]
flickerstreak@23 14
flickerstreak@23 15 local MAJOR_VERSION = "AceModuleCore-2.0"
flickerstreak@23 16 local MINOR_VERSION = "$Revision: 43318 $"
flickerstreak@23 17
flickerstreak@23 18 if not AceLibrary then error(MAJOR_VERSION .. " requires AceLibrary") end
flickerstreak@23 19 if not AceLibrary:IsNewVersion(MAJOR_VERSION, MINOR_VERSION) then return end
flickerstreak@23 20
flickerstreak@23 21 if not AceLibrary:HasInstance("AceOO-2.0") then error(MAJOR_VERSION .. " requires AceOO-2.0") end
flickerstreak@23 22
flickerstreak@23 23 local function safecall(func, ...)
flickerstreak@23 24 local success, err = pcall(func, ...)
flickerstreak@23 25 if not success then geterrorhandler()(err:find("%.lua:%d+:") and err or (debugstack():match("\n(.-: )in.-\n") or "") .. err) end
flickerstreak@23 26 end
flickerstreak@23 27
flickerstreak@23 28 local AceEvent
flickerstreak@23 29 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
flickerstreak@23 30 local AceModuleCore = AceOO.Mixin {
flickerstreak@23 31 "NewModule",
flickerstreak@23 32 "HasModule",
flickerstreak@23 33 "GetModule",
flickerstreak@23 34 "IsModule",
flickerstreak@23 35 "IterateModules",
flickerstreak@23 36 "IterateModulesWithMethod",
flickerstreak@23 37 "CallMethodOnAllModules",
flickerstreak@23 38 "SetModuleMixins",
flickerstreak@23 39 "SetModuleClass",
flickerstreak@23 40 "IsModuleActive",
flickerstreak@23 41 "ToggleModuleActive",
flickerstreak@23 42 "SetModuleDefaultState",
flickerstreak@23 43 }
flickerstreak@23 44 local AceAddon
flickerstreak@23 45
flickerstreak@23 46 local function getlibrary(lib)
flickerstreak@23 47 if type(lib) == "string" then
flickerstreak@23 48 return AceLibrary(lib)
flickerstreak@23 49 else
flickerstreak@23 50 return lib
flickerstreak@23 51 end
flickerstreak@23 52 end
flickerstreak@23 53
flickerstreak@23 54 local new, del
flickerstreak@23 55 do
flickerstreak@23 56 local list = setmetatable({}, {__mode='k'})
flickerstreak@23 57 function new()
flickerstreak@23 58 local t = next(list)
flickerstreak@23 59 if t then
flickerstreak@23 60 list[t] = nil
flickerstreak@23 61 return t
flickerstreak@23 62 else
flickerstreak@23 63 return {}
flickerstreak@23 64 end
flickerstreak@23 65 end
flickerstreak@23 66 function del(t)
flickerstreak@23 67 for k in pairs(t) do
flickerstreak@23 68 t[k] = nil
flickerstreak@23 69 end
flickerstreak@23 70 list[t] = true
flickerstreak@23 71 return nil
flickerstreak@23 72 end
flickerstreak@23 73 end
flickerstreak@23 74
flickerstreak@23 75 local iterList = setmetatable({}, {__mode='v'})
flickerstreak@23 76 local modulesWithMethod = setmetatable({}, {__mode='kv'})
flickerstreak@23 77 do
flickerstreak@23 78 local function func(t)
flickerstreak@23 79 local i = t.i + 1
flickerstreak@23 80 local l = t.l
flickerstreak@23 81 local k = l[i]
flickerstreak@23 82 if k then
flickerstreak@23 83 t.i = i
flickerstreak@23 84 return k, l.m[k]
flickerstreak@23 85 else
flickerstreak@23 86 t = del(t)
flickerstreak@23 87 end
flickerstreak@23 88 end
flickerstreak@23 89 function AceModuleCore:IterateModules()
flickerstreak@23 90 local list = iterList[self]
flickerstreak@23 91 if not list then
flickerstreak@23 92 list = new()
flickerstreak@23 93 for k in pairs(self.modules) do
flickerstreak@23 94 list[#list+1] = k
flickerstreak@23 95 end
flickerstreak@23 96 table.sort(list)
flickerstreak@23 97 list.m = self.modules
flickerstreak@23 98 iterList[self] = list
flickerstreak@23 99 end
flickerstreak@23 100 local t = new()
flickerstreak@23 101 t.i = 0
flickerstreak@23 102 t.l = list
flickerstreak@23 103 return func, t, nil
flickerstreak@23 104 end
flickerstreak@23 105
flickerstreak@23 106 function AceModuleCore:IterateModulesWithMethod(method)
flickerstreak@23 107 local masterList = modulesWithMethod[self]
flickerstreak@23 108 if not masterList then
flickerstreak@23 109 masterList = new()
flickerstreak@23 110 modulesWithMethod[self] = masterList
flickerstreak@23 111 end
flickerstreak@23 112 local list = masterList[method]
flickerstreak@23 113 if not list then
flickerstreak@23 114 list = new()
flickerstreak@23 115 for k, v in pairs(self.modules) do
flickerstreak@23 116 if self:IsModuleActive(k) and type(v[method]) == "function" then
flickerstreak@23 117 list[#list+1] = k
flickerstreak@23 118 end
flickerstreak@23 119 end
flickerstreak@23 120 table.sort(list)
flickerstreak@23 121 list.m = self.modules
flickerstreak@23 122 masterList[method] = list
flickerstreak@23 123 end
flickerstreak@23 124 local t = new()
flickerstreak@23 125 t.i = 0
flickerstreak@23 126 t.l = list
flickerstreak@23 127 return func, t, nil
flickerstreak@23 128 end
flickerstreak@23 129
flickerstreak@23 130 --[[----------------------------------------------------------------------------------
flickerstreak@23 131 Notes:
flickerstreak@23 132 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 133 Arguments:
flickerstreak@23 134 string - the name of the method.
flickerstreak@23 135 tuple - the list of arguments to call the method with.
flickerstreak@23 136 Example:
flickerstreak@23 137 core:CallMethodOnAllModules("OnSomething")
flickerstreak@23 138 core:CallMethodOnAllModules("OnSomethingElse", 1, 2, 3, 4)
flickerstreak@23 139 ------------------------------------------------------------------------------------]]
flickerstreak@23 140 function AceModuleCore:CallMethodOnAllModules(method, ...)
flickerstreak@23 141 for name, module in self:IterateModulesWithMethod(method) do
flickerstreak@23 142 local success, ret = pcall(module[method], module, ...)
flickerstreak@23 143 if not success then
flickerstreak@23 144 geterrorhandler()(ret)
flickerstreak@23 145 end
flickerstreak@23 146 end
flickerstreak@23 147 end
flickerstreak@23 148 end
flickerstreak@23 149
flickerstreak@23 150 --[[----------------------------------------------------------------------------
flickerstreak@23 151 Notes:
flickerstreak@23 152 Create a new module, parented to self.
flickerstreak@23 153 The module created does, in fact, inherit from AceAddon-2.0.
flickerstreak@23 154 Arguments:
flickerstreak@23 155 string - name/title of the Module.
flickerstreak@23 156 list of mixins the module is to inherit from.
flickerstreak@23 157 Example:
flickerstreak@23 158 MyModule = core:NewModule('MyModule', "AceEvent-2.0", "AceHook-2.1")
flickerstreak@23 159 ------------------------------------------------------------------------------]]
flickerstreak@23 160 local tmp = {}
flickerstreak@23 161 function AceModuleCore:NewModule(name, ...)
flickerstreak@23 162 if not self.modules then
flickerstreak@23 163 AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2)
flickerstreak@23 164 end
flickerstreak@23 165 AceModuleCore:argCheck(name, 2, "string")
flickerstreak@23 166 if name:len() == 0 then
flickerstreak@23 167 AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty")
flickerstreak@23 168 end
flickerstreak@23 169 if self.modules[name] then
flickerstreak@23 170 AceModuleCore:error("The module %q has already been registered", name)
flickerstreak@23 171 end
flickerstreak@23 172
flickerstreak@23 173 if iterList[self] then
flickerstreak@23 174 iterList[self] = del(iterList[self])
flickerstreak@23 175 end
flickerstreak@23 176
flickerstreak@23 177 for i = 1, select('#', ...) do
flickerstreak@23 178 tmp[i] = getlibrary((select(i, ...)))
flickerstreak@23 179 end
flickerstreak@23 180
flickerstreak@23 181 if self.moduleMixins then
flickerstreak@23 182 for _,mixin in ipairs(self.moduleMixins) do
flickerstreak@23 183 local exists = false
flickerstreak@23 184 for _,v in ipairs(tmp) do
flickerstreak@23 185 if mixin == v then
flickerstreak@23 186 exists = true
flickerstreak@23 187 break
flickerstreak@23 188 end
flickerstreak@23 189 end
flickerstreak@23 190 if not exists then
flickerstreak@23 191 tmp[#tmp+1] = mixin
flickerstreak@23 192 end
flickerstreak@23 193 end
flickerstreak@23 194 end
flickerstreak@23 195
flickerstreak@23 196 local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name)
flickerstreak@23 197 self.modules[name] = module
flickerstreak@23 198 module.name = name
flickerstreak@23 199 module.title = name
flickerstreak@23 200
flickerstreak@23 201 AceModuleCore.totalModules[module] = self
flickerstreak@23 202
flickerstreak@23 203 if modulesWithMethod[self] then
flickerstreak@23 204 for k,v in pairs(modulesWithMethod[self]) do
flickerstreak@23 205 modulesWithMethod[self] = del(v)
flickerstreak@23 206 end
flickerstreak@23 207 end
flickerstreak@23 208
flickerstreak@23 209 if type(self.OnModuleCreated) == "function" then
flickerstreak@23 210 safecall(self.OnModuleCreated, self, name, module)
flickerstreak@23 211 end
flickerstreak@23 212 if AceEvent then
flickerstreak@23 213 AceEvent:TriggerEvent("Ace2_ModuleCreated", module)
flickerstreak@23 214 end
flickerstreak@23 215
flickerstreak@23 216 local num = #tmp
flickerstreak@23 217 for i = 1, num do
flickerstreak@23 218 tmp[i] = nil
flickerstreak@23 219 end
flickerstreak@23 220 return module
flickerstreak@23 221 end
flickerstreak@23 222 --[[----------------------------------------------------------------------------------
flickerstreak@23 223 Notes:
flickerstreak@23 224 Return whether the module names given are all available in the core.
flickerstreak@23 225 Arguments:
flickerstreak@23 226 list of strings that are the names of the modules. (typically you'd only check for one)
flickerstreak@23 227 Returns:
flickerstreak@23 228 * boolean - Whether all the modules are available in the core.
flickerstreak@23 229 Example:
flickerstreak@23 230 if core:HasModule('Bank') then
flickerstreak@23 231 -- do banking
flickerstreak@23 232 end
flickerstreak@23 233 ------------------------------------------------------------------------------------]]
flickerstreak@23 234 function AceModuleCore:HasModule(...)
flickerstreak@23 235 for i = 1, select('#', ...) do
flickerstreak@23 236 if not self.modules[select(i, ...)] then
flickerstreak@23 237 return false
flickerstreak@23 238 end
flickerstreak@23 239 end
flickerstreak@23 240
flickerstreak@23 241 return true
flickerstreak@23 242 end
flickerstreak@23 243
flickerstreak@23 244 --[[------------------------------------------------------------------------------------
flickerstreak@23 245 Notes:
flickerstreak@23 246 Return the module "name" if it exists.
flickerstreak@23 247 If the module doesnot exist, an error is thrown.
flickerstreak@23 248 Arguments:
flickerstreak@23 249 string - the name of the module.
flickerstreak@23 250 Returns:
flickerstreak@23 251 The module requested, if it exists.
flickerstreak@23 252 Example:
flickerstreak@23 253 local bank = core:GetModule('Bank')
flickerstreak@23 254 ------------------------------------------------------------------------------------]]
flickerstreak@23 255 function AceModuleCore:GetModule(name)
flickerstreak@23 256 if not self.modules then
flickerstreak@23 257 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@23 258 end
flickerstreak@23 259 if not self.modules[name] then
flickerstreak@23 260 AceModuleCore:error("Cannot find module %q.", name)
flickerstreak@23 261 end
flickerstreak@23 262 return self.modules[name]
flickerstreak@23 263 end
flickerstreak@23 264
flickerstreak@23 265 --[[----------------------------------------------------------------------------------
flickerstreak@23 266 Notes:
flickerstreak@23 267 Return whether the given module is actually a module.
flickerstreak@23 268 Arguments:
flickerstreak@23 269 reference to the module
flickerstreak@23 270 Returns:
flickerstreak@23 271 * boolean - whether the given module is actually a module.
flickerstreak@23 272 Example:
flickerstreak@23 273 if core:IsModule(module) then
flickerstreak@23 274 -- do something
flickerstreak@23 275 end
flickerstreak@23 276 -- alternatively
flickerstreak@23 277 if AceModuleCore:IsModule(module) then
flickerstreak@23 278 -- checks all modules, no matter the parent
flickerstreak@23 279 end
flickerstreak@23 280 ------------------------------------------------------------------------------------]]
flickerstreak@23 281 function AceModuleCore:IsModule(module)
flickerstreak@23 282 if self == AceModuleCore then
flickerstreak@23 283 return AceModuleCore.totalModules[module]
flickerstreak@23 284 elseif type(module) == "table" then
flickerstreak@23 285 if module.name and self.modules[module.name] and self.modules[module.name].name == module.name then
flickerstreak@23 286 return true
flickerstreak@23 287 end
flickerstreak@23 288 for k,v in pairs(self.modules) do
flickerstreak@23 289 if v == module then
flickerstreak@23 290 return true
flickerstreak@23 291 end
flickerstreak@23 292 end
flickerstreak@23 293 return false
flickerstreak@23 294 end
flickerstreak@23 295 end
flickerstreak@23 296
flickerstreak@23 297 --[[----------------------------------------------------------------------------------
flickerstreak@23 298 Notes:
flickerstreak@23 299 * Sets the default mixins for a given module.
flickerstreak@23 300 * This cannot be called after :NewModule() has been called.
flickerstreak@23 301 * This should really only be called if you use the mixins in your prototype.
flickerstreak@23 302 Arguments:
flickerstreak@23 303 list of mixins (up to 20)
flickerstreak@23 304 Example:
flickerstreak@23 305 core:SetModuleMixins("AceEvent-2.0", "AceHook-2.0")
flickerstreak@23 306 ------------------------------------------------------------------------------------]]
flickerstreak@23 307 function AceModuleCore:SetModuleMixins(...)
flickerstreak@23 308 if self.moduleMixins then
flickerstreak@23 309 AceModuleCore:error('Cannot call "SetModuleMixins" twice')
flickerstreak@23 310 elseif not self.modules then
flickerstreak@23 311 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@23 312 elseif next(self.modules) then
flickerstreak@23 313 AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.')
flickerstreak@23 314 end
flickerstreak@23 315
flickerstreak@23 316 self.moduleMixins = { ... }
flickerstreak@23 317 for i,v in ipairs(self.moduleMixins) do
flickerstreak@23 318 self.moduleMixins[i] = getlibrary(v)
flickerstreak@23 319 end
flickerstreak@23 320 end
flickerstreak@23 321
flickerstreak@23 322 -- #NODOC
flickerstreak@23 323 function AceModuleCore:SetModuleClass(class)
flickerstreak@23 324 class = getlibrary(class)
flickerstreak@23 325 if not AceOO.inherits(class, AceOO.Class) then
flickerstreak@23 326 AceModuleCore:error("Bad argument #2 to `SetModuleClass' (Class expected)")
flickerstreak@23 327 end
flickerstreak@23 328 if not self.modules then
flickerstreak@23 329 AceModuleCore:error("Error initializing class. Please report error.")
flickerstreak@23 330 end
flickerstreak@23 331 if self.customModuleClass then
flickerstreak@23 332 AceModuleCore:error("Cannot call `SetModuleClass' twice.")
flickerstreak@23 333 end
flickerstreak@23 334 self.customModuleClass = true
flickerstreak@23 335 self.moduleClass = class
flickerstreak@23 336 self.modulePrototype = class.prototype
flickerstreak@23 337 end
flickerstreak@23 338
flickerstreak@23 339 local mt = {__index=function(self, key)
flickerstreak@23 340 self[key] = false
flickerstreak@23 341 return false
flickerstreak@23 342 end}
flickerstreak@23 343 local defaultState = setmetatable({}, {__index=function(self, key)
flickerstreak@23 344 local t = setmetatable({}, mt)
flickerstreak@23 345 self[key] = t
flickerstreak@23 346 return t
flickerstreak@23 347 end})
flickerstreak@23 348
flickerstreak@23 349 local function isDisabled(core, module)
flickerstreak@23 350 local moduleName
flickerstreak@23 351 if type(module) == "table" then
flickerstreak@23 352 moduleName = module.name
flickerstreak@23 353 else
flickerstreak@23 354 moduleName = module
flickerstreak@23 355 end
flickerstreak@23 356 local disabled
flickerstreak@23 357 if type(module) == "table" and type(module.IsActive) == "function" then
flickerstreak@23 358 return not module:IsActive()
flickerstreak@23 359 elseif AceOO.inherits(core, "AceDB-2.0") then
flickerstreak@23 360 local _,profile = core:GetProfile()
flickerstreak@23 361 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 362 else
flickerstreak@23 363 disabled = core.disabledModules and core.disabledModules[moduleName]
flickerstreak@23 364 end
flickerstreak@23 365 if disabled == nil then
flickerstreak@23 366 return defaultState[core][moduleName]
flickerstreak@23 367 else
flickerstreak@23 368 return disabled
flickerstreak@23 369 end
flickerstreak@23 370 end
flickerstreak@23 371
flickerstreak@23 372 --[[----------------------------------------------------------------------------------
flickerstreak@23 373 Notes:
flickerstreak@23 374 Sets the default active state of a module. This should be called before the ADDON_LOADED of the module.
flickerstreak@23 375 Arguments:
flickerstreak@23 376 string - name of the module.
flickerstreak@23 377 table - reference to the module.
flickerstreak@23 378 boolean - new state. false means disabled by default, true means enabled by default (true is the default).
flickerstreak@23 379 Example:
flickerstreak@23 380 self:SetModuleDefaultState('bank', false)
flickerstreak@23 381 ------------------------------------------------------------------------------------]]
flickerstreak@23 382 function AceModuleCore:SetModuleDefaultState(module, state)
flickerstreak@23 383 AceModuleCore:argCheck(module, 2, "table", "string")
flickerstreak@23 384 AceModuleCore:argCheck(state, 3, "boolean")
flickerstreak@23 385
flickerstreak@23 386 if type(module) == "table" then
flickerstreak@23 387 if not self:IsModule(module) then
flickerstreak@23 388 AceModuleCore:error("%q is not a module", module)
flickerstreak@23 389 end
flickerstreak@23 390 module = module.name
flickerstreak@23 391 end
flickerstreak@23 392
flickerstreak@23 393 defaultState[self][module] = not state
flickerstreak@23 394 end
flickerstreak@23 395
flickerstreak@23 396 --[[----------------------------------------------------------------------------------
flickerstreak@23 397 Notes:
flickerstreak@23 398 Toggles the active state of a module.
flickerstreak@23 399
flickerstreak@23 400 This calls module:ToggleActive([state]) if available.
flickerstreak@23 401
flickerstreak@23 402 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 403
flickerstreak@23 404 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 405
flickerstreak@23 406 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 407
flickerstreak@23 408 Arguments:
flickerstreak@23 409 string/table - name of the module or a reference to the module
flickerstreak@23 410 [optional] boolean - new state. (default not :IsModuleActive("name" or module))
flickerstreak@23 411 Returns:
flickerstreak@23 412 * boolean - Whether the module is now in an active (enabled) state.
flickerstreak@23 413 Example:
flickerstreak@23 414 self:ToggleModuleActive('bank')
flickerstreak@23 415 ------------------------------------------------------------------------------------]]
flickerstreak@23 416 function AceModuleCore:ToggleModuleActive(module, state)
flickerstreak@23 417 AceModuleCore:argCheck(module, 2, "table", "string")
flickerstreak@23 418 AceModuleCore:argCheck(state, 3, "nil", "boolean")
flickerstreak@23 419
flickerstreak@23 420 if type(module) == "string" then
flickerstreak@23 421 if not self:HasModule(module) then
flickerstreak@23 422 AceModuleCore:error("Cannot find module %q", module)
flickerstreak@23 423 end
flickerstreak@23 424 module = self:GetModule(module)
flickerstreak@23 425 elseif not self:IsModule(module) then
flickerstreak@23 426 AceModuleCore:error("%q is not a module", module)
flickerstreak@23 427 end
flickerstreak@23 428
flickerstreak@23 429 local disable
flickerstreak@23 430 if state == nil then
flickerstreak@23 431 disable = self:IsModuleActive(module)
flickerstreak@23 432 else
flickerstreak@23 433 disable = not state
flickerstreak@23 434 if disable ~= self:IsModuleActive(module) then
flickerstreak@23 435 return
flickerstreak@23 436 end
flickerstreak@23 437 end
flickerstreak@23 438
flickerstreak@23 439 if type(module.ToggleActive) == "function" then
flickerstreak@23 440 return module:ToggleActive(not disable)
flickerstreak@23 441 elseif AceOO.inherits(self, "AceDB-2.0") then
flickerstreak@23 442 if not self.db or not self.db.raw then
flickerstreak@23 443 AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fired.")
flickerstreak@23 444 end
flickerstreak@23 445 if type(self.db.raw.disabledModules) ~= "table" then
flickerstreak@23 446 self.db.raw.disabledModules = {}
flickerstreak@23 447 end
flickerstreak@23 448 local _,profile = self:GetProfile()
flickerstreak@23 449 if type(self.db.raw.disabledModules[profile]) ~= "table" then
flickerstreak@23 450 self.db.raw.disabledModules[profile] = {}
flickerstreak@23 451 end
flickerstreak@23 452 if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then
flickerstreak@23 453 local value = nil
flickerstreak@23 454 if disable ~= defaultState[self][module.name] then
flickerstreak@23 455 value = disable
flickerstreak@23 456 end
flickerstreak@23 457 self.db.raw.disabledModules[profile][module.name] = value
flickerstreak@23 458 end
flickerstreak@23 459 if not disable then
flickerstreak@23 460 if not next(self.db.raw.disabledModules[profile]) then
flickerstreak@23 461 self.db.raw.disabledModules[profile] = nil
flickerstreak@23 462 end
flickerstreak@23 463 if not next(self.db.raw.disabledModules) then
flickerstreak@23 464 self.db.raw.disabledModules = nil
flickerstreak@23 465 end
flickerstreak@23 466 end
flickerstreak@23 467 else
flickerstreak@23 468 if type(self.disabledModules) ~= "table" then
flickerstreak@23 469 self.disabledModules = {}
flickerstreak@23 470 end
flickerstreak@23 471 local value = nil
flickerstreak@23 472 if disable ~= defaultState[self][module.name] then
flickerstreak@23 473 value = disable
flickerstreak@23 474 end
flickerstreak@23 475 self.disabledModules[module.name] = value
flickerstreak@23 476 end
flickerstreak@23 477 if AceOO.inherits(module, "AceAddon-2.0") then
flickerstreak@23 478 if not AceAddon.addonsStarted[module] then
flickerstreak@23 479 return
flickerstreak@23 480 end
flickerstreak@23 481 end
flickerstreak@23 482 if not disable then
flickerstreak@23 483 local first = nil
flickerstreak@23 484 if AceOO.inherits(module, "AceAddon-2.0") then
flickerstreak@23 485 if AceAddon.addonsEnabled and not AceAddon.addonsEnabled[module] then
flickerstreak@23 486 AceAddon.addonsEnabled[module] = true
flickerstreak@23 487 first = true
flickerstreak@23 488 end
flickerstreak@23 489 end
flickerstreak@23 490 local current = module.class
flickerstreak@23 491 while true do
flickerstreak@23 492 if current == AceOO.Class then
flickerstreak@23 493 break
flickerstreak@23 494 end
flickerstreak@23 495 if current.mixins then
flickerstreak@23 496 for mixin in pairs(current.mixins) do
flickerstreak@23 497 if type(mixin.OnEmbedEnable) == "function" then
flickerstreak@23 498 safecall(mixin.OnEmbedEnable, mixin, module, first)
flickerstreak@23 499 end
flickerstreak@23 500 end
flickerstreak@23 501 end
flickerstreak@23 502 current = current.super
flickerstreak@23 503 end
flickerstreak@23 504 if type(module.OnEnable) == "function" then
flickerstreak@23 505 safecall(module.OnEnable, module, first)
flickerstreak@23 506 end
flickerstreak@23 507 if AceEvent then
flickerstreak@23 508 AceEvent:TriggerEvent("Ace2_AddonEnabled", module, first)
flickerstreak@23 509 end
flickerstreak@23 510 else
flickerstreak@23 511 local current = module.class
flickerstreak@23 512 while true do
flickerstreak@23 513 if current == AceOO.Class then
flickerstreak@23 514 break
flickerstreak@23 515 end
flickerstreak@23 516 if current.mixins then
flickerstreak@23 517 for mixin in pairs(current.mixins) do
flickerstreak@23 518 if type(mixin.OnEmbedDisable) == "function" then
flickerstreak@23 519 safecall(mixin.OnEmbedDisable, mixin, module)
flickerstreak@23 520 end
flickerstreak@23 521 end
flickerstreak@23 522 end
flickerstreak@23 523 current = current.super
flickerstreak@23 524 end
flickerstreak@23 525 if type(module.OnDisable) == "function" then
flickerstreak@23 526 safecall(module.OnDisable, module)
flickerstreak@23 527 end
flickerstreak@23 528 if AceEvent then
flickerstreak@23 529 AceEvent:TriggerEvent("Ace2_AddonDisabled", module)
flickerstreak@23 530 end
flickerstreak@23 531 end
flickerstreak@23 532 return not disable
flickerstreak@23 533 end
flickerstreak@23 534
flickerstreak@23 535 --[[-----------------------------------------------------------------------
flickerstreak@23 536 Notes:
flickerstreak@23 537 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 538 Arguments:
flickerstreak@23 539 string/table - name of the module or a reference to the module
flickerstreak@23 540 [optional] - boolean - if set, this will check modules that are not loaded as well. (default: false)
flickerstreak@23 541 Returns:
flickerstreak@23 542 * boolean - Whether the module is in an active (enabled) state.
flickerstreak@23 543 Example:
flickerstreak@23 544 assert(self:IsModuleActive('bank'))
flickerstreak@23 545 ------------------------------------------------------------------------]]
flickerstreak@23 546 function AceModuleCore:IsModuleActive(module, notLoaded)
flickerstreak@23 547 AceModuleCore:argCheck(module, 2, "table", "string")
flickerstreak@23 548 AceModuleCore:argCheck(notLoaded, 3, "nil", "boolean")
flickerstreak@23 549 if notLoaded then
flickerstreak@23 550 AceModuleCore:argCheck(module, 2, "string")
flickerstreak@23 551 end
flickerstreak@23 552
flickerstreak@23 553 if AceModuleCore == self then
flickerstreak@23 554 self:argCheck(module, 2, "table")
flickerstreak@23 555
flickerstreak@23 556 local core = AceModuleCore.totalModules[module]
flickerstreak@23 557 if not core then
flickerstreak@23 558 self:error("Bad argument #2 to `IsModuleActive'. Not a module")
flickerstreak@23 559 end
flickerstreak@23 560 return core:IsModuleActive(module)
flickerstreak@23 561 end
flickerstreak@23 562
flickerstreak@23 563 if type(module) == "string" then
flickerstreak@23 564 if not notLoaded and not self:HasModule(module) then
flickerstreak@23 565 AceModuleCore:error("Cannot find module %q", module)
flickerstreak@23 566 end
flickerstreak@23 567 if not notLoaded then
flickerstreak@23 568 module = self:GetModule(module)
flickerstreak@23 569 else
flickerstreak@23 570 module = self:HasModule(module) and self:GetModule(module) or module
flickerstreak@23 571 end
flickerstreak@23 572 else
flickerstreak@23 573 if not self:IsModule(module) then
flickerstreak@23 574 AceModuleCore:error("%q is not a module", module)
flickerstreak@23 575 end
flickerstreak@23 576 end
flickerstreak@23 577
flickerstreak@23 578 return not isDisabled(self, module)
flickerstreak@23 579 end
flickerstreak@23 580
flickerstreak@23 581 -- #NODOC
flickerstreak@23 582 function AceModuleCore:OnInstanceInit(target)
flickerstreak@23 583 if target.modules then
flickerstreak@23 584 do return end
flickerstreak@23 585 AceModuleCore:error("OnInstanceInit cannot be called twice")
flickerstreak@23 586 end
flickerstreak@23 587
flickerstreak@23 588 if not AceAddon then
flickerstreak@23 589 if AceLibrary:HasInstance("AceAddon-2.0") then
flickerstreak@23 590 AceAddon = AceLibrary("AceAddon-2.0")
flickerstreak@23 591 else
flickerstreak@23 592 self:error(MAJOR_VERSION .. " requires AceAddon-2.0")
flickerstreak@23 593 end
flickerstreak@23 594 end
flickerstreak@23 595 target.modules = {}
flickerstreak@23 596
flickerstreak@23 597 target.moduleClass = AceOO.Class("AceAddon-2.0")
flickerstreak@23 598 target.modulePrototype = target.moduleClass.prototype
flickerstreak@23 599 end
flickerstreak@23 600
flickerstreak@23 601 AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit
flickerstreak@23 602
flickerstreak@23 603 function AceModuleCore.OnEmbedProfileDisable(AceModuleCore, self, newProfile)
flickerstreak@23 604 if not AceOO.inherits(self, "AceDB-2.0") then
flickerstreak@23 605 return
flickerstreak@23 606 end
flickerstreak@23 607 local _,currentProfile = self:GetProfile()
flickerstreak@23 608 for k, module in pairs(self.modules) do
flickerstreak@23 609 if type(module.IsActive) == "function" or type(module.ToggleActive) == "function" then
flickerstreak@23 610 -- continue
flickerstreak@23 611 else
flickerstreak@23 612 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 613 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 614 if currentActive ~= newActive then
flickerstreak@23 615 self:ToggleModuleActive(module)
flickerstreak@23 616 if not self.db.raw.disabledModules then
flickerstreak@23 617 self.db.raw.disabledModules = {}
flickerstreak@23 618 end
flickerstreak@23 619 if not self.db.raw.disabledModules[currentProfile] then
flickerstreak@23 620 self.db.raw.disabledModules[currentProfile] = {}
flickerstreak@23 621 end
flickerstreak@23 622 self.db.raw.disabledModules[currentProfile][module.name] = not currentActive or nil
flickerstreak@23 623 end
flickerstreak@23 624 end
flickerstreak@23 625 end
flickerstreak@23 626 end
flickerstreak@23 627
flickerstreak@23 628 -- #NODOC
flickerstreak@23 629 function AceModuleCore:Ace2_AddonEnabled(module, first)
flickerstreak@23 630 local addon = self.totalModules[module]
flickerstreak@23 631 if not addon then
flickerstreak@23 632 return
flickerstreak@23 633 end
flickerstreak@23 634
flickerstreak@23 635 if modulesWithMethod[addon] then
flickerstreak@23 636 for k,v in pairs(modulesWithMethod[addon]) do
flickerstreak@23 637 modulesWithMethod[addon] = del(v)
flickerstreak@23 638 end
flickerstreak@23 639 end
flickerstreak@23 640 if type(addon.OnModuleEnable) == "function" then
flickerstreak@23 641 safecall(addon.OnModuleEnable, addon, module, first)
flickerstreak@23 642 end
flickerstreak@23 643 end
flickerstreak@23 644
flickerstreak@23 645 -- #NODOC
flickerstreak@23 646 function AceModuleCore:Ace2_AddonDisabled(module)
flickerstreak@23 647 local addon = self.totalModules[module]
flickerstreak@23 648 if not addon then
flickerstreak@23 649 return
flickerstreak@23 650 end
flickerstreak@23 651
flickerstreak@23 652 if modulesWithMethod[addon] then
flickerstreak@23 653 for k,v in pairs(modulesWithMethod[addon]) do
flickerstreak@23 654 modulesWithMethod[addon] = del(v)
flickerstreak@23 655 end
flickerstreak@23 656 end
flickerstreak@23 657 if type(addon.OnModuleDisable) == "function" then
flickerstreak@23 658 safecall(addon.OnModuleDisable, addon, module)
flickerstreak@23 659 end
flickerstreak@23 660 end
flickerstreak@23 661
flickerstreak@23 662 local function activate(self, oldLib, oldDeactivate)
flickerstreak@23 663 AceModuleCore = self
flickerstreak@23 664
flickerstreak@23 665 self.totalModules = oldLib and oldLib.totalModules or {}
flickerstreak@23 666
flickerstreak@23 667 self:activate(oldLib, oldDeactivate)
flickerstreak@23 668
flickerstreak@23 669 if oldDeactivate then
flickerstreak@23 670 oldDeactivate(oldLib)
flickerstreak@23 671 end
flickerstreak@23 672 end
flickerstreak@23 673
flickerstreak@23 674 local function external(self, major, instance)
flickerstreak@23 675 if major == "AceEvent-2.0" then
flickerstreak@23 676 AceEvent = instance
flickerstreak@23 677 AceEvent:embed(self)
flickerstreak@23 678
flickerstreak@23 679 self:UnregisterAllEvents()
flickerstreak@23 680 self:RegisterEvent("Ace2_AddonEnabled")
flickerstreak@23 681 self:RegisterEvent("Ace2_AddonDisabled")
flickerstreak@23 682 elseif major == "AceAddon-2.0" then
flickerstreak@23 683 AceAddon = instance
flickerstreak@23 684 end
flickerstreak@23 685 end
flickerstreak@23 686
flickerstreak@23 687 AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate, nil, external)
flickerstreak@23 688 AceModuleCore = AceLibrary(MAJOR_VERSION)