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