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) |