vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 --[[
2 Name: AceModuleCore-2.0
3 Revision: $Rev: 11577 $
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, Compost-2.0 (optional)
12 ]]
13  
14 local MAJOR_VERSION = "AceModuleCore-2.0"
15 local MINOR_VERSION = "$Revision: 11577 $"
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 table_setn
23 do
24 local version = GetBuildInfo()
25 if string.find(version, "^2%.") then
26 -- 2.0.0
27 table_setn = function() end
28 else
29 table_setn = table.setn
30 end
31 end
32  
33 local AceOO = AceLibrary:GetInstance("AceOO-2.0")
34 local AceModuleCore = AceOO.Mixin {
35 "NewModule",
36 "HasModule",
37 "GetModule",
38 "IsModule",
39 "IterateModules",
40 "SetModuleMixins",
41 "SetModuleClass",
42 "IsModuleActive",
43 "ToggleModuleActive"
44 }
45  
46 local Compost = AceLibrary:HasInstance("Compost-2.0") and AceLibrary("Compost-2.0")
47  
48 local function getlibrary(lib)
49 if type(lib) == "string" then
50 return AceLibrary(lib)
51 else
52 return lib
53 end
54 end
55  
56 local tmp
57 function AceModuleCore:NewModule(name, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
58 if not self.modules then
59 AceModuleCore:error("CreatePrototype() must be called before attempting to create a new module.", 2)
60 end
61 AceModuleCore:argCheck(name, 2, "string")
62 if string.len(name) == 0 then
63 AceModuleCore:error("Bad argument #2 to `NewModule`, string must not be empty")
64 end
65 if self.modules[name] then
66 AceModuleCore:error("The module %q has already been registered", name)
67 end
68  
69 if not tmp then
70 tmp = {}
71 end
72 if a1 then table.insert(tmp, a1)
73 if a2 then table.insert(tmp, a2)
74 if a3 then table.insert(tmp, a3)
75 if a4 then table.insert(tmp, a4)
76 if a5 then table.insert(tmp, a5)
77 if a6 then table.insert(tmp, a6)
78 if a7 then table.insert(tmp, a7)
79 if a8 then table.insert(tmp, a8)
80 if a9 then table.insert(tmp, a9)
81 if a10 then table.insert(tmp, a10)
82 if a11 then table.insert(tmp, a11)
83 if a12 then table.insert(tmp, a12)
84 if a13 then table.insert(tmp, a13)
85 if a14 then table.insert(tmp, a14)
86 if a15 then table.insert(tmp, a15)
87 if a16 then table.insert(tmp, a16)
88 if a17 then table.insert(tmp, a17)
89 if a18 then table.insert(tmp, a18)
90 if a19 then table.insert(tmp, a19)
91 if a20 then table.insert(tmp, a20)
92 end end end end end end end end end end end end end end end end end end end end
93 for k,v in ipairs(tmp) do
94 tmp[k] = getlibrary(v)
95 end
96  
97 if self.moduleMixins then
98 for _,mixin in ipairs(self.moduleMixins) do
99 local exists = false
100 for _,v in ipairs(tmp) do
101 if mixin == v then
102 exists = true
103 break
104 end
105 end
106 if not exists then
107 table.insert(tmp, mixin)
108 end
109 end
110 end
111  
112 local module = AceOO.Classpool(self.moduleClass, unpack(tmp)):new(name)
113 self.modules[name] = module
114 module.name = name
115 module.title = name
116  
117 AceModuleCore.totalModules[module] = self
118  
119 for k in pairs(tmp) do
120 tmp[k] = nil
121 end
122 table_setn(tmp, 0)
123 return module
124 end
125  
126 function AceModuleCore:HasModule(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
127 if a1 then if not self.modules[a1] then return false end
128 if a2 then if not self.modules[a2] then return false end
129 if a3 then if not self.modules[a3] then return false end
130 if a4 then if not self.modules[a4] then return false end
131 if a5 then if not self.modules[a5] then return false end
132 if a6 then if not self.modules[a6] then return false end
133 if a7 then if not self.modules[a7] then return false end
134 if a8 then if not self.modules[a8] then return false end
135 if a9 then if not self.modules[a9] then return false end
136 if a10 then if not self.modules[a10] then return false end
137 if a11 then if not self.modules[a11] then return false end
138 if a12 then if not self.modules[a12] then return false end
139 if a13 then if not self.modules[a13] then return false end
140 if a14 then if not self.modules[a14] then return false end
141 if a15 then if not self.modules[a15] then return false end
142 if a16 then if not self.modules[a16] then return false end
143 if a17 then if not self.modules[a17] then return false end
144 if a18 then if not self.modules[a18] then return false end
145 if a19 then if not self.modules[a19] then return false end
146 if a20 then if not self.modules[a20] then return false end
147 end end end end end end end end end end end end end end end end end end end end
148  
149 return true
150 end
151  
152 function AceModuleCore:GetModule(name)
153 if not self.modules then
154 AceModuleCore:error("Error initializing class. Please report error.")
155 end
156 if not self.modules[name] then
157 AceModuleCore:error("Cannot find module %q.", name)
158 end
159 return self.modules[name]
160 end
161  
162 function AceModuleCore:IsModule(module)
163 if self == AceModuleCore then
164 return AceModuleCore.totalModules[module]
165 else
166 for k,v in pairs(self.modules) do
167 if v == module then
168 return true
169 end
170 end
171 return false
172 end
173 end
174  
175 function AceModuleCore:IterateModules()
176 return pairs(self.modules)
177 end
178  
179 function AceModuleCore:SetModuleMixins(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
180 if self.moduleMixins then
181 AceModuleCore:error('Cannot call "SetModuleMixins" twice')
182 elseif not self.modules then
183 AceModuleCore:error("Error initializing class. Please report error.")
184 elseif next(self.modules) then
185 AceModuleCore:error('Cannot call "SetModuleMixins" after "NewModule" has been called.')
186 end
187  
188 self.moduleMixins = Compost and Compost:Acquire(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) or {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20}
189 for k,v in ipairs(self.moduleMixins) do
190 self.moduleMixins[k] = getlibrary(v)
191 end
192 end
193  
194 function AceModuleCore:SetModuleClass(class)
195 class = getlibrary(class)
196 AceModuleCore:assert(AceOO.inherits(class, AceOO.Class), "Bad argument #2 to `SetModuleClass' (Class expected)")
197 if not self.modules then
198 AceModuleCore:error("Error initializing class. Please report error.")
199 end
200 if self.customModuleClass then
201 AceModuleCore:error("Cannot call `SetModuleClass' twice.")
202 end
203 self.customModuleClass = true
204 self.moduleClass = class
205 self.modulePrototype = class.prototype
206 end
207  
208 function AceModuleCore:ToggleModuleActive(module, state)
209 AceModuleCore:argCheck(module, 2, "table", "string")
210 AceModuleCore:argCheck(state, 3, "nil", "boolean")
211  
212 if type(module) == "string" then
213 if not self:HasModule(module) then
214 AceModuleCore:error("Cannot find module %q", module)
215 end
216 module = self:GetModule(module)
217 else
218 if not self:IsModule(module) then
219 AceModuleCore:error("%q is not a module", module)
220 end
221 end
222  
223 local disable
224 if state == nil then
225 disable = self:IsModuleActive(module)
226 else
227 disable = not state
228 if disable ~= self:IsModuleActive(module) then
229 return
230 end
231 end
232  
233 if type(module.ToggleActive) == "function" then
234 return module:ToggleActive(not disable)
235 elseif AceOO.inherits(self, "AceDB-2.0") then
236 if not self.db or not self.db.raw then
237 AceModuleCore:error("Cannot toggle a module until `RegisterDB' has been called and `ADDON_LOADED' has been fireed.")
238 end
239 if type(self.db.raw.disabledModules) ~= "table" then
240 self.db.raw.disabledModules = Compost and Compost:Acquire() or {}
241 end
242 local _,profile = self:GetProfile()
243 if type(self.db.raw.disabledModules[profile]) ~= "table" then
244 self.db.raw.disabledModules[profile] = Compost and Compost:Acquire() or {}
245 end
246 if type(self.db.raw.disabledModules[profile][module.name]) ~= "table" then
247 self.db.raw.disabledModules[profile][module.name] = disable or nil
248 end
249 if not disable then
250 if not next(self.db.raw.disabledModules[profile]) then
251 if Compost then
252 Compost:Reclaim(self.db.raw.disabledModules[profile])
253 end
254 self.db.raw.disabledModules[profile] = nil
255 end
256 if not next(self.db.raw.disabledModules) then
257 if Compost then
258 Compost:Reclaim(self.db.raw.disabledModules)
259 end
260 self.db.raw.disabledModules = nil
261 end
262 end
263 else
264 if type(self.disabledModules) ~= "table" then
265 self.disabledModules = Compost and Compost:Acquire() or {}
266 end
267 self.disabledModules[module.name] = disable or nil
268 end
269 if AceOO.inherits(module, "AceAddon-2.0") then
270 local AceAddon = AceLibrary("AceAddon-2.0")
271 if not AceAddon.addonsStarted[module] then
272 return
273 end
274 end
275 if not disable then
276 if type(module.OnEnable) == "function" then
277 module:OnEnable()
278 end
279 else
280 local current = module.class
281 while true do
282 if current == AceOO.Class then
283 break
284 end
285 if current.mixins then
286 for mixin in pairs(current.mixins) do
287 if type(mixin.OnEmbedDisable) == "function" then
288 mixin:OnEmbedDisable(module)
289 end
290 end
291 end
292 current = current.super
293 end
294 if type(module.OnDisable) == "function" then
295 module:OnDisable()
296 end
297 end
298 return not disable
299 end
300  
301 function AceModuleCore:IsModuleActive(module)
302 AceModuleCore:argCheck(module, 2, "table", "string")
303  
304 if AceModuleCore == self then
305 self:argCheck(module, 2, "table")
306  
307 local core = AceModuleCore.totalModules[module]
308 if not core then
309 self:error("Bad argument #2 to `IsModuleActive'. Not a module")
310 end
311 return core:IsModuleActive(module)
312 end
313  
314 if type(module) == "string" then
315 if not self:HasModule(module) then
316 AceModuleCore:error("Cannot find module %q", module)
317 end
318 module = self:GetModule(module)
319 else
320 if not self:IsModule(module) then
321 AceModuleCore:error("%q is not a module", module)
322 end
323 end
324  
325 if type(module.IsActive) == "function" then
326 return module:IsActive()
327 elseif AceOO.inherits(self, "AceDB-2.0") then
328 local _,profile = self:GetProfile()
329 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]
330 else
331 return not self.disabledModules or not self.disabledModules[module.name]
332 end
333 end
334  
335 function AceModuleCore:OnInstanceInit(target)
336 if target.modules then
337 AceModuleCore:error("OnInstanceInit cannot be called twice")
338 end
339 target.modules = Compost and Compost:Acquire() or {}
340  
341 target.moduleClass = AceOO.Class("AceAddon-2.0")
342 target.modulePrototype = target.moduleClass.prototype
343 end
344  
345 AceModuleCore.OnManualEmbed = AceModuleCore.OnInstanceInit
346  
347 local function activate(self, oldLib, oldDeactivate)
348 AceModuleCore = self
349  
350 self.super.activate(self, oldLib, oldDeactivate)
351  
352 if oldLib then
353 self.totalModules = oldLib.totalModules
354 end
355 if not self.totalModules then
356 self.totalModules = {}
357 end
358 end
359  
360 local function external(self, major, instance)
361 if major == "Compost-2.0" then
362 Compost = instance
363 end
364 end
365  
366 AceLibrary:Register(AceModuleCore, MAJOR_VERSION, MINOR_VERSION, activate)
367 AceModuleCore = AceLibrary(MAJOR_VERSION)