flickerstreak@30
|
1 --[[
|
flickerstreak@30
|
2 Name: LibRock-1.0
|
flickerstreak@30
|
3 Revision: $Rev: 63317 $
|
flickerstreak@30
|
4 Developed by: ckknight (ckknight@gmail.com)
|
flickerstreak@30
|
5 Website: http://www.wowace.com/
|
flickerstreak@30
|
6 Description: Library to allow for library and addon creation and easy table recycling functions.
|
flickerstreak@30
|
7 License: LGPL v2.1
|
flickerstreak@30
|
8 ]]
|
flickerstreak@30
|
9
|
flickerstreak@30
|
10 local MAJOR_VERSION = "LibRock-1.0"
|
flickerstreak@30
|
11 local MINOR_VERSION = tonumber(("$Revision: 63317 $"):match("(%d+)")) - 60000
|
flickerstreak@30
|
12
|
flickerstreak@30
|
13 local _G = _G
|
flickerstreak@30
|
14 local GetLocale = _G.GetLocale
|
flickerstreak@30
|
15 local CATEGORIES
|
flickerstreak@30
|
16 if GetLocale() == "deDE" then
|
flickerstreak@30
|
17 CATEGORIES = {
|
flickerstreak@30
|
18 ["Action Bars"] = "Aktionsleisten",
|
flickerstreak@30
|
19 ["Auction"] = "Auktion",
|
flickerstreak@30
|
20 ["Audio"] = "Audio",
|
flickerstreak@30
|
21 ["Battlegrounds/PvP"] = "Schlachtfeld/PvP",
|
flickerstreak@30
|
22 ["Buffs"] = "Stärkungszauber",
|
flickerstreak@30
|
23 ["Chat/Communication"] = "Chat/Kommunikation",
|
flickerstreak@30
|
24 ["Druid"] = "Druide",
|
flickerstreak@30
|
25 ["Hunter"] = "Jäger",
|
flickerstreak@30
|
26 ["Mage"] = "Magier",
|
flickerstreak@30
|
27 ["Paladin"] = "Paladin",
|
flickerstreak@30
|
28 ["Priest"] = "Priester",
|
flickerstreak@30
|
29 ["Rogue"] = "Schurke",
|
flickerstreak@30
|
30 ["Shaman"] = "Schamane",
|
flickerstreak@30
|
31 ["Warlock"] = "Hexenmeister",
|
flickerstreak@30
|
32 ["Warrior"] = "Krieger",
|
flickerstreak@30
|
33 ["Healer"] = "Heiler",
|
flickerstreak@30
|
34 ["Tank"] = "Tank",
|
flickerstreak@30
|
35 ["Caster"] = "Zauberer",
|
flickerstreak@30
|
36 ["Combat"] = "Kampf",
|
flickerstreak@30
|
37 ["Compilations"] = "Zusammenstellungen",
|
flickerstreak@30
|
38 ["Data Export"] = "Datenexport",
|
flickerstreak@30
|
39 ["Development Tools"] = "Entwicklungstools",
|
flickerstreak@30
|
40 ["Guild"] = "Gilde",
|
flickerstreak@30
|
41 ["Frame Modification"] = "Frameveränderungen",
|
flickerstreak@30
|
42 ["Interface Enhancements"] = "Interfaceverbesserungen",
|
flickerstreak@30
|
43 ["Inventory"] = "Inventar",
|
flickerstreak@30
|
44 ["Library"] = "Bibliotheken",
|
flickerstreak@30
|
45 ["Map"] = "Karte",
|
flickerstreak@30
|
46 ["Mail"] = "Post",
|
flickerstreak@30
|
47 ["Miscellaneous"] = "Diverses",
|
flickerstreak@30
|
48 ["Quest"] = "Quest",
|
flickerstreak@30
|
49 ["Raid"] = "Schlachtzug",
|
flickerstreak@30
|
50 ["Tradeskill"] = "Beruf",
|
flickerstreak@30
|
51 ["UnitFrame"] = "Einheiten-Fenster",
|
flickerstreak@30
|
52 }
|
flickerstreak@30
|
53 elseif GetLocale() == "frFR" then
|
flickerstreak@30
|
54 CATEGORIES = {
|
flickerstreak@30
|
55 ["Action Bars"] = "Barres d'action",
|
flickerstreak@30
|
56 ["Auction"] = "Hôtel des ventes",
|
flickerstreak@30
|
57 ["Audio"] = "Audio",
|
flickerstreak@30
|
58 ["Battlegrounds/PvP"] = "Champs de bataille/JcJ",
|
flickerstreak@30
|
59 ["Buffs"] = "Buffs",
|
flickerstreak@30
|
60 ["Chat/Communication"] = "Chat/Communication",
|
flickerstreak@30
|
61 ["Druid"] = "Druide",
|
flickerstreak@30
|
62 ["Hunter"] = "Chasseur",
|
flickerstreak@30
|
63 ["Mage"] = "Mage",
|
flickerstreak@30
|
64 ["Paladin"] = "Paladin",
|
flickerstreak@30
|
65 ["Priest"] = "Prêtre",
|
flickerstreak@30
|
66 ["Rogue"] = "Voleur",
|
flickerstreak@30
|
67 ["Shaman"] = "Chaman",
|
flickerstreak@30
|
68 ["Warlock"] = "Démoniste",
|
flickerstreak@30
|
69 ["Warrior"] = "Guerrier",
|
flickerstreak@30
|
70 ["Healer"] = "Soigneur",
|
flickerstreak@30
|
71 ["Tank"] = "Tank",
|
flickerstreak@30
|
72 ["Caster"] = "Casteur",
|
flickerstreak@30
|
73 ["Combat"] = "Combat",
|
flickerstreak@30
|
74 ["Compilations"] = "Compilations",
|
flickerstreak@30
|
75 ["Data Export"] = "Exportation de données",
|
flickerstreak@30
|
76 ["Development Tools"] = "Outils de développement",
|
flickerstreak@30
|
77 ["Guild"] = "Guilde",
|
flickerstreak@30
|
78 ["Frame Modification"] = "Modification des fenêtres",
|
flickerstreak@30
|
79 ["Interface Enhancements"] = "Améliorations de l'interface",
|
flickerstreak@30
|
80 ["Inventory"] = "Inventaire",
|
flickerstreak@30
|
81 ["Library"] = "Bibliothèques",
|
flickerstreak@30
|
82 ["Map"] = "Carte",
|
flickerstreak@30
|
83 ["Mail"] = "Courrier",
|
flickerstreak@30
|
84 ["Miscellaneous"] = "Divers",
|
flickerstreak@30
|
85 ["Quest"] = "Quêtes",
|
flickerstreak@30
|
86 ["Raid"] = "Raid",
|
flickerstreak@30
|
87 ["Tradeskill"] = "Métiers",
|
flickerstreak@30
|
88 ["UnitFrame"] = "Fenêtres d'unité",
|
flickerstreak@30
|
89 }
|
flickerstreak@30
|
90 elseif GetLocale() == "koKR" then
|
flickerstreak@30
|
91 CATEGORIES = {
|
flickerstreak@30
|
92 ["Action Bars"] = "액션바",
|
flickerstreak@30
|
93 ["Auction"] = "경매",
|
flickerstreak@30
|
94 ["Audio"] = "음향",
|
flickerstreak@30
|
95 ["Battlegrounds/PvP"] = "전장/PvP",
|
flickerstreak@30
|
96 ["Buffs"] = "버프",
|
flickerstreak@30
|
97 ["Chat/Communication"] = "대화/의사소통",
|
flickerstreak@30
|
98 ["Druid"] = "드루이드",
|
flickerstreak@30
|
99 ["Hunter"] = "사냥꾼",
|
flickerstreak@30
|
100 ["Mage"] = "마법사",
|
flickerstreak@30
|
101 ["Paladin"] = "성기사",
|
flickerstreak@30
|
102 ["Priest"] = "사제",
|
flickerstreak@30
|
103 ["Rogue"] = "도적",
|
flickerstreak@30
|
104 ["Shaman"] = "주술사",
|
flickerstreak@30
|
105 ["Warlock"] = "흑마법사",
|
flickerstreak@30
|
106 ["Warrior"] = "전사",
|
flickerstreak@30
|
107 ["Healer"] = "힐러",
|
flickerstreak@30
|
108 ["Tank"] = "탱커",
|
flickerstreak@30
|
109 ["Caster"] = "캐스터",
|
flickerstreak@30
|
110 ["Combat"] = "전투",
|
flickerstreak@30
|
111 ["Compilations"] = "복합",
|
flickerstreak@30
|
112 ["Data Export"] = "자료 출력",
|
flickerstreak@30
|
113 ["Development Tools"] = "개발 도구",
|
flickerstreak@30
|
114 ["Guild"] = "길드",
|
flickerstreak@30
|
115 ["Frame Modification"] = "구조 변경",
|
flickerstreak@30
|
116 ["Interface Enhancements"] = "인터페이스 강화",
|
flickerstreak@30
|
117 ["Inventory"] = "인벤토리",
|
flickerstreak@30
|
118 ["Library"] = "라이브러리",
|
flickerstreak@30
|
119 ["Map"] = "지도",
|
flickerstreak@30
|
120 ["Mail"] = "우편",
|
flickerstreak@30
|
121 ["Miscellaneous"] = "기타",
|
flickerstreak@30
|
122 ["Quest"] = "퀘스트",
|
flickerstreak@30
|
123 ["Raid"] = "공격대",
|
flickerstreak@30
|
124 ["Tradeskill"] = "전문기술",
|
flickerstreak@30
|
125 ["UnitFrame"] = "유닛 프레임",
|
flickerstreak@30
|
126 }
|
flickerstreak@30
|
127 elseif GetLocale() == "zhTW" then
|
flickerstreak@30
|
128 CATEGORIES = {
|
flickerstreak@30
|
129 ["Action Bars"] = "動作列",
|
flickerstreak@30
|
130 ["Auction"] = "拍賣",
|
flickerstreak@30
|
131 ["Audio"] = "音效",
|
flickerstreak@30
|
132 ["Battlegrounds/PvP"] = "戰場/PvP",
|
flickerstreak@30
|
133 ["Buffs"] = "增益",
|
flickerstreak@30
|
134 ["Chat/Communication"] = "聊天/通訊",
|
flickerstreak@30
|
135 ["Druid"] = "德魯伊",
|
flickerstreak@30
|
136 ["Hunter"] = "獵人",
|
flickerstreak@30
|
137 ["Mage"] = "法師",
|
flickerstreak@30
|
138 ["Paladin"] = "聖騎士",
|
flickerstreak@30
|
139 ["Priest"] = "牧師",
|
flickerstreak@30
|
140 ["Rogue"] = "盜賊",
|
flickerstreak@30
|
141 ["Shaman"] = "薩滿",
|
flickerstreak@30
|
142 ["Warlock"] = "術士",
|
flickerstreak@30
|
143 ["Warrior"] = "戰士",
|
flickerstreak@30
|
144 ["Healer"] = "治療者",
|
flickerstreak@30
|
145 ["Tank"] = "坦克",
|
flickerstreak@30
|
146 ["Caster"] = "施法者",
|
flickerstreak@30
|
147 ["Combat"] = "戰鬥",
|
flickerstreak@30
|
148 ["Compilations"] = "整合",
|
flickerstreak@30
|
149 ["Data Export"] = "資料匯出",
|
flickerstreak@30
|
150 ["Development Tools"] = "開發工具",
|
flickerstreak@30
|
151 ["Guild"] = "公會",
|
flickerstreak@30
|
152 ["Frame Modification"] = "框架修改",
|
flickerstreak@30
|
153 ["Interface Enhancements"] = "介面增強",
|
flickerstreak@30
|
154 ["Inventory"] = "庫存",
|
flickerstreak@30
|
155 ["Library"] = "程式庫",
|
flickerstreak@30
|
156 ["Map"] = "地圖",
|
flickerstreak@30
|
157 ["Mail"] = "郵件",
|
flickerstreak@30
|
158 ["Miscellaneous"] = "雜項",
|
flickerstreak@30
|
159 ["Quest"] = "任務",
|
flickerstreak@30
|
160 ["Raid"] = "團隊",
|
flickerstreak@30
|
161 ["Tradeskill"] = "交易技能",
|
flickerstreak@30
|
162 ["UnitFrame"] = "頭像框架",
|
flickerstreak@30
|
163 }
|
flickerstreak@30
|
164 elseif GetLocale() == "zhCN" then
|
flickerstreak@30
|
165 CATEGORIES = {
|
flickerstreak@30
|
166 ["Action Bars"] = "动作条",
|
flickerstreak@30
|
167 ["Auction"] = "拍卖",
|
flickerstreak@30
|
168 ["Audio"] = "音频",
|
flickerstreak@30
|
169 ["Battlegrounds/PvP"] = "战场/PvP",
|
flickerstreak@30
|
170 ["Buffs"] = "增益魔法",
|
flickerstreak@30
|
171 ["Chat/Communication"] = "聊天/交流",
|
flickerstreak@30
|
172 ["Druid"] = "德鲁伊",
|
flickerstreak@30
|
173 ["Hunter"] = "猎人",
|
flickerstreak@30
|
174 ["Mage"] = "法师",
|
flickerstreak@30
|
175 ["Paladin"] = "圣骑士",
|
flickerstreak@30
|
176 ["Priest"] = "牧师",
|
flickerstreak@30
|
177 ["Rogue"] = "潜行者",
|
flickerstreak@30
|
178 ["Shaman"] = "萨满祭司",
|
flickerstreak@30
|
179 ["Warlock"] = "术士",
|
flickerstreak@30
|
180 ["Warrior"] = "战士",
|
flickerstreak@30
|
181 ["Healer"] = "治疗",
|
flickerstreak@30
|
182 ["Tank"] = "坦克",
|
flickerstreak@30
|
183 ["Caster"] = "远程输出",
|
flickerstreak@30
|
184 ["Combat"] = "战斗",
|
flickerstreak@30
|
185 ["Compilations"] = "编译",
|
flickerstreak@30
|
186 ["Data Export"] = "数据导出",
|
flickerstreak@30
|
187 ["Development Tools"] = "开发工具",
|
flickerstreak@30
|
188 ["Guild"] = "公会",
|
flickerstreak@30
|
189 ["Frame Modification"] = "框架修改",
|
flickerstreak@30
|
190 ["Interface Enhancements"] = "界面增强",
|
flickerstreak@30
|
191 ["Inventory"] = "背包",
|
flickerstreak@30
|
192 ["Library"] = "库",
|
flickerstreak@30
|
193 ["Map"] = "地图",
|
flickerstreak@30
|
194 ["Mail"] = "邮件",
|
flickerstreak@30
|
195 ["Miscellaneous"] = "杂项",
|
flickerstreak@30
|
196 ["Quest"] = "任务",
|
flickerstreak@30
|
197 ["Raid"] = "团队",
|
flickerstreak@30
|
198 ["Tradeskill"] = "商业技能",
|
flickerstreak@30
|
199 ["UnitFrame"] = "头像框架",
|
flickerstreak@30
|
200 }
|
flickerstreak@30
|
201 elseif GetLocale() == "esES" then
|
flickerstreak@30
|
202 CATEGORIES = {
|
flickerstreak@30
|
203 ["Action Bars"] = "Barras de Acción",
|
flickerstreak@30
|
204 ["Auction"] = "Subasta",
|
flickerstreak@30
|
205 ["Audio"] = "Audio",
|
flickerstreak@30
|
206 ["Battlegrounds/PvP"] = "Campos de Batalla/JcJ",
|
flickerstreak@30
|
207 ["Buffs"] = "Buffs",
|
flickerstreak@30
|
208 ["Chat/Communication"] = "Chat/Comunicación",
|
flickerstreak@30
|
209 ["Druid"] = "Druida",
|
flickerstreak@30
|
210 ["Hunter"] = "Cazador",
|
flickerstreak@30
|
211 ["Mage"] = "Mago",
|
flickerstreak@30
|
212 ["Paladin"] = "Paladín",
|
flickerstreak@30
|
213 ["Priest"] = "Sacerdote",
|
flickerstreak@30
|
214 ["Rogue"] = "Pícaro",
|
flickerstreak@30
|
215 ["Shaman"] = "Chamán",
|
flickerstreak@30
|
216 ["Warlock"] = "Brujo",
|
flickerstreak@30
|
217 ["Warrior"] = "Guerrero",
|
flickerstreak@30
|
218 ["Healer"] = "Sanador",
|
flickerstreak@30
|
219 ["Tank"] = "Tanque",
|
flickerstreak@30
|
220 ["Caster"] = "Conjurador",
|
flickerstreak@30
|
221 ["Combat"] = "Combate",
|
flickerstreak@30
|
222 ["Compilations"] = "Compilaciones",
|
flickerstreak@30
|
223 ["Data Export"] = "Exportar Datos",
|
flickerstreak@30
|
224 ["Development Tools"] = "Herramientas de Desarrollo",
|
flickerstreak@30
|
225 ["Guild"] = "Hermandad",
|
flickerstreak@30
|
226 ["Frame Modification"] = "Modificación de Marcos",
|
flickerstreak@30
|
227 ["Interface Enhancements"] = "Mejoras de la Interfaz",
|
flickerstreak@30
|
228 ["Inventory"] = "Inventario",
|
flickerstreak@30
|
229 ["Library"] = "Biblioteca",
|
flickerstreak@30
|
230 ["Map"] = "Mapa",
|
flickerstreak@30
|
231 ["Mail"] = "Correo",
|
flickerstreak@30
|
232 ["Miscellaneous"] = "Misceláneo",
|
flickerstreak@30
|
233 ["Quest"] = "Misión",
|
flickerstreak@30
|
234 ["Raid"] = "Banda",
|
flickerstreak@30
|
235 ["Tradeskill"] = "Habilidad de Comercio",
|
flickerstreak@30
|
236 ["UnitFrame"] = "Marco de Unidades",
|
flickerstreak@30
|
237 }
|
flickerstreak@30
|
238 else -- enUS
|
flickerstreak@30
|
239 CATEGORIES = {
|
flickerstreak@30
|
240 ["Action Bars"] = "Action Bars",
|
flickerstreak@30
|
241 ["Auction"] = "Auction",
|
flickerstreak@30
|
242 ["Audio"] = "Audio",
|
flickerstreak@30
|
243 ["Battlegrounds/PvP"] = "Battlegrounds/PvP",
|
flickerstreak@30
|
244 ["Buffs"] = "Buffs",
|
flickerstreak@30
|
245 ["Chat/Communication"] = "Chat/Communication",
|
flickerstreak@30
|
246 ["Druid"] = "Druid",
|
flickerstreak@30
|
247 ["Hunter"] = "Hunter",
|
flickerstreak@30
|
248 ["Mage"] = "Mage",
|
flickerstreak@30
|
249 ["Paladin"] = "Paladin",
|
flickerstreak@30
|
250 ["Priest"] = "Priest",
|
flickerstreak@30
|
251 ["Rogue"] = "Rogue",
|
flickerstreak@30
|
252 ["Shaman"] = "Shaman",
|
flickerstreak@30
|
253 ["Warlock"] = "Warlock",
|
flickerstreak@30
|
254 ["Warrior"] = "Warrior",
|
flickerstreak@30
|
255 ["Healer"] = "Healer",
|
flickerstreak@30
|
256 ["Tank"] = "Tank",
|
flickerstreak@30
|
257 ["Caster"] = "Caster",
|
flickerstreak@30
|
258 ["Combat"] = "Combat",
|
flickerstreak@30
|
259 ["Compilations"] = "Compilations",
|
flickerstreak@30
|
260 ["Data Export"] = "Data Export",
|
flickerstreak@30
|
261 ["Development Tools"] = "Development Tools",
|
flickerstreak@30
|
262 ["Guild"] = "Guild",
|
flickerstreak@30
|
263 ["Frame Modification"] = "Frame Modification",
|
flickerstreak@30
|
264 ["Interface Enhancements"] = "Interface Enhancements",
|
flickerstreak@30
|
265 ["Inventory"] = "Inventory",
|
flickerstreak@30
|
266 ["Library"] = "Library",
|
flickerstreak@30
|
267 ["Map"] = "Map",
|
flickerstreak@30
|
268 ["Mail"] = "Mail",
|
flickerstreak@30
|
269 ["Miscellaneous"] = "Miscellaneous",
|
flickerstreak@30
|
270 ["Quest"] = "Quest",
|
flickerstreak@30
|
271 ["Raid"] = "Raid",
|
flickerstreak@30
|
272 ["Tradeskill"] = "Tradeskill",
|
flickerstreak@30
|
273 ["UnitFrame"] = "UnitFrame",
|
flickerstreak@30
|
274 }
|
flickerstreak@30
|
275 end
|
flickerstreak@30
|
276
|
flickerstreak@30
|
277 local select = _G.select
|
flickerstreak@30
|
278 local tostring = _G.tostring
|
flickerstreak@30
|
279 local pairs = _G.pairs
|
flickerstreak@30
|
280 local ipairs = _G.ipairs
|
flickerstreak@30
|
281 local error = _G.error
|
flickerstreak@30
|
282 local setmetatable = _G.setmetatable
|
flickerstreak@30
|
283 local getmetatable = _G.getmetatable
|
flickerstreak@30
|
284 local type = _G.type
|
flickerstreak@30
|
285 local pcall = _G.pcall
|
flickerstreak@30
|
286 local next = _G.next
|
flickerstreak@30
|
287 local tonumber = _G.tonumber
|
flickerstreak@30
|
288 local strmatch = _G.strmatch
|
flickerstreak@30
|
289 local table_remove = _G.table.remove
|
flickerstreak@30
|
290 local debugstack = _G.debugstack
|
flickerstreak@30
|
291 local LoadAddOn = _G.LoadAddOn
|
flickerstreak@30
|
292 local GetAddOnInfo = _G.GetAddOnInfo
|
flickerstreak@30
|
293 local GetAddOnMetadata = _G.GetAddOnMetadata
|
flickerstreak@30
|
294 local GetNumAddOns = _G.GetNumAddOns
|
flickerstreak@30
|
295 local DisableAddOn = _G.DisableAddOn
|
flickerstreak@30
|
296 local EnableAddOn = _G.EnableAddOn
|
flickerstreak@30
|
297 local IsAddOnLoadOnDemand = _G.IsAddOnLoadOnDemand
|
flickerstreak@30
|
298 local IsLoggedIn = _G.IsLoggedIn
|
flickerstreak@30
|
299 local geterrorhandler = _G.geterrorhandler
|
flickerstreak@30
|
300 local assert = _G.assert
|
flickerstreak@30
|
301 local collectgarbage = _G.collectgarbage
|
flickerstreak@30
|
302 local table_sort = _G.table.sort
|
flickerstreak@30
|
303 local table_concat = _G.table.concat
|
flickerstreak@30
|
304
|
flickerstreak@30
|
305 -- #AUTODOC_NAMESPACE Rock
|
flickerstreak@30
|
306
|
flickerstreak@30
|
307
|
flickerstreak@30
|
308 local LibStub = _G.LibStub
|
flickerstreak@30
|
309
|
flickerstreak@30
|
310 local Rock = LibStub:GetLibrary(MAJOR_VERSION, true) or _G.Rock
|
flickerstreak@30
|
311 local oldRock
|
flickerstreak@30
|
312 if not Rock then
|
flickerstreak@30
|
313 Rock = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
|
flickerstreak@30
|
314 if not Rock then
|
flickerstreak@30
|
315 return
|
flickerstreak@30
|
316 end
|
flickerstreak@30
|
317 Rock.name = MAJOR_VERSION
|
flickerstreak@30
|
318 else
|
flickerstreak@30
|
319 Rock, oldRock = Rock:NewLibrary(MAJOR_VERSION, MINOR_VERSION)
|
flickerstreak@30
|
320 if not Rock then
|
flickerstreak@30
|
321 return
|
flickerstreak@30
|
322 end
|
flickerstreak@30
|
323 end
|
flickerstreak@30
|
324 _G.Rock = Rock
|
flickerstreak@30
|
325
|
flickerstreak@30
|
326 local L = setmetatable({}, {__index=function(self,key) self[key] = key; return key end})
|
flickerstreak@30
|
327 if GetLocale() == "zhCN" then
|
flickerstreak@30
|
328 L["Advanced options"] = "高级选项"
|
flickerstreak@30
|
329 L["Advanced options for developers and power users."] = "开发者与高级用户的高级选项"
|
flickerstreak@30
|
330 L["Unit tests"] = "框体测试"
|
flickerstreak@30
|
331 L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "开启框体测试,仅供开发者使用。\n\n需要重载用户界面。"
|
flickerstreak@30
|
332 L["Contracts"] = "侦错协定"
|
flickerstreak@30
|
333 L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "启用侦错协定,这是给插件作者用来通报错误所使用。"
|
flickerstreak@30
|
334 L["Reload UI"] = "重载UI"
|
flickerstreak@30
|
335 L["Reload the User Interface for some changes to take effect."] = "部分功能更改需要重载用户界面才会生效。"
|
flickerstreak@30
|
336 L["Reload"] = "重载"
|
flickerstreak@30
|
337 L["Give donation"] = "捐赠"
|
flickerstreak@30
|
338 L["Donate"] = "捐赠"
|
flickerstreak@30
|
339 L["Give a much-needed donation to the author of this addon."] = "给插件作者捐赠支持插件开发。"
|
flickerstreak@30
|
340 L["File issue"] = "通报错误"
|
flickerstreak@30
|
341 L["Report"] = "报告"
|
flickerstreak@30
|
342 L["File a bug or request a new feature or an improvement to this addon."] = "发送错误报告或请求新功能及要改进的部分。"
|
flickerstreak@30
|
343 L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C复制网址,Alt-Tab切换到桌面,打开浏览器,在地址栏贴上网址。"
|
flickerstreak@30
|
344 L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C复制网址,Cmd-Tab切换到电脑桌面,打开浏览器,在地址栏贴上网址。"
|
flickerstreak@30
|
345 L["Enabled"] = "开启"
|
flickerstreak@30
|
346 L["Enable or disable this addon."] = "启用这个插件。"
|
flickerstreak@30
|
347
|
flickerstreak@30
|
348 elseif GetLocale() == "zhTW" then
|
flickerstreak@30
|
349 L["Advanced options"] = "進階選項"
|
flickerstreak@30
|
350 L["Advanced options for developers and power users."] = "插件作者、進階用戶選項"
|
flickerstreak@30
|
351 L["Unit tests"] = "單元測試"
|
flickerstreak@30
|
352 L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "啟用單元測試,這是給插件作者使用的功能。\n\n需要重載介面才能使用。"
|
flickerstreak@30
|
353 L["Contracts"] = "偵錯協定"
|
flickerstreak@30
|
354 L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "啟用偵錯協定,這是給插件作者用來通報錯誤所使用。"
|
flickerstreak@30
|
355 L["Reload UI"] = "重載介面"
|
flickerstreak@30
|
356 L["Reload the User Interface for some changes to take effect."] = "重新載入使用者介面,部分功能才會生效。"
|
flickerstreak@30
|
357 L["Reload"] = "重載"
|
flickerstreak@30
|
358 L["Give donation"] = "捐贈"
|
flickerstreak@30
|
359 L["Donate"] = "捐贈"
|
flickerstreak@30
|
360 L["Give a much-needed donation to the author of this addon."] = "捐贈金錢給插件作者。"
|
flickerstreak@30
|
361 L["File issue"] = "通報錯誤"
|
flickerstreak@30
|
362 L["Report"] = "報告"
|
flickerstreak@30
|
363 L["File a bug or request a new feature or an improvement to this addon."] = "發出錯誤報告或請求新功能及要改進的部分。"
|
flickerstreak@30
|
364 L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C複製網址,Alt-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
|
flickerstreak@30
|
365 L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C複製網址,Cmd-Tab切換到電腦桌面,打開瀏覽器,在網址列貼上網址。"
|
flickerstreak@30
|
366 L["Enabled"] = "啟用"
|
flickerstreak@30
|
367 L["Enable or disable this addon."] = "啟用這個插件。"
|
flickerstreak@30
|
368 elseif GetLocale() == "koKR" then
|
flickerstreak@30
|
369 L["Advanced options"] = "상세 옵션"
|
flickerstreak@30
|
370 L["Advanced options for developers and power users."] = "개발자와 파워 사용자를 위한 상세 옵션입니다."
|
flickerstreak@30
|
371 L["Unit tests"] = "유닛 테스트"
|
flickerstreak@30
|
372 L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."] = "유닛 테스트를 사용합니다. 이것은 개발자만을 위한 옵션입니다.\n\n변경된 결과를 적용하기 위해 당신의 UI를 재실행 합니다."
|
flickerstreak@30
|
373 L["Contracts"] = "계약"
|
flickerstreak@30
|
374 L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."] = "계약을 사용합니다. 이것은 개발자와 버그 파일을 알릴 분이면 누구나 사용 가능합니다. 계약이 가능하지 않으면 버그 파일을 보내지 마십시오. 이것은 당신의 애드온 속도를 약간 떨어뜨립니다."
|
flickerstreak@30
|
375 L["Reload UI"] = "UI 재실행"
|
flickerstreak@30
|
376 L["Reload the User Interface for some changes to take effect."] = "변경된 결과를 적용하기 위해 사용자 인터페이스를 재실행합니다."
|
flickerstreak@30
|
377 L["Reload"] = "재실행"
|
flickerstreak@30
|
378 L["Give donation"] = "기부"
|
flickerstreak@30
|
379 L["Donate"] = "기부"
|
flickerstreak@30
|
380 L["Give a much-needed donation to the author of this addon."] = "이 애드온의 제작자에게 필요한 기부를 합니다."
|
flickerstreak@30
|
381 L["File issue"] = "파일 이슈"
|
flickerstreak@30
|
382 L["Report"] = "보고"
|
flickerstreak@30
|
383 L["File a bug or request a new feature or an improvement to this addon."] = "버그 파일을 알리거나 새로운 기능 또는 이 애드온에 대한 개선을 부탁합니다."
|
flickerstreak@30
|
384 L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C로 복사합니다. Alt-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
|
flickerstreak@30
|
385 L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C로 복사합니다. Cmd-Tab 눌려 게임으로 부터 나간후 웹 브라우저를 엽니다. 복사된 링크를 주소 창에 붙여넣기 합니다."
|
flickerstreak@30
|
386 L["Enabled"] = "사용"
|
flickerstreak@30
|
387 L["Enable or disable this addon."] = "이 애드온을 사용하거나 사용하지 않습니다."
|
flickerstreak@30
|
388 elseif GetLocale() == "frFR" then
|
flickerstreak@30
|
389 L["Advanced options"] = "Options avancées"
|
flickerstreak@30
|
390 L["Advanced options for developers and power users."] = "Options avancées à l'attention des développeurs et des utilisateurs expérimentés."
|
flickerstreak@30
|
391 L["Reload UI"] = "Recharger IU"
|
flickerstreak@30
|
392 L["Reload the User Interface for some changes to take effect."] = "Recharge l'interface utilisateur afin que certains changements prennent effet."
|
flickerstreak@30
|
393 L["Reload"] = "Recharger"
|
flickerstreak@30
|
394 L["Give donation"] = "Faire un don"
|
flickerstreak@30
|
395 L["Donate"] = "Don"
|
flickerstreak@30
|
396 L["Give a much-needed donation to the author of this addon."] = "Permet de faire un don bien mérité à l'auteur de cet addon."
|
flickerstreak@30
|
397 L["File issue"] = "Problème"
|
flickerstreak@30
|
398 L["Report"] = "Signaler"
|
flickerstreak@30
|
399 L["File a bug or request a new feature or an improvement to this addon."] = "Permet de signaler un bogue ou de demander une amélioration à cet addon."
|
flickerstreak@30
|
400 L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Ctrl-C pour copier, puis Alt-Tab pour sortir du jeu. Ouvrez votre navigateur internet et collez le lien dans la barre d'adresse."
|
flickerstreak@30
|
401 L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] = "Cmd-C pour copier, puis Alt-Tab pour sortir du jeu. Ouvrez votre navigateur internet et collez le lien dans la barre d'adresse."
|
flickerstreak@30
|
402 L["Enabled"] = "Activé"
|
flickerstreak@30
|
403 L["Enable or disable this addon."] = "Active ou désactive cet addon."
|
flickerstreak@30
|
404 end
|
flickerstreak@30
|
405
|
flickerstreak@30
|
406 local isStandalone = debugstack():match("[Oo%.][Nn%.][Ss%.]\\([^\\]+)\\") == MAJOR_VERSION or nil
|
flickerstreak@30
|
407 local unitTestDB, enableContracts
|
flickerstreak@30
|
408
|
flickerstreak@30
|
409 local weakKey = { __mode = 'k' }
|
flickerstreak@30
|
410
|
flickerstreak@30
|
411 -- frame to manage events from
|
flickerstreak@30
|
412 Rock.frame = oldRock and oldRock.frame or _G.CreateFrame("Frame")
|
flickerstreak@30
|
413 local frame = Rock.frame
|
flickerstreak@30
|
414 -- dict of libraries in { ["major"] = object } form
|
flickerstreak@30
|
415 Rock.libraries = oldRock and oldRock.libraries or { [MAJOR_VERSION] = Rock }
|
flickerstreak@30
|
416 local libraries = Rock.libraries
|
flickerstreak@30
|
417 -- set of libraries which have gone through the finalization process in { [object] = true } form
|
flickerstreak@30
|
418 Rock.finalizedLibraries = setmetatable(oldRock and oldRock.finalizedLibraries or { }, weakKey)
|
flickerstreak@30
|
419 local finalizedLibraries = Rock.finalizedLibraries
|
flickerstreak@30
|
420 -- set of libraries which have been tried to be loaded.
|
flickerstreak@30
|
421 Rock.scannedLibraries = oldRock and oldRock.scannedLibraries or {}
|
flickerstreak@30
|
422 local scannedLibraries = Rock.scannedLibraries
|
flickerstreak@30
|
423 -- exportedMethods[library] = { "method1", "method2" }
|
flickerstreak@30
|
424 Rock.exportedMethods = setmetatable(oldRock and oldRock.exportedMethods or {}, weakKey)
|
flickerstreak@30
|
425 local exportedMethods = Rock.exportedMethods
|
flickerstreak@30
|
426 -- mixinToObject[mixin][object] = true
|
flickerstreak@30
|
427 Rock.mixinToObject = setmetatable(oldRock and oldRock.mixinToObject or {}, weakKey)
|
flickerstreak@30
|
428 local mixinToObject = Rock.mixinToObject
|
flickerstreak@30
|
429 -- dict of addons in { ["name"] = object } form
|
flickerstreak@30
|
430 Rock.addons = oldRock and oldRock.addons or {}
|
flickerstreak@30
|
431 local addons = Rock.addons
|
flickerstreak@30
|
432 -- set of libraries that should be finalized before ADDON_LOADED.
|
flickerstreak@30
|
433 Rock.pendingLibraries = setmetatable(oldRock and oldRock.pendingLibraries or { }, weakKey)
|
flickerstreak@30
|
434 local pendingLibraries = Rock.pendingLibraries
|
flickerstreak@30
|
435 -- list of addons in order of created that need to be initialized by ADDON_LOADED.
|
flickerstreak@30
|
436 Rock.pendingAddons = oldRock and oldRock.pendingAddons or {}
|
flickerstreak@30
|
437 local pendingAddons = Rock.pendingAddons
|
flickerstreak@30
|
438 -- dictionary of addons to their folder names
|
flickerstreak@30
|
439 Rock.addonToFolder = oldRock and oldRock.addonToFolder or {}
|
flickerstreak@30
|
440 local addonToFolder = Rock.addonToFolder
|
flickerstreak@30
|
441 -- set of folders which have been loaded
|
flickerstreak@30
|
442 Rock.foldersLoaded = oldRock and oldRock.foldersLoaded or {}
|
flickerstreak@30
|
443 local foldersLoaded = Rock.foldersLoaded
|
flickerstreak@30
|
444 -- list of addons in order of created that need to be enabled by PLAYER_LOGIN.
|
flickerstreak@30
|
445 Rock.pendingAddonsEnable = oldRock and oldRock.pendingAddonsEnable or {}
|
flickerstreak@30
|
446 local pendingAddonsEnable = Rock.pendingAddonsEnable
|
flickerstreak@30
|
447 -- set of addons which have been enabled at least once.
|
flickerstreak@30
|
448 Rock.addonsAlreadyEnabled = oldRock and oldRock.addonsAlreadyEnabled or {}
|
flickerstreak@30
|
449 local addonsAlreadyEnabled = Rock.addonsAlreadyEnabled
|
flickerstreak@30
|
450 -- set of addons which have no database and are set to be inactive.
|
flickerstreak@30
|
451 Rock.inactiveAddons = oldRock and oldRock.inactiveAddons or {}
|
flickerstreak@30
|
452 local inactiveAddons = Rock.inactiveAddons
|
flickerstreak@30
|
453 -- set of addons which are currently enabled (not necessarily should be)
|
flickerstreak@30
|
454 Rock.currentlyEnabledAddons = oldRock and oldRock.currentlyEnabledAddons or {}
|
flickerstreak@30
|
455 local currentlyEnabledAddons = Rock.currentlyEnabledAddons
|
flickerstreak@30
|
456 -- dictionary of namespace to list of functions which will be run.
|
flickerstreak@30
|
457 Rock.unitTests = oldRock and oldRock.unitTests or {}
|
flickerstreak@30
|
458 local unitTests = Rock.unitTests
|
flickerstreak@30
|
459 -- metatable for addons
|
flickerstreak@30
|
460 Rock.addon_mt = oldRock and oldRock.addon_mt or {}
|
flickerstreak@30
|
461 local addon_mt = Rock.addon_mt
|
flickerstreak@30
|
462 for k in pairs(addon_mt) do
|
flickerstreak@30
|
463 addon_mt[k] = nil
|
flickerstreak@30
|
464 end
|
flickerstreak@30
|
465 function addon_mt:__tostring()
|
flickerstreak@30
|
466 return tostring(self.name)
|
flickerstreak@30
|
467 end
|
flickerstreak@30
|
468
|
flickerstreak@30
|
469 local function better_tostring(self)
|
flickerstreak@30
|
470 if type(self) == "table" and self.name then
|
flickerstreak@30
|
471 return tostring(self.name)
|
flickerstreak@30
|
472 end
|
flickerstreak@30
|
473 return tostring(self)
|
flickerstreak@30
|
474 end
|
flickerstreak@30
|
475
|
flickerstreak@30
|
476 local function figureCurrentAddon(pos)
|
flickerstreak@30
|
477 local stack = debugstack(pos+1, 1, 0)
|
flickerstreak@30
|
478 local folder = stack:match("[Oo%.][Nn%.][Ss%.]\\([^\\]+)\\")
|
flickerstreak@30
|
479 if folder then
|
flickerstreak@30
|
480 return folder
|
flickerstreak@30
|
481 end
|
flickerstreak@30
|
482
|
flickerstreak@30
|
483 local partFolder = stack:match("...([^\\]+)\\")
|
flickerstreak@30
|
484 if partFolder then
|
flickerstreak@30
|
485 local partFolder_len = #partFolder
|
flickerstreak@30
|
486 for i = 1, GetNumAddOns() do
|
flickerstreak@30
|
487 local name = GetAddOnInfo(i)
|
flickerstreak@30
|
488 if #name >= partFolder_len then
|
flickerstreak@30
|
489 local partName = name:sub(-partFolder_len)
|
flickerstreak@30
|
490 if partName == partFolder then
|
flickerstreak@30
|
491 return name
|
flickerstreak@30
|
492 end
|
flickerstreak@30
|
493 end
|
flickerstreak@30
|
494 end
|
flickerstreak@30
|
495 end
|
flickerstreak@30
|
496 return nil
|
flickerstreak@30
|
497 end
|
flickerstreak@30
|
498
|
flickerstreak@30
|
499 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
500 Returns:
|
flickerstreak@30
|
501 string - the localized name of the given category.
|
flickerstreak@30
|
502 Arguments:
|
flickerstreak@30
|
503 string - the English name of the category.
|
flickerstreak@30
|
504 Example:
|
flickerstreak@30
|
505 local uf = Rock:GetLocalizedCategory("UnitFrame")
|
flickerstreak@30
|
506 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
507 function Rock:GetLocalizedCategory(name)
|
flickerstreak@30
|
508 if type(name) ~= "string" then
|
flickerstreak@30
|
509 error(("Bad argument #2 to `GetLocalizedCategory'. Expected %q, got %q."):format("string", type(name)), 2)
|
flickerstreak@30
|
510 end
|
flickerstreak@30
|
511 local cat = CATEGORIES[name]
|
flickerstreak@30
|
512 if cat then
|
flickerstreak@30
|
513 return cat
|
flickerstreak@30
|
514 end
|
flickerstreak@30
|
515 local name_lower = name:lower()
|
flickerstreak@30
|
516 for k in pairs(CATEGORIES) do
|
flickerstreak@30
|
517 if k:lower() == name_lower then
|
flickerstreak@30
|
518 return k
|
flickerstreak@30
|
519 end
|
flickerstreak@30
|
520 end
|
flickerstreak@30
|
521 return _G.UNKNOWN or "Unknown"
|
flickerstreak@30
|
522 end
|
flickerstreak@30
|
523
|
flickerstreak@30
|
524 local weak = {__mode = 'kv'}
|
flickerstreak@30
|
525
|
flickerstreak@30
|
526 Rock.recycleData = oldRock and oldRock.recycleData or {}
|
flickerstreak@30
|
527 local recycleData = Rock.recycleData
|
flickerstreak@30
|
528 if recycleData.pools then
|
flickerstreak@30
|
529 setmetatable(recycleData.pools, weak)
|
flickerstreak@30
|
530 end
|
flickerstreak@30
|
531 if recycleData.debugPools then
|
flickerstreak@30
|
532 setmetatable(recycleData.debugPools, weak)
|
flickerstreak@30
|
533 end
|
flickerstreak@30
|
534 if recycleData.newList then
|
flickerstreak@30
|
535 setmetatable(recycleData.newList, weak)
|
flickerstreak@30
|
536 end
|
flickerstreak@30
|
537 if recycleData.newDict then
|
flickerstreak@30
|
538 setmetatable(recycleData.newDict, weak)
|
flickerstreak@30
|
539 end
|
flickerstreak@30
|
540 if recycleData.newSet then
|
flickerstreak@30
|
541 setmetatable(recycleData.newSet, weak)
|
flickerstreak@30
|
542 end
|
flickerstreak@30
|
543 if recycleData.del then
|
flickerstreak@30
|
544 setmetatable(recycleData.del, weak)
|
flickerstreak@30
|
545 end
|
flickerstreak@30
|
546
|
flickerstreak@30
|
547 local tmp = {}
|
flickerstreak@30
|
548 local function myUnpack(t, start)
|
flickerstreak@30
|
549 if not start then
|
flickerstreak@30
|
550 start = 1
|
flickerstreak@30
|
551 end
|
flickerstreak@30
|
552 local value = t[start]
|
flickerstreak@30
|
553 if value == nil then
|
flickerstreak@30
|
554 return
|
flickerstreak@30
|
555 end
|
flickerstreak@30
|
556 t[start] = nil
|
flickerstreak@30
|
557 return value, myUnpack(t, start+1)
|
flickerstreak@30
|
558 end
|
flickerstreak@30
|
559
|
flickerstreak@30
|
560 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
561 Notes:
|
flickerstreak@30
|
562 * Returns functions for the specified namespace based on what is provided.
|
flickerstreak@30
|
563 * function types:
|
flickerstreak@30
|
564 ; "newList" : to create a list
|
flickerstreak@30
|
565 ; "newDict" : to create a dictionary
|
flickerstreak@30
|
566 ; "newSet" : to create a set
|
flickerstreak@30
|
567 ; "del" : to delete a table
|
flickerstreak@30
|
568 ; "unpackListAndDel" : deletes a table and returns what its contents were as a list, in order.
|
flickerstreak@30
|
569 ; "unpackSetAndDel" : deletes a table and returns what its contents were as a set, in no particular order.
|
flickerstreak@30
|
570 ; "unpackDictAndDel" : deletes a table and returns what its contents were as a dictionary, in no particular order.
|
flickerstreak@30
|
571 * If you provide "Debug" as the last argument, then the namespace can be debugged with ''':DebugRecycle'''
|
flickerstreak@30
|
572 * It is '''not recommended''' to use table recycling with tables that have more than 128 keys, as it is typically faster to let lua's garbage collector handle it.
|
flickerstreak@30
|
573 Arguments:
|
flickerstreak@30
|
574 string - the namespace. ''Note: this doesn't necessarily have to be a string.''
|
flickerstreak@30
|
575 Example:
|
flickerstreak@30
|
576 local newList, newDict, newSet, del, unpackListAndDel, unpackSetAndDel, unpackDictAndDel = Rock:GetRecyclingFunctions("MyNamespace", "newList", "newDict", "newSet", "del", "unpackListAndDel", "unpackSetAndDel", "unpackDictAndDel")
|
flickerstreak@30
|
577
|
flickerstreak@30
|
578 local t = newList('alpha', 'bravo') -- same as t = {'alpha', 'bravo'}
|
flickerstreak@30
|
579 local u = newDict('alpha', 'bravo') -- same as t = {['alpha'] = 'bravo'}
|
flickerstreak@30
|
580 local v = newSet('alpha', 'bravo') -- same as t = {['alpha'] = true, ['bravo'] = true}
|
flickerstreak@30
|
581 t = del(t) -- you want to clear your reference as well as deleting.
|
flickerstreak@30
|
582 u = del(u)
|
flickerstreak@30
|
583 v = del(v)
|
flickerstreak@30
|
584
|
flickerstreak@30
|
585 -- for debugging
|
flickerstreak@30
|
586 local newList = Rock:GetRecyclingFunctions("MyNamespace", "newList", "Debug")
|
flickerstreak@30
|
587 local t = newList()
|
flickerstreak@30
|
588 Rock:DebugRecycle("MyNamespace")
|
flickerstreak@30
|
589 t = del(t)
|
flickerstreak@30
|
590
|
flickerstreak@30
|
591 -- unpacking functions
|
flickerstreak@30
|
592 unpackListAndDel(newList(...)) => ...
|
flickerstreak@30
|
593 unpackSetAndDel(newSet(...)) => ...
|
flickerstreak@30
|
594 unpackDictAndDel(newDict(...)) => ...
|
flickerstreak@30
|
595 newList(unpackListAndDel(t)) => t
|
flickerstreak@30
|
596 newSet(unpackSetAndDel(t)) => t
|
flickerstreak@30
|
597 newDict(unpackDictAndDel(t)) => t
|
flickerstreak@30
|
598 -- as you can see, they are inverses of each other.
|
flickerstreak@30
|
599 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
600 function Rock:GetRecyclingFunctions(namespace, ...)
|
flickerstreak@30
|
601 local pools = recycleData.pools
|
flickerstreak@30
|
602 if not pools then
|
flickerstreak@30
|
603 pools = setmetatable({}, weak)
|
flickerstreak@30
|
604 recycleData.pools = pools
|
flickerstreak@30
|
605 end
|
flickerstreak@30
|
606 if namespace == "newList" or namespace == "newSet" or namespace == "newDict" or namespace == "del" or namespace == "unpackListAndDel" or namespace == "unpackSetAndDel" or namespace == "unpackDictAndDel" then
|
flickerstreak@30
|
607 error(("Bad argument #2 to `GetRecyclingFunctions'. Cannot be %q"):format(namespace), 2)
|
flickerstreak@30
|
608 end
|
flickerstreak@30
|
609 local pool = pools[namespace]
|
flickerstreak@30
|
610 if not pool then
|
flickerstreak@30
|
611 pool = setmetatable({}, weak)
|
flickerstreak@30
|
612 pools[namespace] = pool
|
flickerstreak@30
|
613 end
|
flickerstreak@30
|
614 local n = select('#', ...)
|
flickerstreak@30
|
615 local debug = select(n, ...) == "Debug"
|
flickerstreak@30
|
616 if debug then
|
flickerstreak@30
|
617 n = n - 1
|
flickerstreak@30
|
618 local debugPools = recycleData.debugPools
|
flickerstreak@30
|
619 if not debugPools then
|
flickerstreak@30
|
620 debugPools = setmetatable({}, weak)
|
flickerstreak@30
|
621 recycleData.debugPools = debugPools
|
flickerstreak@30
|
622 end
|
flickerstreak@30
|
623 debug = debugPools[namespace]
|
flickerstreak@30
|
624 if not debug then
|
flickerstreak@30
|
625 debug = { num = 0 }
|
flickerstreak@30
|
626 debugPools[namespace] = debug
|
flickerstreak@30
|
627 end
|
flickerstreak@30
|
628 elseif recycleData.debugPools and recycleData.debugPools[namespace] then
|
flickerstreak@30
|
629 debug = recycleData.debugPools[namespace]
|
flickerstreak@30
|
630 end
|
flickerstreak@30
|
631 for i = 1, n do
|
flickerstreak@30
|
632 local func = select(i, ...)
|
flickerstreak@30
|
633 local recycleData_func = recycleData[func]
|
flickerstreak@30
|
634 if not recycleData_func then
|
flickerstreak@30
|
635 recycleData_func = setmetatable({}, weak)
|
flickerstreak@30
|
636 recycleData[func] = recycleData_func
|
flickerstreak@30
|
637 end
|
flickerstreak@30
|
638 if func == "newList" then
|
flickerstreak@30
|
639 local newList = recycleData_func[namespace]
|
flickerstreak@30
|
640 if not newList then
|
flickerstreak@30
|
641 function newList(...)
|
flickerstreak@30
|
642 local t = next(pool)
|
flickerstreak@30
|
643 local n = select('#', ...)
|
flickerstreak@30
|
644 if t then
|
flickerstreak@30
|
645 pool[t] = nil
|
flickerstreak@30
|
646 for i = 1, n do
|
flickerstreak@30
|
647 t[i] = select(i, ...)
|
flickerstreak@30
|
648 end
|
flickerstreak@30
|
649 else
|
flickerstreak@30
|
650 t = { ... }
|
flickerstreak@30
|
651 end
|
flickerstreak@30
|
652
|
flickerstreak@30
|
653 if debug then
|
flickerstreak@30
|
654 debug[t] = debugstack(2)
|
flickerstreak@30
|
655 debug.num = debug.num + 1
|
flickerstreak@30
|
656 end
|
flickerstreak@30
|
657
|
flickerstreak@30
|
658 return t, n
|
flickerstreak@30
|
659 end
|
flickerstreak@30
|
660 recycleData_func[namespace] = newList
|
flickerstreak@30
|
661 end
|
flickerstreak@30
|
662 tmp[i] = newList
|
flickerstreak@30
|
663 elseif func == "newDict" then
|
flickerstreak@30
|
664 local newDict = recycleData_func[namespace]
|
flickerstreak@30
|
665 if not newDict then
|
flickerstreak@30
|
666 function newDict(...)
|
flickerstreak@30
|
667 local t = next(pool)
|
flickerstreak@30
|
668 if t then
|
flickerstreak@30
|
669 pool[t] = nil
|
flickerstreak@30
|
670 else
|
flickerstreak@30
|
671 t = {}
|
flickerstreak@30
|
672 end
|
flickerstreak@30
|
673
|
flickerstreak@30
|
674 for i = 1, select('#', ...), 2 do
|
flickerstreak@30
|
675 t[select(i, ...)] = select(i+1, ...)
|
flickerstreak@30
|
676 end
|
flickerstreak@30
|
677
|
flickerstreak@30
|
678 if debug then
|
flickerstreak@30
|
679 debug[t] = debugstack(2)
|
flickerstreak@30
|
680 debug.num = debug.num + 1
|
flickerstreak@30
|
681 end
|
flickerstreak@30
|
682
|
flickerstreak@30
|
683 return t
|
flickerstreak@30
|
684 end
|
flickerstreak@30
|
685 recycleData_func[namespace] = newDict
|
flickerstreak@30
|
686 end
|
flickerstreak@30
|
687 tmp[i] = newDict
|
flickerstreak@30
|
688 elseif func == "newSet" then
|
flickerstreak@30
|
689 local newSet = recycleData_func[namespace]
|
flickerstreak@30
|
690 if not newSet then
|
flickerstreak@30
|
691 function newSet(...)
|
flickerstreak@30
|
692 local t = next(pool)
|
flickerstreak@30
|
693 if t then
|
flickerstreak@30
|
694 pool[t] = nil
|
flickerstreak@30
|
695 else
|
flickerstreak@30
|
696 t = {}
|
flickerstreak@30
|
697 end
|
flickerstreak@30
|
698
|
flickerstreak@30
|
699 for i = 1, select('#', ...) do
|
flickerstreak@30
|
700 t[select(i, ...)] = true
|
flickerstreak@30
|
701 end
|
flickerstreak@30
|
702
|
flickerstreak@30
|
703 if debug then
|
flickerstreak@30
|
704 debug[t] = debugstack(2)
|
flickerstreak@30
|
705 debug.num = debug.num + 1
|
flickerstreak@30
|
706 end
|
flickerstreak@30
|
707
|
flickerstreak@30
|
708 return t
|
flickerstreak@30
|
709 end
|
flickerstreak@30
|
710 recycleData_func[namespace] = newSet
|
flickerstreak@30
|
711 end
|
flickerstreak@30
|
712 tmp[i] = newSet
|
flickerstreak@30
|
713 elseif func == "del" then
|
flickerstreak@30
|
714 local del = recycleData_func[namespace]
|
flickerstreak@30
|
715 if not del then
|
flickerstreak@30
|
716 function del(t)
|
flickerstreak@30
|
717 if not t then
|
flickerstreak@30
|
718 error(("Bad argument #1 to `del'. Expected %q, got %q."):format("table", type(t)), 2)
|
flickerstreak@30
|
719 end
|
flickerstreak@30
|
720 if pool[t] then
|
flickerstreak@30
|
721 local _, ret = pcall(error, "Error, double-free syndrome.", 3)
|
flickerstreak@30
|
722 geterrorhandler()(ret)
|
flickerstreak@30
|
723 end
|
flickerstreak@30
|
724 setmetatable(t, nil)
|
flickerstreak@30
|
725 for k in pairs(t) do
|
flickerstreak@30
|
726 t[k] = nil
|
flickerstreak@30
|
727 end
|
flickerstreak@30
|
728 t[true] = true
|
flickerstreak@30
|
729 t[true] = nil
|
flickerstreak@30
|
730 pool[t] = true
|
flickerstreak@30
|
731
|
flickerstreak@30
|
732 if debug then
|
flickerstreak@30
|
733 debug[t] = nil
|
flickerstreak@30
|
734 debug.num = debug.num - 1
|
flickerstreak@30
|
735 end
|
flickerstreak@30
|
736 return nil
|
flickerstreak@30
|
737 end
|
flickerstreak@30
|
738 recycleData_func[namespace] = del
|
flickerstreak@30
|
739 end
|
flickerstreak@30
|
740 tmp[i] = del
|
flickerstreak@30
|
741 elseif func == "unpackListAndDel" then
|
flickerstreak@30
|
742 local unpackListAndDel = recycleData_func[namespace]
|
flickerstreak@30
|
743 if not unpackListAndDel then
|
flickerstreak@30
|
744 local function f(t, start, finish)
|
flickerstreak@30
|
745 if start > finish then
|
flickerstreak@30
|
746 for k in pairs(t) do
|
flickerstreak@30
|
747 t[k] = nil
|
flickerstreak@30
|
748 end
|
flickerstreak@30
|
749 t[true] = true
|
flickerstreak@30
|
750 t[true] = nil
|
flickerstreak@30
|
751 pool[t] = true
|
flickerstreak@30
|
752 return
|
flickerstreak@30
|
753 end
|
flickerstreak@30
|
754 return t[start], f(t, start+1, finish)
|
flickerstreak@30
|
755 end
|
flickerstreak@30
|
756 function unpackListAndDel(t, start, finish)
|
flickerstreak@30
|
757 if not t then
|
flickerstreak@30
|
758 error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
|
flickerstreak@30
|
759 end
|
flickerstreak@30
|
760 if not start then
|
flickerstreak@30
|
761 start = 1
|
flickerstreak@30
|
762 end
|
flickerstreak@30
|
763 if not finish then
|
flickerstreak@30
|
764 finish = #t
|
flickerstreak@30
|
765 end
|
flickerstreak@30
|
766 setmetatable(t, nil)
|
flickerstreak@30
|
767 if debug then
|
flickerstreak@30
|
768 debug[t] = nil
|
flickerstreak@30
|
769 debug.num = debug.num - 1
|
flickerstreak@30
|
770 end
|
flickerstreak@30
|
771 return f(t, start, finish)
|
flickerstreak@30
|
772 end
|
flickerstreak@30
|
773 end
|
flickerstreak@30
|
774 tmp[i] = unpackListAndDel
|
flickerstreak@30
|
775 elseif func == "unpackSetAndDel" then
|
flickerstreak@30
|
776 local unpackSetAndDel = recycleData_func[namespace]
|
flickerstreak@30
|
777 if not unpackSetAndDel then
|
flickerstreak@30
|
778 local function f(t, current)
|
flickerstreak@30
|
779 current = next(t, current)
|
flickerstreak@30
|
780 if current == nil then
|
flickerstreak@30
|
781 for k in pairs(t) do
|
flickerstreak@30
|
782 t[k] = nil
|
flickerstreak@30
|
783 end
|
flickerstreak@30
|
784 t[true] = true
|
flickerstreak@30
|
785 t[true] = nil
|
flickerstreak@30
|
786 pool[t] = true
|
flickerstreak@30
|
787 return
|
flickerstreak@30
|
788 end
|
flickerstreak@30
|
789 return current, f(t, current)
|
flickerstreak@30
|
790 end
|
flickerstreak@30
|
791 function unpackSetAndDel(t)
|
flickerstreak@30
|
792 if not t then
|
flickerstreak@30
|
793 error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
|
flickerstreak@30
|
794 end
|
flickerstreak@30
|
795 setmetatable(t, nil)
|
flickerstreak@30
|
796 if debug then
|
flickerstreak@30
|
797 debug[t] = nil
|
flickerstreak@30
|
798 debug.num = debug.num - 1
|
flickerstreak@30
|
799 end
|
flickerstreak@30
|
800 return f(t, nil)
|
flickerstreak@30
|
801 end
|
flickerstreak@30
|
802 end
|
flickerstreak@30
|
803 tmp[i] = unpackSetAndDel
|
flickerstreak@30
|
804 elseif func == "unpackDictAndDel" then
|
flickerstreak@30
|
805 local unpackDictAndDel = recycleData_func[namespace]
|
flickerstreak@30
|
806 if not unpackDictAndDel then
|
flickerstreak@30
|
807 local function f(t, current)
|
flickerstreak@30
|
808 local value
|
flickerstreak@30
|
809 current, value = next(t, current)
|
flickerstreak@30
|
810 if current == nil then
|
flickerstreak@30
|
811 for k in pairs(t) do
|
flickerstreak@30
|
812 t[k] = nil
|
flickerstreak@30
|
813 end
|
flickerstreak@30
|
814 t[true] = true
|
flickerstreak@30
|
815 t[true] = nil
|
flickerstreak@30
|
816 pool[t] = true
|
flickerstreak@30
|
817 return
|
flickerstreak@30
|
818 end
|
flickerstreak@30
|
819 return current, value, f(t, current)
|
flickerstreak@30
|
820 end
|
flickerstreak@30
|
821 function unpackDictAndDel(t)
|
flickerstreak@30
|
822 if not t then
|
flickerstreak@30
|
823 error(("Bad argument #1 to `unpackListAndDel'. Expected %q, got %q."):format("table", type(t)), 2)
|
flickerstreak@30
|
824 end
|
flickerstreak@30
|
825 setmetatable(t, nil)
|
flickerstreak@30
|
826 if debug then
|
flickerstreak@30
|
827 debug[t] = nil
|
flickerstreak@30
|
828 debug.num = debug.num - 1
|
flickerstreak@30
|
829 end
|
flickerstreak@30
|
830 return f(t, nil)
|
flickerstreak@30
|
831 end
|
flickerstreak@30
|
832 end
|
flickerstreak@30
|
833 tmp[i] = unpackDictAndDel
|
flickerstreak@30
|
834 else
|
flickerstreak@30
|
835 error(("Bad argument #%d to `GetRecyclingFunctions': %q, %q, %q, %q, %q, %q, or %q expected, got %s"):format(i+2, "newList", "newDict", "newSet", "del", "unpackListAndDel", "unpackSetAndDel", "unpackDictAndDel", type(func) == "string" and ("%q"):format(func) or tostring(func)), 2)
|
flickerstreak@30
|
836 end
|
flickerstreak@30
|
837 end
|
flickerstreak@30
|
838 return myUnpack(tmp)
|
flickerstreak@30
|
839 end
|
flickerstreak@30
|
840
|
flickerstreak@30
|
841 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
842 Notes:
|
flickerstreak@30
|
843 * Prints information about the specified recycling namespace, including what tables are still in play and where they come from and how many there are.
|
flickerstreak@30
|
844 * This goes in tandem with ''':GetRecyclingFunctions'''
|
flickerstreak@30
|
845 Arguments:
|
flickerstreak@30
|
846 string - the namespace. ''Note: this doesn't necessarily have to be a string.''
|
flickerstreak@30
|
847 Example:
|
flickerstreak@30
|
848 local newList = Rock:GetRecyclingFunctions("MyNamespace", "newList", "Debug")
|
flickerstreak@30
|
849 local t = newList()
|
flickerstreak@30
|
850 Rock:DebugRecycle("MyNamespace")
|
flickerstreak@30
|
851 t = del(t)
|
flickerstreak@30
|
852 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
853 function Rock:DebugRecycle(namespace)
|
flickerstreak@30
|
854 local debug = recycleData.debugPools and recycleData.debugPools[namespace]
|
flickerstreak@30
|
855 if not debug then
|
flickerstreak@30
|
856 return
|
flickerstreak@30
|
857 end
|
flickerstreak@30
|
858 for k, v in pairs(debug) do
|
flickerstreak@30
|
859 if k ~= "num" then
|
flickerstreak@30
|
860 _G.DEFAULT_CHAT_FRAME:AddMessage(v)
|
flickerstreak@30
|
861 _G.DEFAULT_CHAT_FRAME:AddMessage("------")
|
flickerstreak@30
|
862 end
|
flickerstreak@30
|
863 end
|
flickerstreak@30
|
864 _G.DEFAULT_CHAT_FRAME:AddMessage(("%s: %d tables in action."):format(tostring(namespace), debug.num))
|
flickerstreak@30
|
865 end
|
flickerstreak@30
|
866
|
flickerstreak@30
|
867 local newList, del, unpackListAndDel, unpackDictAndDel = Rock:GetRecyclingFunctions(MAJOR_VERSION, "newList", "del", "unpackListAndDel", "unpackDictAndDel")
|
flickerstreak@30
|
868
|
flickerstreak@30
|
869 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
870 Notes:
|
flickerstreak@30
|
871 * Adds a unit test for the specified namespace
|
flickerstreak@30
|
872 * The function provided is called, and it should be where tests are performed, if a problem occurs, an error should fire. If no problems occur, it should return silently.
|
flickerstreak@30
|
873 * You can have as many tests per namespace as you want.
|
flickerstreak@30
|
874 Arguments:
|
flickerstreak@30
|
875 string - the namespace.
|
flickerstreak@30
|
876 function - the function to call.
|
flickerstreak@30
|
877 Example:
|
flickerstreak@30
|
878 Rock:AddUnitTest("LibMonkey-1.0", function()
|
flickerstreak@30
|
879 local LibMonkey = Rock("LibMonkey-1.0")
|
flickerstreak@30
|
880 assert(LibMonkey:Fling() == "Poo")
|
flickerstreak@30
|
881 end)
|
flickerstreak@30
|
882 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
883 function Rock:AddUnitTest(namespace, func)
|
flickerstreak@30
|
884 if not isStandalone then
|
flickerstreak@30
|
885 return
|
flickerstreak@30
|
886 end
|
flickerstreak@30
|
887 if type(namespace) ~= "string" then
|
flickerstreak@30
|
888 error(("Bad argument #2 to `AddUnitTest'. Expected %q, got %q."):format("string", type(namespace)), 2)
|
flickerstreak@30
|
889 end
|
flickerstreak@30
|
890 if namespace:find("^Lib[A-Z]") then
|
flickerstreak@30
|
891 local addon = figureCurrentAddon(2)
|
flickerstreak@30
|
892 if addon ~= namespace then
|
flickerstreak@30
|
893 return
|
flickerstreak@30
|
894 end
|
flickerstreak@30
|
895 end
|
flickerstreak@30
|
896 if type(func) ~= "function" then
|
flickerstreak@30
|
897 error(("Bad argument #3 to `AddUnitTest'. Expected %q, got %q."):format("function", type(func)), 2)
|
flickerstreak@30
|
898 end
|
flickerstreak@30
|
899 local addon = figureCurrentAddon(2)
|
flickerstreak@30
|
900 if libraries[namespace] and addon ~= namespace then
|
flickerstreak@30
|
901 -- only work on standalone libraries.
|
flickerstreak@30
|
902 return
|
flickerstreak@30
|
903 end
|
flickerstreak@30
|
904 local unitTests_namespace = unitTests[namespace]
|
flickerstreak@30
|
905 if not unitTests_namespace then
|
flickerstreak@30
|
906 unitTests_namespace = newList()
|
flickerstreak@30
|
907 unitTests[namespace] = unitTests_namespace
|
flickerstreak@30
|
908 end
|
flickerstreak@30
|
909 if not unitTests_namespace.addon then
|
flickerstreak@30
|
910 unitTests_namespace.addon = addon
|
flickerstreak@30
|
911 end
|
flickerstreak@30
|
912 if unitTestDB and not unitTestDB[namespace] then
|
flickerstreak@30
|
913 return
|
flickerstreak@30
|
914 end
|
flickerstreak@30
|
915 unitTests_namespace[#unitTests_namespace+1] = func
|
flickerstreak@30
|
916 end
|
flickerstreak@30
|
917
|
flickerstreak@30
|
918 local LibRockEvent
|
flickerstreak@30
|
919 local LibRockModuleCore
|
flickerstreak@30
|
920 local OpenDonationFrame, OpenIssueFrame
|
flickerstreak@30
|
921 function Rock:OnLibraryLoad(major, library)
|
flickerstreak@30
|
922 if major == "LibRockEvent-1.0" then
|
flickerstreak@30
|
923 LibRockEvent = library
|
flickerstreak@30
|
924 LibRockEvent:Embed(Rock)
|
flickerstreak@30
|
925 elseif major == "LibRockModuleCore-1.0" then
|
flickerstreak@30
|
926 LibRockModuleCore = library
|
flickerstreak@30
|
927 elseif major == "LibRockConfig-1.0" then
|
flickerstreak@30
|
928 if isStandalone then
|
flickerstreak@30
|
929 library.rockOptions.args.advanced = {
|
flickerstreak@30
|
930 type = 'group',
|
flickerstreak@30
|
931 groupType = 'inline',
|
flickerstreak@30
|
932 name = L["Advanced options"],
|
flickerstreak@30
|
933 desc = L["Advanced options for developers and power users."],
|
flickerstreak@30
|
934 order = -1,
|
flickerstreak@30
|
935 args = {
|
flickerstreak@30
|
936 unitTests = {
|
flickerstreak@30
|
937 type = 'multichoice',
|
flickerstreak@30
|
938 name = L["Unit tests"],
|
flickerstreak@30
|
939 desc = L["Enable unit tests to be run. This is for developers only.\n\nYou must ReloadUI for changes to take effect."],
|
flickerstreak@30
|
940 get = function(key)
|
flickerstreak@30
|
941 return unitTestDB[key]
|
flickerstreak@30
|
942 end,
|
flickerstreak@30
|
943 set = function(key, value)
|
flickerstreak@30
|
944 unitTestDB[key] = value or nil
|
flickerstreak@30
|
945 end,
|
flickerstreak@30
|
946 choices = function()
|
flickerstreak@30
|
947 local t = newList()
|
flickerstreak@30
|
948 for k in pairs(unitTests) do
|
flickerstreak@30
|
949 t[k] = k
|
flickerstreak@30
|
950 end
|
flickerstreak@30
|
951 return "@dict", unpackDictAndDel(t)
|
flickerstreak@30
|
952 end
|
flickerstreak@30
|
953 },
|
flickerstreak@30
|
954 contracts = {
|
flickerstreak@30
|
955 type = 'boolean',
|
flickerstreak@30
|
956 name = L["Contracts"],
|
flickerstreak@30
|
957 desc = L["Enable contracts to be run. This is for developers and anyone wanting to file a bug. Do not file a bug unless contracts are enabled. This will slightly slow down your addons if enabled."],
|
flickerstreak@30
|
958 get = function()
|
flickerstreak@30
|
959 return enableContracts
|
flickerstreak@30
|
960 end,
|
flickerstreak@30
|
961 set = function(value)
|
flickerstreak@30
|
962 _G.LibRock_1_0DB.contracts = value or nil
|
flickerstreak@30
|
963 enableContracts = value
|
flickerstreak@30
|
964 end,
|
flickerstreak@30
|
965 }
|
flickerstreak@30
|
966 }
|
flickerstreak@30
|
967 }
|
flickerstreak@30
|
968 end
|
flickerstreak@30
|
969 library.rockOptions.args.reloadui = {
|
flickerstreak@30
|
970 type = 'execute',
|
flickerstreak@30
|
971 name = L["Reload UI"],
|
flickerstreak@30
|
972 desc = L["Reload the User Interface for some changes to take effect."],
|
flickerstreak@30
|
973 buttonText = L["Reload"],
|
flickerstreak@30
|
974 func = function()
|
flickerstreak@30
|
975 _G.ReloadUI()
|
flickerstreak@30
|
976 end,
|
flickerstreak@30
|
977 order = -2,
|
flickerstreak@30
|
978 }
|
flickerstreak@30
|
979 Rock.donate = "Paypal:ckknight AT gmail DOT com"
|
flickerstreak@30
|
980 library.rockOptions.args.donate = {
|
flickerstreak@30
|
981 type = 'execute',
|
flickerstreak@30
|
982 name = L["Give donation"],
|
flickerstreak@30
|
983 buttonText = L["Donate"],
|
flickerstreak@30
|
984 desc = L["Give a much-needed donation to the author of this addon."],
|
flickerstreak@30
|
985 func = OpenDonationFrame,
|
flickerstreak@30
|
986 passValue = Rock,
|
flickerstreak@30
|
987 order = -3,
|
flickerstreak@30
|
988 }
|
flickerstreak@30
|
989 Rock.issueTracker = "Wowace:10027"
|
flickerstreak@30
|
990 library.rockOptions.args.issue = {
|
flickerstreak@30
|
991 type = 'execute',
|
flickerstreak@30
|
992 name = L["File issue"],
|
flickerstreak@30
|
993 buttonText = L["Report"],
|
flickerstreak@30
|
994 desc = L["File a bug or request a new feature or an improvement to this addon."],
|
flickerstreak@30
|
995 func = OpenIssueFrame,
|
flickerstreak@30
|
996 passValue = Rock,
|
flickerstreak@30
|
997 order = -4,
|
flickerstreak@30
|
998 }
|
flickerstreak@30
|
999 end
|
flickerstreak@30
|
1000 end
|
flickerstreak@30
|
1001
|
flickerstreak@30
|
1002 addon_mt.__index = {}
|
flickerstreak@30
|
1003 local addon_mt___index = addon_mt.__index
|
flickerstreak@30
|
1004 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1005 #FORCE_DOC
|
flickerstreak@30
|
1006 Notes:
|
flickerstreak@30
|
1007 * This is exported to all addons.
|
flickerstreak@30
|
1008 * This information is retrieved from LibRockModuleCore-1.0 if it is a module, otherwise from LibRockDB-1.0 if it uses that as a mixin, otherwise it keeps a variable locally.
|
flickerstreak@30
|
1009 Returns:
|
flickerstreak@30
|
1010 boolean - whether the addon is in an active state or not.
|
flickerstreak@30
|
1011 Example:
|
flickerstreak@30
|
1012 local active = MyAddon:IsActive()
|
flickerstreak@30
|
1013 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1014 function addon_mt___index:IsActive()
|
flickerstreak@30
|
1015 if LibRockModuleCore then
|
flickerstreak@30
|
1016 local core = LibRockModuleCore:HasModule(self)
|
flickerstreak@30
|
1017 if core then
|
flickerstreak@30
|
1018 return core:IsModuleActive(self)
|
flickerstreak@30
|
1019 end
|
flickerstreak@30
|
1020 end
|
flickerstreak@30
|
1021
|
flickerstreak@30
|
1022 local self_db = self.db
|
flickerstreak@30
|
1023 if self_db then
|
flickerstreak@30
|
1024 local disabled
|
flickerstreak@30
|
1025 local self_db_raw = self_db.raw
|
flickerstreak@30
|
1026 if self_db_raw then
|
flickerstreak@30
|
1027 local self_db_raw_disabled = self_db_raw.disabled
|
flickerstreak@30
|
1028 if self_db_raw_disabled then
|
flickerstreak@30
|
1029 local profile = type(self.GetProfile) == "function" and select(2, self:GetProfile()) or false
|
flickerstreak@30
|
1030 disabled = self_db_raw_disabled[profile]
|
flickerstreak@30
|
1031 end
|
flickerstreak@30
|
1032 else
|
flickerstreak@30
|
1033 return false
|
flickerstreak@30
|
1034 end
|
flickerstreak@30
|
1035 return not disabled
|
flickerstreak@30
|
1036 end
|
flickerstreak@30
|
1037
|
flickerstreak@30
|
1038 return not inactiveAddons[self]
|
flickerstreak@30
|
1039 end
|
flickerstreak@30
|
1040 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1041 #FORCE_DOC
|
flickerstreak@30
|
1042 Notes:
|
flickerstreak@30
|
1043 * This is exported to all addons.
|
flickerstreak@30
|
1044 * If it enables the addon, it will call :OnEnable(first) on the addon and :OnEmbedEnable(addon, first) on all its mixins.
|
flickerstreak@30
|
1045 * If it disables the addon, it will call :OnDisable(first) on the addon and :OnEmbedDisable(addon, first) on all its mixins.
|
flickerstreak@30
|
1046 * This information is stored by LibRockModuleCore-1.0 if it is a module, otherwise from LibRockDB-1.0 if it uses that as a mixin, otherwise it keeps a variable locally.
|
flickerstreak@30
|
1047 Arguments:
|
flickerstreak@30
|
1048 [optional] boolean - whether the addon should be in an active state or not. Default: not :IsActive()
|
flickerstreak@30
|
1049 Returns:
|
flickerstreak@30
|
1050 boolean - whether the addon is in an active state or not.
|
flickerstreak@30
|
1051 Example:
|
flickerstreak@30
|
1052 MyAddon:ToggleActive() -- switch
|
flickerstreak@30
|
1053 MyAddon:ToggleActive(true) -- force on
|
flickerstreak@30
|
1054 MyAddon:ToggleActive(false) -- force off
|
flickerstreak@30
|
1055 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1056 function addon_mt___index:ToggleActive(state)
|
flickerstreak@30
|
1057 if state and state ~= true then
|
flickerstreak@30
|
1058 error(("Bad argument #2 to `ToggleActive'. Expected %q or %q, got %q."):format("boolean", "nil", type(state)), 2)
|
flickerstreak@30
|
1059 end
|
flickerstreak@30
|
1060 if LibRockModuleCore then
|
flickerstreak@30
|
1061 local core = LibRockModuleCore:HasModule(self)
|
flickerstreak@30
|
1062 if core then
|
flickerstreak@30
|
1063 return core:ToggleModuleActive(self, state)
|
flickerstreak@30
|
1064 end
|
flickerstreak@30
|
1065 end
|
flickerstreak@30
|
1066
|
flickerstreak@30
|
1067 local self_db = self.db
|
flickerstreak@30
|
1068 if self_db then
|
flickerstreak@30
|
1069 local self_db_raw = self_db.raw
|
flickerstreak@30
|
1070 if not self_db_raw then
|
flickerstreak@30
|
1071 error("Error saving to database with `ToggleActive'. db.raw not available.", 2)
|
flickerstreak@30
|
1072 end
|
flickerstreak@30
|
1073 local self_db_raw_disabled = self_db_raw.disabled
|
flickerstreak@30
|
1074 if not self_db_raw_disabled then
|
flickerstreak@30
|
1075 self_db_raw_disabled = newList()
|
flickerstreak@30
|
1076 self_db_raw.disabled = self_db_raw_disabled
|
flickerstreak@30
|
1077 end
|
flickerstreak@30
|
1078 local profile = type(self.GetProfile) == "function" and select(2, self:GetProfile()) or false
|
flickerstreak@30
|
1079 if state == nil then
|
flickerstreak@30
|
1080 state = not not self_db_raw_disabled[profile]
|
flickerstreak@30
|
1081 elseif (not self_db_raw_disabled[profile]) == state then
|
flickerstreak@30
|
1082 return
|
flickerstreak@30
|
1083 end
|
flickerstreak@30
|
1084 self_db_raw_disabled[profile] = not state or nil
|
flickerstreak@30
|
1085 if next(self_db_raw_disabled) == nil then
|
flickerstreak@30
|
1086 self_db_raw.disabled = del(self_db_raw_disabled)
|
flickerstreak@30
|
1087 end
|
flickerstreak@30
|
1088 else
|
flickerstreak@30
|
1089 if state == nil then
|
flickerstreak@30
|
1090 state = not not inactiveAddons[self]
|
flickerstreak@30
|
1091 elseif (not inactiveAddons[self]) == state then
|
flickerstreak@30
|
1092 return
|
flickerstreak@30
|
1093 end
|
flickerstreak@30
|
1094 inactiveAddons[self] = not state or nil
|
flickerstreak@30
|
1095 end
|
flickerstreak@30
|
1096
|
flickerstreak@30
|
1097 Rock:RecheckEnabledStates()
|
flickerstreak@30
|
1098
|
flickerstreak@30
|
1099 return state
|
flickerstreak@30
|
1100 end
|
flickerstreak@30
|
1101
|
flickerstreak@30
|
1102 local function noop() end
|
flickerstreak@30
|
1103
|
flickerstreak@30
|
1104 do
|
flickerstreak@30
|
1105 local preconditions = setmetatable({}, weakKey)
|
flickerstreak@30
|
1106 local postconditions = setmetatable({}, weakKey)
|
flickerstreak@30
|
1107 local postconditionsOld = setmetatable({}, weakKey)
|
flickerstreak@30
|
1108
|
flickerstreak@30
|
1109 local currentMethod = nil
|
flickerstreak@30
|
1110
|
flickerstreak@30
|
1111 local function hook(object, method)
|
flickerstreak@30
|
1112 local object_method = object[method]
|
flickerstreak@30
|
1113 object[method] = function(...)
|
flickerstreak@30
|
1114 local pre = preconditions[object_method]
|
flickerstreak@30
|
1115 local post = postconditions[object_method]
|
flickerstreak@30
|
1116 if pre then
|
flickerstreak@30
|
1117 local old_currentMethod = currentMethod
|
flickerstreak@30
|
1118 currentMethod = method
|
flickerstreak@30
|
1119 pre(...)
|
flickerstreak@30
|
1120 currentMethod = old_currentMethod
|
flickerstreak@30
|
1121 end
|
flickerstreak@30
|
1122 if not post then
|
flickerstreak@30
|
1123 return object_method(...)
|
flickerstreak@30
|
1124 end
|
flickerstreak@30
|
1125 local oldFunc = postconditionsOld[object_method]
|
flickerstreak@30
|
1126 local old
|
flickerstreak@30
|
1127 if oldFunc then
|
flickerstreak@30
|
1128 old = newList()
|
flickerstreak@30
|
1129 oldFunc(old, ...)
|
flickerstreak@30
|
1130 end
|
flickerstreak@30
|
1131
|
flickerstreak@30
|
1132 local old_currentMethod = currentMethod
|
flickerstreak@30
|
1133 currentMethod = nil
|
flickerstreak@30
|
1134 local ret, n = newList(object_method(...))
|
flickerstreak@30
|
1135
|
flickerstreak@30
|
1136 currentMethod = method
|
flickerstreak@30
|
1137 if old then
|
flickerstreak@30
|
1138 post(old, ret, ...)
|
flickerstreak@30
|
1139 old = del(old)
|
flickerstreak@30
|
1140 else
|
flickerstreak@30
|
1141 post(ret, ...)
|
flickerstreak@30
|
1142 end
|
flickerstreak@30
|
1143 currentMethod = old_currentMethod
|
flickerstreak@30
|
1144 return unpackListAndDel(ret, 1, n)
|
flickerstreak@30
|
1145 end
|
flickerstreak@30
|
1146 end
|
flickerstreak@30
|
1147
|
flickerstreak@30
|
1148 local function precondition(object, method, func)
|
flickerstreak@30
|
1149 if type(object) ~= "table" then
|
flickerstreak@30
|
1150 error(("Bad argument #1 to `precondition'. Expected %q, got %q."):format("table", type(object)), 2)
|
flickerstreak@30
|
1151 end
|
flickerstreak@30
|
1152 if type(object[method]) ~= "function" then
|
flickerstreak@30
|
1153 error(("Method %q not found on object %s. Expected %q, got %q."):format(tostring(method), tostring(object), "function", type(object[method])), 2)
|
flickerstreak@30
|
1154 end
|
flickerstreak@30
|
1155 if type(func) ~= "function" then
|
flickerstreak@30
|
1156 error(("Bad argument #3 to `precondition'. Expected %q, got %q."):format("function", type(func)), 2)
|
flickerstreak@30
|
1157 end
|
flickerstreak@30
|
1158
|
flickerstreak@30
|
1159 local object_method = object[method]
|
flickerstreak@30
|
1160 if preconditions[object_method] then
|
flickerstreak@30
|
1161 error("Cannot call `preconditon' on the same method twice.", 2)
|
flickerstreak@30
|
1162 end
|
flickerstreak@30
|
1163 preconditions[object_method] = func
|
flickerstreak@30
|
1164
|
flickerstreak@30
|
1165 if not postconditions[object_method] then
|
flickerstreak@30
|
1166 hook(object, method)
|
flickerstreak@30
|
1167 end
|
flickerstreak@30
|
1168 end
|
flickerstreak@30
|
1169
|
flickerstreak@30
|
1170 local function postcondition(object, method, func, fillOld)
|
flickerstreak@30
|
1171 if type(object) ~= "table" then
|
flickerstreak@30
|
1172 error(("Bad argument #1 to `postcondition'. Expected %q, got %q."):format("table", type(object)), 2)
|
flickerstreak@30
|
1173 end
|
flickerstreak@30
|
1174 if type(object[method]) ~= "function" then
|
flickerstreak@30
|
1175 error(("Method %q not found on object %s. Expected %q, got %q."):format(tostring(method), tostring(object), "function", type(object[method])), 2)
|
flickerstreak@30
|
1176 end
|
flickerstreak@30
|
1177 if type(func) ~= "function" then
|
flickerstreak@30
|
1178 error(("Bad argument #3 to `postcondition'. Expected %q, got %q."):format("function", type(func)), 2)
|
flickerstreak@30
|
1179 end
|
flickerstreak@30
|
1180 if fillOld and type(fillOld) ~= "function" then
|
flickerstreak@30
|
1181 error(("Bad argument #4 to `postcondition'. Expected %q or %q, got %q."):format("function", "nil", type(func)), 2)
|
flickerstreak@30
|
1182 end
|
flickerstreak@30
|
1183
|
flickerstreak@30
|
1184 local object_method = object[method]
|
flickerstreak@30
|
1185 if postconditions[object_method] then
|
flickerstreak@30
|
1186 error("Cannot call `postcondition' on the same method twice.", 2)
|
flickerstreak@30
|
1187 end
|
flickerstreak@30
|
1188 postconditions[object_method] = func
|
flickerstreak@30
|
1189 postconditionsOld[object_method] = fillOld
|
flickerstreak@30
|
1190
|
flickerstreak@30
|
1191 if not preconditions[object_method] then
|
flickerstreak@30
|
1192 hook(object, method)
|
flickerstreak@30
|
1193 end
|
flickerstreak@30
|
1194 end
|
flickerstreak@30
|
1195
|
flickerstreak@30
|
1196 local function argCheck(value, position, ...)
|
flickerstreak@30
|
1197 if not currentMethod then
|
flickerstreak@30
|
1198 error("Cannot call `argCheck' outside of a pre/post-condition.", 2)
|
flickerstreak@30
|
1199 end
|
flickerstreak@30
|
1200 if type(position) ~= "number" then
|
flickerstreak@30
|
1201 error(("Bad argument #2 to `argCheck'. Expected %q, got %q"):format("number", type(position)), 2)
|
flickerstreak@30
|
1202 end
|
flickerstreak@30
|
1203 local type_value = type(value)
|
flickerstreak@30
|
1204 for i = 1, select('#', ...) do
|
flickerstreak@30
|
1205 local v = select(i, ...)
|
flickerstreak@30
|
1206 if type(v) ~= "string" then
|
flickerstreak@30
|
1207 error(("Bad argument #%d to `argCheck'. Expected %q, got %q"):format(i+1, "string", type(v)), 2)
|
flickerstreak@30
|
1208 end
|
flickerstreak@30
|
1209 if v == type_value then
|
flickerstreak@30
|
1210 return
|
flickerstreak@30
|
1211 end
|
flickerstreak@30
|
1212 end
|
flickerstreak@30
|
1213 local t = newList(...)
|
flickerstreak@30
|
1214 t[#t] = nil
|
flickerstreak@30
|
1215 for i,v in ipairs(t) do
|
flickerstreak@30
|
1216 t[i] = ("%q"):format(v)
|
flickerstreak@30
|
1217 end
|
flickerstreak@30
|
1218 local s
|
flickerstreak@30
|
1219 if #t == 0 then
|
flickerstreak@30
|
1220 s = ("%q"):format((...))
|
flickerstreak@30
|
1221 elseif #t == 1 then
|
flickerstreak@30
|
1222 s = ("%q or %q"):format(...)
|
flickerstreak@30
|
1223 else
|
flickerstreak@30
|
1224 s = table_concat(t, ", ") .. ", or " .. ("%q"):format(select(#t+1, ...))
|
flickerstreak@30
|
1225 end
|
flickerstreak@30
|
1226 t = del(t)
|
flickerstreak@30
|
1227
|
flickerstreak@30
|
1228 error(("Bad argument #%d to `%s'. Expected %s, got %q."):format(position, tostring(currentMethod), s, type_value), 4)
|
flickerstreak@30
|
1229 end
|
flickerstreak@30
|
1230
|
flickerstreak@30
|
1231 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1232 Notes:
|
flickerstreak@30
|
1233 * Returns functions for the specified namespace based on what is provided.
|
flickerstreak@30
|
1234 * function types:
|
flickerstreak@30
|
1235 ; "precondition" : to set the pre-condition for a method.
|
flickerstreak@30
|
1236 ; "postcondition" : to set the post-condition for a method.
|
flickerstreak@30
|
1237 ; "argCheck" : to check the type of an argument, to be executed within a pre-condition.
|
flickerstreak@30
|
1238 * preconditon is in the form of <tt>precondition(object, "methodName", func(self, ...))</tt>
|
flickerstreak@30
|
1239 * postcondition is in the form of either <tt>postcondition(object, "methodName", func(returnValues, self, ...))</tt> or <tt>postcondition(object, "methodName", func(oldValues, returnValues, self, ...), populateOld(oldValues, self, ...))</tt>
|
flickerstreak@30
|
1240 ** returnValues is the list of return values, empty if no return values were sent.
|
flickerstreak@30
|
1241 ** if the populateOld function is provided, then the empty oldValues table is provided and expected to be filled, and then given to the func.
|
flickerstreak@30
|
1242 * argCheck is in the form of <tt>argCheck(value, n, "type1" [, "type2", ...])</tt>
|
flickerstreak@30
|
1243 ** value is the value provided to the function you're checking.
|
flickerstreak@30
|
1244 ** n is the argument position. ''Note: 1 is the position of `self'. 2 would be the first "real" position.''
|
flickerstreak@30
|
1245 ** the tuple of types can be any string, but specifically "nil", "boolean", "string", "number", "function", "userdata", "table", etc.
|
flickerstreak@30
|
1246 Arguments:
|
flickerstreak@30
|
1247 string - the namespace. ''Note: this doesn't necessarily have to be a string.''
|
flickerstreak@30
|
1248 Example:
|
flickerstreak@30
|
1249 local precondition, postcondition, argCheck = Rock:GetRecyclingFunctions("Stack", "precondition", "postcondition", "argCheck")
|
flickerstreak@30
|
1250
|
flickerstreak@30
|
1251 local stack = {}
|
flickerstreak@30
|
1252 stack.IsEmpty = function(self)
|
flickerstreak@30
|
1253 return self[1] == nil
|
flickerstreak@30
|
1254 end
|
flickerstreak@30
|
1255 stack.GetLength = function(self)
|
flickerstreak@30
|
1256 return #self
|
flickerstreak@30
|
1257 end
|
flickerstreak@30
|
1258 stack.Push = function(self, value)
|
flickerstreak@30
|
1259 self[#self+1] = value
|
flickerstreak@30
|
1260 end
|
flickerstreak@30
|
1261 precondition(stack, "Push", function(self, value)
|
flickerstreak@30
|
1262 argCheck(value, 2, "string") -- only accept strings, no other values
|
flickerstreak@30
|
1263 end)
|
flickerstreak@30
|
1264 postcondition(stack, "Push", function(old, ret, self, value)
|
flickerstreak@30
|
1265 assert(self:GetLength() == old.length+1)
|
flickerstreak@30
|
1266 assert(not self:IsEmpty())
|
flickerstreak@30
|
1267 end, function(old, self)
|
flickerstreak@30
|
1268 old.length = self:GetLength()
|
flickerstreak@30
|
1269 end)
|
flickerstreak@30
|
1270 stack.Pop = function(self)
|
flickerstreak@30
|
1271 local value = self[#self]
|
flickerstreak@30
|
1272 self[#self] = nil
|
flickerstreak@30
|
1273 return value
|
flickerstreak@30
|
1274 end
|
flickerstreak@30
|
1275 precondition(stack, "Pop", function(self)
|
flickerstreak@30
|
1276 assert(self:GetLength() >= 1)
|
flickerstreak@30
|
1277 end)
|
flickerstreak@30
|
1278 postcondition(stack, "Pop", function(old, ret, self)
|
flickerstreak@30
|
1279 assert(self:GetLength() == old.length-1)
|
flickerstreak@30
|
1280 end, function(old, self)
|
flickerstreak@30
|
1281 old.length = self:GetLength()
|
flickerstreak@30
|
1282 end)
|
flickerstreak@30
|
1283 stack.Peek = function(self)
|
flickerstreak@30
|
1284 return self[#self]
|
flickerstreak@30
|
1285 end
|
flickerstreak@30
|
1286 precondition(stack, "Peek", function(self)
|
flickerstreak@30
|
1287 assert(self:GetLength() >= 1)
|
flickerstreak@30
|
1288 end)
|
flickerstreak@30
|
1289 postcondition(stack, "Peek", function(old, ret, self)
|
flickerstreak@30
|
1290 assert(self:GetLength() == old.length)
|
flickerstreak@30
|
1291 end, function(old, self)
|
flickerstreak@30
|
1292 old.length = self:GetLength()
|
flickerstreak@30
|
1293 end)
|
flickerstreak@30
|
1294
|
flickerstreak@30
|
1295 local t = setmetatable({}, {__index=stack})
|
flickerstreak@30
|
1296 t:Push("Alpha")
|
flickerstreak@30
|
1297 t:Push("Bravo")
|
flickerstreak@30
|
1298 t:Push(5) -- error, only strings
|
flickerstreak@30
|
1299 assert(t:Pop() == "Bravo")
|
flickerstreak@30
|
1300 assert(t:Pop() == "Alpha")
|
flickerstreak@30
|
1301 t:Pop() -- error, out of values
|
flickerstreak@30
|
1302 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1303 function Rock:GetContractFunctions(namespace, ...)
|
flickerstreak@30
|
1304 if namespace == "precondition" or namespace == "postcondition" or namespace == "argCheck" then
|
flickerstreak@30
|
1305 error(("Bad argument #2 to `GetContractFunctions'. Cannot be %q."):format(namespace), 2)
|
flickerstreak@30
|
1306 end
|
flickerstreak@30
|
1307 local t = newList()
|
flickerstreak@30
|
1308 if enableContracts then
|
flickerstreak@30
|
1309 for i = 1, select('#', ...) do
|
flickerstreak@30
|
1310 local v = select(i, ...)
|
flickerstreak@30
|
1311 if v == "precondition" then
|
flickerstreak@30
|
1312 t[i] = precondition
|
flickerstreak@30
|
1313 elseif v == "postcondition" then
|
flickerstreak@30
|
1314 t[i] = postcondition
|
flickerstreak@30
|
1315 elseif v == "argCheck" then
|
flickerstreak@30
|
1316 t[i] = argCheck
|
flickerstreak@30
|
1317 else
|
flickerstreak@30
|
1318 error(("Bad argument #%d to `GetContractFunctions'. Expected %q, %q, or %q, got %q."):format(i+2, "precondition", "postcondition", "argCheck", tostring(v)))
|
flickerstreak@30
|
1319 end
|
flickerstreak@30
|
1320 end
|
flickerstreak@30
|
1321 else
|
flickerstreak@30
|
1322 for i = 1, select('#', ...) do
|
flickerstreak@30
|
1323 t[i] = noop
|
flickerstreak@30
|
1324 end
|
flickerstreak@30
|
1325 end
|
flickerstreak@30
|
1326 return unpackListAndDel(t)
|
flickerstreak@30
|
1327 end
|
flickerstreak@30
|
1328 end
|
flickerstreak@30
|
1329
|
flickerstreak@30
|
1330 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1331 Notes:
|
flickerstreak@30
|
1332 * convert a revision string to a number
|
flickerstreak@30
|
1333 Arguments:
|
flickerstreak@30
|
1334 string - revision string
|
flickerstreak@30
|
1335 Returns:
|
flickerstreak@30
|
1336 string or number - the string given or the number retrieved from it.
|
flickerstreak@30
|
1337 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1338 local function coerceRevisionToNumber(version)
|
flickerstreak@30
|
1339 if type(version) == "string" then
|
flickerstreak@30
|
1340 return tonumber(version:match("(%-?%d+)")) or version
|
flickerstreak@30
|
1341 else
|
flickerstreak@30
|
1342 return version
|
flickerstreak@30
|
1343 end
|
flickerstreak@30
|
1344 end
|
flickerstreak@30
|
1345
|
flickerstreak@30
|
1346 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1347 Notes:
|
flickerstreak@30
|
1348 * try to enable the standalone library specified
|
flickerstreak@30
|
1349 Arguments:
|
flickerstreak@30
|
1350 string - name of the library.
|
flickerstreak@30
|
1351 Returns:
|
flickerstreak@30
|
1352 boolean - whether the library is properly enabled and loadable.
|
flickerstreak@30
|
1353 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1354 local function TryToEnable(addon)
|
flickerstreak@30
|
1355 local islod = IsAddOnLoadOnDemand(addon)
|
flickerstreak@30
|
1356 if islod then
|
flickerstreak@30
|
1357 local _, _, _, enabled = GetAddOnInfo(addon)
|
flickerstreak@30
|
1358 EnableAddOn(addon)
|
flickerstreak@30
|
1359 local _, _, _, _, loadable = GetAddOnInfo(addon)
|
flickerstreak@30
|
1360 if not loadable and not enabled then
|
flickerstreak@30
|
1361 DisableAddOn(addon)
|
flickerstreak@30
|
1362 end
|
flickerstreak@30
|
1363
|
flickerstreak@30
|
1364 return loadable
|
flickerstreak@30
|
1365 end
|
flickerstreak@30
|
1366 end
|
flickerstreak@30
|
1367
|
flickerstreak@30
|
1368 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1369 Notes:
|
flickerstreak@30
|
1370 * try to load the standalone library specified
|
flickerstreak@30
|
1371 Arguments:
|
flickerstreak@30
|
1372 string - name of the library.
|
flickerstreak@30
|
1373 Returns:
|
flickerstreak@30
|
1374 boolean - whether the library is loaded.
|
flickerstreak@30
|
1375 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1376 local function TryToLoadStandalone(major)
|
flickerstreak@30
|
1377 major = major:lower()
|
flickerstreak@30
|
1378 if scannedLibraries[major] then
|
flickerstreak@30
|
1379 return
|
flickerstreak@30
|
1380 end
|
flickerstreak@30
|
1381 scannedLibraries[major] = true
|
flickerstreak@30
|
1382 local name, _, _, enabled, loadable, state = GetAddOnInfo(major)
|
flickerstreak@30
|
1383 if state == "MISSING" or not IsAddOnLoadOnDemand(major) then
|
flickerstreak@30
|
1384 -- backwards compatibility for X-AceLibrary
|
flickerstreak@30
|
1385 local field = "X-AceLibrary-" .. major
|
flickerstreak@30
|
1386 local loaded
|
flickerstreak@30
|
1387 for i = 1, GetNumAddOns() do
|
flickerstreak@30
|
1388 if GetAddOnMetadata(i, field) then
|
flickerstreak@30
|
1389 name, _, _, enabled, loadable = GetAddOnInfo(i)
|
flickerstreak@30
|
1390
|
flickerstreak@30
|
1391 loadable = (enabled and loadable) or TryToEnable(name)
|
flickerstreak@30
|
1392 if loadable then
|
flickerstreak@30
|
1393 loaded = true
|
flickerstreak@30
|
1394 LoadAddOn(name)
|
flickerstreak@30
|
1395 end
|
flickerstreak@30
|
1396 end
|
flickerstreak@30
|
1397 end
|
flickerstreak@30
|
1398
|
flickerstreak@30
|
1399 return loaded
|
flickerstreak@30
|
1400 elseif (enabled and loadable) or TryToEnable(major) then
|
flickerstreak@30
|
1401 LoadAddOn(major)
|
flickerstreak@30
|
1402 return true
|
flickerstreak@30
|
1403 else
|
flickerstreak@30
|
1404 return false
|
flickerstreak@30
|
1405 end
|
flickerstreak@30
|
1406 end
|
flickerstreak@30
|
1407
|
flickerstreak@30
|
1408 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1409 Notes:
|
flickerstreak@30
|
1410 * Return the LibStub library, casing is unimportant.
|
flickerstreak@30
|
1411 Arguments:
|
flickerstreak@30
|
1412 string - name of the library.
|
flickerstreak@30
|
1413 Returns:
|
flickerstreak@30
|
1414 table or nil - library
|
flickerstreak@30
|
1415 number - minor version
|
flickerstreak@30
|
1416 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1417 local function GetLibStubLibrary(major)
|
flickerstreak@30
|
1418 local lib, minor = LibStub:GetLibrary(major, true)
|
flickerstreak@30
|
1419 if lib then
|
flickerstreak@30
|
1420 return lib, minor
|
flickerstreak@30
|
1421 end
|
flickerstreak@30
|
1422 major = major:lower()
|
flickerstreak@30
|
1423 for m, lib in LibStub:IterateLibraries() do
|
flickerstreak@30
|
1424 if m:lower() == major then
|
flickerstreak@30
|
1425 return LibStub:GetLibrary(m)
|
flickerstreak@30
|
1426 end
|
flickerstreak@30
|
1427 end
|
flickerstreak@30
|
1428 return nil, nil
|
flickerstreak@30
|
1429 end
|
flickerstreak@30
|
1430
|
flickerstreak@30
|
1431 local finishLibraryRegistration
|
flickerstreak@30
|
1432 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1433 Notes:
|
flickerstreak@30
|
1434 * create a new library if the version provided is not out of date.
|
flickerstreak@30
|
1435 Arguments:
|
flickerstreak@30
|
1436 string - name of the library.
|
flickerstreak@30
|
1437 number - version of the library.
|
flickerstreak@30
|
1438 Returns:
|
flickerstreak@30
|
1439 library, oldLibrary
|
flickerstreak@30
|
1440 * table or nil - the library with which to manipulate
|
flickerstreak@30
|
1441 * table or nil - the old version of the library to upgrade from
|
flickerstreak@30
|
1442 Example:
|
flickerstreak@30
|
1443 local LibMonkey, oldLib = Rock:NewLibrary("LibMonkey-1.0", 50)
|
flickerstreak@30
|
1444 if not LibMonkey then
|
flickerstreak@30
|
1445 -- opt out now, out of date
|
flickerstreak@30
|
1446 return
|
flickerstreak@30
|
1447 end
|
flickerstreak@30
|
1448 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1449 function Rock:NewLibrary(major, version)
|
flickerstreak@30
|
1450 if type(major) ~= "string" then
|
flickerstreak@30
|
1451 error(("Bad argument #2 to `NewLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
|
flickerstreak@30
|
1452 end
|
flickerstreak@30
|
1453 if not major:match("^Lib[A-Z][A-Za-z%d%-]*%-%d+%.%d+$") then
|
flickerstreak@30
|
1454 error(("Bad argument #2 to `NewLibrary'. Must match %q, got %q."):format("^Lib[A-Z][A-Za-z%d%-]*%-%d+%.%d+$", major), 2)
|
flickerstreak@30
|
1455 end
|
flickerstreak@30
|
1456 TryToLoadStandalone(major)
|
flickerstreak@30
|
1457 version = coerceRevisionToNumber(version)
|
flickerstreak@30
|
1458 if type(version) ~= "number" then
|
flickerstreak@30
|
1459 error(("Bad argument #3 to `NewLibrary'. Expected %q, got %q."):format("number", type(version)), 2)
|
flickerstreak@30
|
1460 end
|
flickerstreak@30
|
1461 local library, oldMinor = LibStub:GetLibrary(major, true)
|
flickerstreak@30
|
1462 if oldMinor and oldMinor >= version then
|
flickerstreak@30
|
1463 -- in case LibStub is acting funny
|
flickerstreak@30
|
1464 return nil, nil
|
flickerstreak@30
|
1465 end
|
flickerstreak@30
|
1466 local library, oldMinor = LibStub:NewLibrary(major, version)
|
flickerstreak@30
|
1467 if not library then
|
flickerstreak@30
|
1468 return nil, nil
|
flickerstreak@30
|
1469 end
|
flickerstreak@30
|
1470 local unitTests_major = unitTests[major]
|
flickerstreak@30
|
1471 if unitTests_major then
|
flickerstreak@30
|
1472 for k,v in pairs(unitTests_major) do
|
flickerstreak@30
|
1473 unitTests_major[k] = nil
|
flickerstreak@30
|
1474 end
|
flickerstreak@30
|
1475 end
|
flickerstreak@30
|
1476 for k, v in pairs(recycleData) do
|
flickerstreak@30
|
1477 v[major] = nil
|
flickerstreak@30
|
1478 end
|
flickerstreak@30
|
1479 local mixinToObject_library = mixinToObject[library]
|
flickerstreak@30
|
1480
|
flickerstreak@30
|
1481 local oldLib
|
flickerstreak@30
|
1482 if oldMinor then
|
flickerstreak@30
|
1483 -- previous version exists
|
flickerstreak@30
|
1484 local mixins = newList()
|
flickerstreak@30
|
1485 for mixin, objectSet in pairs(mixinToObject) do
|
flickerstreak@30
|
1486 if objectSet[library] then
|
flickerstreak@30
|
1487 mixins[mixin] = true
|
flickerstreak@30
|
1488 end
|
flickerstreak@30
|
1489 end
|
flickerstreak@30
|
1490 for mixin in pairs(mixins) do
|
flickerstreak@30
|
1491 mixin:Unembed(library)
|
flickerstreak@30
|
1492 end
|
flickerstreak@30
|
1493 mixins = del(mixins)
|
flickerstreak@30
|
1494 oldLib = newList()
|
flickerstreak@30
|
1495 for k, v in pairs(library) do
|
flickerstreak@30
|
1496 oldLib[k] = v
|
flickerstreak@30
|
1497 library[k] = nil
|
flickerstreak@30
|
1498 end
|
flickerstreak@30
|
1499 setmetatable(oldLib, getmetatable(library))
|
flickerstreak@30
|
1500 setmetatable(library, nil)
|
flickerstreak@30
|
1501 end
|
flickerstreak@30
|
1502 finishLibraryRegistration(major, version, library, figureCurrentAddon(2))
|
flickerstreak@30
|
1503
|
flickerstreak@30
|
1504 return library, oldLib
|
flickerstreak@30
|
1505 end
|
flickerstreak@30
|
1506 function finishLibraryRegistration(major, version, library, folder)
|
flickerstreak@30
|
1507 library.name = major
|
flickerstreak@30
|
1508
|
flickerstreak@30
|
1509 libraries[major] = library
|
flickerstreak@30
|
1510 pendingLibraries[library] = folder
|
flickerstreak@30
|
1511 local exportedMethods_library = exportedMethods[library]
|
flickerstreak@30
|
1512 if exportedMethods_library then
|
flickerstreak@30
|
1513 local mixinToObject_library = mixinToObject[library]
|
flickerstreak@30
|
1514 if mixinToObject_library then
|
flickerstreak@30
|
1515 for object in pairs(mixinToObject_library) do
|
flickerstreak@30
|
1516 for _,v in ipairs(exportedMethods_library) do
|
flickerstreak@30
|
1517 object[v] = nil
|
flickerstreak@30
|
1518 end
|
flickerstreak@30
|
1519 end
|
flickerstreak@30
|
1520 end
|
flickerstreak@30
|
1521 exportedMethods[library] = del(exportedMethods_library)
|
flickerstreak@30
|
1522 end
|
flickerstreak@30
|
1523 if library ~= Rock then
|
flickerstreak@30
|
1524 Rock:Embed(library)
|
flickerstreak@30
|
1525 end
|
flickerstreak@30
|
1526
|
flickerstreak@30
|
1527 frame:Show()
|
flickerstreak@30
|
1528 end
|
flickerstreak@30
|
1529 if not oldRock then
|
flickerstreak@30
|
1530 finishLibraryRegistration(MAJOR_VERSION, MINOR_VERSION, Rock, figureCurrentAddon(1))
|
flickerstreak@30
|
1531 end
|
flickerstreak@30
|
1532
|
flickerstreak@30
|
1533 -- #NODOC
|
flickerstreak@30
|
1534 local function __removeLibrary(libName)
|
flickerstreak@30
|
1535 libraries[libName] = nil
|
flickerstreak@30
|
1536 if LibStub.libs then
|
flickerstreak@30
|
1537 LibStub.libs[libName] = nil
|
flickerstreak@30
|
1538 end
|
flickerstreak@30
|
1539 if LibStub.minors then
|
flickerstreak@30
|
1540 LibStub.minors[libName] = nil
|
flickerstreak@30
|
1541 end
|
flickerstreak@30
|
1542 local lastCount
|
flickerstreak@30
|
1543 repeat
|
flickerstreak@30
|
1544 lastCount = collectgarbage('count')
|
flickerstreak@30
|
1545 collectgarbage('collect')
|
flickerstreak@30
|
1546 until lastCount == collectgarbage('count')
|
flickerstreak@30
|
1547 end
|
flickerstreak@30
|
1548 local function run(_,a)
|
flickerstreak@30
|
1549 if a < 1/30 then
|
flickerstreak@30
|
1550 collectgarbage('step')
|
flickerstreak@30
|
1551 end
|
flickerstreak@30
|
1552 end
|
flickerstreak@30
|
1553
|
flickerstreak@30
|
1554 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1555 Notes:
|
flickerstreak@30
|
1556 * properly finalizes the library, essentially stating that it has loaded properly.
|
flickerstreak@30
|
1557 * This will call :OnLibraryLoad("major", library) on every other library
|
flickerstreak@30
|
1558 * This will also call :OnLibraryLoad("major", library) on the library provided, using every other library as the arguments.
|
flickerstreak@30
|
1559 * An error will occur if this is not done before ADDON_LOADED.
|
flickerstreak@30
|
1560 Arguments:
|
flickerstreak@30
|
1561 string - name of the library.
|
flickerstreak@30
|
1562 Example:
|
flickerstreak@30
|
1563 local LibMonkey, oldLib = Rock:NewLibrary("LibMonkey-1.0", 50)
|
flickerstreak@30
|
1564 if not LibMonkey then
|
flickerstreak@30
|
1565 -- opt out now, out of date
|
flickerstreak@30
|
1566 return
|
flickerstreak@30
|
1567 end
|
flickerstreak@30
|
1568 Rock:FinalizeLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
1569 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1570 function Rock:FinalizeLibrary(major)
|
flickerstreak@30
|
1571 if type(major) ~= "string" then
|
flickerstreak@30
|
1572 error(("Bad argument #2 to `FinalizeLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
|
flickerstreak@30
|
1573 end
|
flickerstreak@30
|
1574 local library = libraries[major]
|
flickerstreak@30
|
1575 if not library then
|
flickerstreak@30
|
1576 error(("Bad argument #2 to `FinalizeLibrary'. %q is not a library."):format("string", major), 2)
|
flickerstreak@30
|
1577 end
|
flickerstreak@30
|
1578 pendingLibraries[library] = nil
|
flickerstreak@30
|
1579 local library_OnLibraryLoad = library.OnLibraryLoad
|
flickerstreak@30
|
1580 if library_OnLibraryLoad then
|
flickerstreak@30
|
1581 for maj, lib in LibStub:IterateLibraries() do -- for all libraries
|
flickerstreak@30
|
1582 if maj ~= major then
|
flickerstreak@30
|
1583 local success, ret = pcall(library_OnLibraryLoad, library, maj, lib)
|
flickerstreak@30
|
1584 if not success then
|
flickerstreak@30
|
1585 geterrorhandler()(ret)
|
flickerstreak@30
|
1586 break
|
flickerstreak@30
|
1587 end
|
flickerstreak@30
|
1588 end
|
flickerstreak@30
|
1589 end
|
flickerstreak@30
|
1590 end
|
flickerstreak@30
|
1591 if finalizedLibraries[library] then
|
flickerstreak@30
|
1592 return
|
flickerstreak@30
|
1593 end
|
flickerstreak@30
|
1594 finalizedLibraries[library] = true
|
flickerstreak@30
|
1595 for maj, lib in pairs(libraries) do -- just Rock libraries
|
flickerstreak@30
|
1596 if maj ~= major then
|
flickerstreak@30
|
1597 local lib_OnLibraryLoad = lib.OnLibraryLoad
|
flickerstreak@30
|
1598 if lib_OnLibraryLoad then
|
flickerstreak@30
|
1599 local success, ret = pcall(lib_OnLibraryLoad, lib, major, library)
|
flickerstreak@30
|
1600 if not success then
|
flickerstreak@30
|
1601 geterrorhandler()(ret)
|
flickerstreak@30
|
1602 end
|
flickerstreak@30
|
1603 end
|
flickerstreak@30
|
1604 end
|
flickerstreak@30
|
1605 end
|
flickerstreak@30
|
1606 if LibRockEvent then
|
flickerstreak@30
|
1607 self:DispatchEvent("LibraryLoad", major, library)
|
flickerstreak@30
|
1608 end
|
flickerstreak@30
|
1609 end
|
flickerstreak@30
|
1610
|
flickerstreak@30
|
1611 local function manualFinalize(major, library)
|
flickerstreak@30
|
1612 if libraries[major] then -- non-Rock libraries only
|
flickerstreak@30
|
1613 return
|
flickerstreak@30
|
1614 end
|
flickerstreak@30
|
1615 if finalizedLibraries[library] then -- don't do it twice
|
flickerstreak@30
|
1616 return
|
flickerstreak@30
|
1617 end
|
flickerstreak@30
|
1618 finalizedLibraries[library] = true
|
flickerstreak@30
|
1619 for maj, lib in pairs(libraries) do -- just Rock libraries
|
flickerstreak@30
|
1620 if maj ~= major then
|
flickerstreak@30
|
1621 local lib_OnLibraryLoad = lib.OnLibraryLoad
|
flickerstreak@30
|
1622 if lib_OnLibraryLoad then
|
flickerstreak@30
|
1623 local success, ret = pcall(lib_OnLibraryLoad, lib, major, library)
|
flickerstreak@30
|
1624 if not success then
|
flickerstreak@30
|
1625 geterrorhandler()(ret)
|
flickerstreak@30
|
1626 end
|
flickerstreak@30
|
1627 end
|
flickerstreak@30
|
1628 end
|
flickerstreak@30
|
1629 end
|
flickerstreak@30
|
1630 if LibRockEvent then
|
flickerstreak@30
|
1631 Rock:DispatchEvent("LibraryLoad", major, library)
|
flickerstreak@30
|
1632 end
|
flickerstreak@30
|
1633 end
|
flickerstreak@30
|
1634
|
flickerstreak@30
|
1635 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1636 Arguments:
|
flickerstreak@30
|
1637 string - name of the library.
|
flickerstreak@30
|
1638 [optional] boolean - whether to not load a library if it is not found. Default: false
|
flickerstreak@30
|
1639 [optional] boolean - whether to not error if a library is not found. Default: false
|
flickerstreak@30
|
1640 Returns:
|
flickerstreak@30
|
1641 library
|
flickerstreak@30
|
1642 * table or nil - the library requested
|
flickerstreak@30
|
1643 Example:
|
flickerstreak@30
|
1644 local LibMonkey = Rock:GetLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
1645 -- or
|
flickerstreak@30
|
1646 local LibMonkey = Rock("LibMonkey-1.0")
|
flickerstreak@30
|
1647 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1648 function Rock:GetLibrary(major, dontLoad, dontError)
|
flickerstreak@30
|
1649 if type(major) ~= "string" then
|
flickerstreak@30
|
1650 error(("Bad argument #2 to `GetLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
|
flickerstreak@30
|
1651 end
|
flickerstreak@30
|
1652 if dontLoad and dontLoad ~= true then
|
flickerstreak@30
|
1653 error(("Bad argument #3 to `GetLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontLoad)), 2)
|
flickerstreak@30
|
1654 end
|
flickerstreak@30
|
1655 if dontError and dontError ~= true then
|
flickerstreak@30
|
1656 error(("Bad argument #4 to `GetLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontError)), 2)
|
flickerstreak@30
|
1657 end
|
flickerstreak@30
|
1658 if not dontLoad then
|
flickerstreak@30
|
1659 TryToLoadStandalone(major)
|
flickerstreak@30
|
1660 end
|
flickerstreak@30
|
1661
|
flickerstreak@30
|
1662 local library = GetLibStubLibrary(major)
|
flickerstreak@30
|
1663 if not library then
|
flickerstreak@30
|
1664 if dontError then
|
flickerstreak@30
|
1665 return nil
|
flickerstreak@30
|
1666 end
|
flickerstreak@30
|
1667 error(("Library %q not found."):format(major), 2)
|
flickerstreak@30
|
1668 end
|
flickerstreak@30
|
1669
|
flickerstreak@30
|
1670 return library
|
flickerstreak@30
|
1671 end
|
flickerstreak@30
|
1672
|
flickerstreak@30
|
1673 setmetatable(Rock, { __call = Rock.GetLibrary })
|
flickerstreak@30
|
1674
|
flickerstreak@30
|
1675 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1676 Arguments:
|
flickerstreak@30
|
1677 string - name of the library.
|
flickerstreak@30
|
1678 Returns:
|
flickerstreak@30
|
1679 boolean - whether the library exists and is a proper mixin which can be embedded.
|
flickerstreak@30
|
1680 Example:
|
flickerstreak@30
|
1681 local isMixin = Rock:IsLibraryMixin("LibMonkey-1.0")
|
flickerstreak@30
|
1682 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1683 function Rock:IsLibraryMixin(name)
|
flickerstreak@30
|
1684 local library = self:GetLibrary(name, false, true)
|
flickerstreak@30
|
1685 if not library then
|
flickerstreak@30
|
1686 return false
|
flickerstreak@30
|
1687 end
|
flickerstreak@30
|
1688 return not not exportedMethods[library]
|
flickerstreak@30
|
1689 end
|
flickerstreak@30
|
1690
|
flickerstreak@30
|
1691 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1692 Arguments:
|
flickerstreak@30
|
1693 string - name of the library.
|
flickerstreak@30
|
1694 [optional] boolean - whether to not load a library if it is not found. Default: false
|
flickerstreak@30
|
1695 Returns:
|
flickerstreak@30
|
1696 library
|
flickerstreak@30
|
1697 * table or nil - the library requested
|
flickerstreak@30
|
1698 Example:
|
flickerstreak@30
|
1699 local hasLibMonkey = Rock:HasLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
1700 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1701 function Rock:HasLibrary(major, dontLoad)
|
flickerstreak@30
|
1702 if type(major) ~= "string" then
|
flickerstreak@30
|
1703 error(("Bad argument #2 to `HasLibrary'. Expected %q, got %q."):format("string", type(major)), 2)
|
flickerstreak@30
|
1704 end
|
flickerstreak@30
|
1705 if dontLoad and dontLoad ~= true then
|
flickerstreak@30
|
1706 error(("Bad argument #3 to `HasLibrary'. Expected %q or %q, got %q."):format("boolean", "nil", type(dontLoad)), 2)
|
flickerstreak@30
|
1707 end
|
flickerstreak@30
|
1708 if not dontLoad then
|
flickerstreak@30
|
1709 TryToLoadStandalone(major)
|
flickerstreak@30
|
1710 end
|
flickerstreak@30
|
1711 return not not GetLibStubLibrary(major)
|
flickerstreak@30
|
1712 end
|
flickerstreak@30
|
1713
|
flickerstreak@30
|
1714 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1715 Notes:
|
flickerstreak@30
|
1716 * This is exported to all libraries
|
flickerstreak@30
|
1717 Returns:
|
flickerstreak@30
|
1718 major, minor
|
flickerstreak@30
|
1719 * string - name of the library
|
flickerstreak@30
|
1720 * number - version of the library
|
flickerstreak@30
|
1721 Example:
|
flickerstreak@30
|
1722 local major, minor = Rock:GetLibraryVersion() -- will be "LibRock-1.0", 12345
|
flickerstreak@30
|
1723 local major, minor = LibMonkey:GetLibraryVersion() -- will be "LibMonkey-1.0", 50
|
flickerstreak@30
|
1724 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1725 function Rock:GetLibraryVersion()
|
flickerstreak@30
|
1726 if type(self) ~= "table" then
|
flickerstreak@30
|
1727 return nil, nil
|
flickerstreak@30
|
1728 end
|
flickerstreak@30
|
1729 local major
|
flickerstreak@30
|
1730 local name = self.name
|
flickerstreak@30
|
1731 if name and GetLibStubLibrary(name) == self then
|
flickerstreak@30
|
1732 major = name
|
flickerstreak@30
|
1733 else
|
flickerstreak@30
|
1734 for m, instance in LibStub:IterateLibraries() do
|
flickerstreak@30
|
1735 if instance == self then
|
flickerstreak@30
|
1736 major = m
|
flickerstreak@30
|
1737 break
|
flickerstreak@30
|
1738 end
|
flickerstreak@30
|
1739 end
|
flickerstreak@30
|
1740 if not major then
|
flickerstreak@30
|
1741 return nil, nil
|
flickerstreak@30
|
1742 end
|
flickerstreak@30
|
1743 end
|
flickerstreak@30
|
1744 local _, minor = GetLibStubLibrary(major)
|
flickerstreak@30
|
1745 return major, minor
|
flickerstreak@30
|
1746 end
|
flickerstreak@30
|
1747
|
flickerstreak@30
|
1748 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1749 Returns:
|
flickerstreak@30
|
1750 an iterator to traverse all registered libraries.
|
flickerstreak@30
|
1751 Example:
|
flickerstreak@30
|
1752 for major, library in Rock:IterateLibraries() do
|
flickerstreak@30
|
1753 -- do something with major and library
|
flickerstreak@30
|
1754 end
|
flickerstreak@30
|
1755 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1756 function Rock:IterateLibraries()
|
flickerstreak@30
|
1757 return LibStub:IterateLibraries()
|
flickerstreak@30
|
1758 end
|
flickerstreak@30
|
1759
|
flickerstreak@30
|
1760 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1761 Notes:
|
flickerstreak@30
|
1762 * This is exported to all libraries
|
flickerstreak@30
|
1763 * Allows you to set precisely what methods for the library to export.
|
flickerstreak@30
|
1764 * This automatically turns a library into a mixin.
|
flickerstreak@30
|
1765 Arguments:
|
flickerstreak@30
|
1766 tuple - the list of method names to export.
|
flickerstreak@30
|
1767 Example:
|
flickerstreak@30
|
1768 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
|
flickerstreak@30
|
1769 LibMonkey.FlingPoo = function(self)
|
flickerstreak@30
|
1770 return "Splat!"
|
flickerstreak@30
|
1771 end
|
flickerstreak@30
|
1772 LibMonkey:SetExportedMethods("FlingPoo")
|
flickerstreak@30
|
1773 -- later
|
flickerstreak@30
|
1774 local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
|
flickerstreak@30
|
1775 assert(Darwin:FlingPoo() == "Splat!")
|
flickerstreak@30
|
1776 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1777 function Rock:SetExportedMethods(...)
|
flickerstreak@30
|
1778 if exportedMethods[self] then
|
flickerstreak@30
|
1779 error("Cannot call `SetExportedMethods' more than once.", 2)
|
flickerstreak@30
|
1780 end
|
flickerstreak@30
|
1781 local t = newList(...)
|
flickerstreak@30
|
1782 if #t == 0 then
|
flickerstreak@30
|
1783 error("Must supply at least 1 method to `SetExportedMethods'.", 2)
|
flickerstreak@30
|
1784 end
|
flickerstreak@30
|
1785 for i,v in ipairs(t) do
|
flickerstreak@30
|
1786 if type(self[v]) ~= "function" then
|
flickerstreak@30
|
1787 error(("Bad argument #%d to `SetExportedMethods'. Method %q does not exist."):format(i+1, tostring(v)), 2)
|
flickerstreak@30
|
1788 end
|
flickerstreak@30
|
1789 end
|
flickerstreak@30
|
1790 exportedMethods[self] = t
|
flickerstreak@30
|
1791
|
flickerstreak@30
|
1792 local mixinToObject_library = mixinToObject[self]
|
flickerstreak@30
|
1793 if mixinToObject_library then
|
flickerstreak@30
|
1794 for object in pairs(mixinToObject_library) do
|
flickerstreak@30
|
1795 for _,method in ipairs(t) do
|
flickerstreak@30
|
1796 object[method] = self[method]
|
flickerstreak@30
|
1797 end
|
flickerstreak@30
|
1798 end
|
flickerstreak@30
|
1799 end
|
flickerstreak@30
|
1800 end
|
flickerstreak@30
|
1801
|
flickerstreak@30
|
1802 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1803 Notes:
|
flickerstreak@30
|
1804 * This is exported to all libraries
|
flickerstreak@30
|
1805 * Embeds all the methods previously set to export onto a table.
|
flickerstreak@30
|
1806 * This will call :OnEmbed(object) on the library if it is available.
|
flickerstreak@30
|
1807 Arguments:
|
flickerstreak@30
|
1808 table - the table with which to export methods onto.
|
flickerstreak@30
|
1809 Returns:
|
flickerstreak@30
|
1810 The table provided, after embedding.
|
flickerstreak@30
|
1811 Example:
|
flickerstreak@30
|
1812 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
|
flickerstreak@30
|
1813 LibMonkey.FlingPoo = function(self)
|
flickerstreak@30
|
1814 return "Splat!"
|
flickerstreak@30
|
1815 end
|
flickerstreak@30
|
1816 LibMonkey:SetExportedMethods("FlingPoo")
|
flickerstreak@30
|
1817 -- later
|
flickerstreak@30
|
1818 local Darwin = {}
|
flickerstreak@30
|
1819 Rock("LibMonkey-1.0"):Embed(Darwin)
|
flickerstreak@30
|
1820 assert(Darwin:FlingPoo() == "Splat!")
|
flickerstreak@30
|
1821 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1822 function Rock:Embed(object)
|
flickerstreak@30
|
1823 if not exportedMethods[self] then
|
flickerstreak@30
|
1824 error(("Cannot call `Embed' for library %q if `SetExportedMethods' has not been called."):format(tostring(self.name)), 2)
|
flickerstreak@30
|
1825 end
|
flickerstreak@30
|
1826 if type(object) ~= "table" then
|
flickerstreak@30
|
1827 error(("Bad argument #2 to `Embed'. Expected %q, got %q."):format("table", type(object)), 2)
|
flickerstreak@30
|
1828 end
|
flickerstreak@30
|
1829
|
flickerstreak@30
|
1830 for i,v in ipairs(exportedMethods[self]) do
|
flickerstreak@30
|
1831 if type(self[v]) ~= "function" then
|
flickerstreak@30
|
1832 error(("Problem embedding method %q from library %q. Expected %q, got %q."):format(tostring(v), better_tostring(self), "function", type(self[v])))
|
flickerstreak@30
|
1833 end
|
flickerstreak@30
|
1834 object[v] = self[v]
|
flickerstreak@30
|
1835 end
|
flickerstreak@30
|
1836
|
flickerstreak@30
|
1837 if not mixinToObject[self] then
|
flickerstreak@30
|
1838 -- weak because objects come and go
|
flickerstreak@30
|
1839 mixinToObject[self] = setmetatable(newList(), weakKey)
|
flickerstreak@30
|
1840 end
|
flickerstreak@30
|
1841 if mixinToObject[self][object] then
|
flickerstreak@30
|
1842 error(("Cannot embed library %q into the same object %q more than once."):format(better_tostring(self), better_tostring(object)), 2)
|
flickerstreak@30
|
1843 end
|
flickerstreak@30
|
1844 mixinToObject[self][object] = true
|
flickerstreak@30
|
1845 if type(rawget(object, 'mixins')) == "table" then
|
flickerstreak@30
|
1846 object.mixins[self] = true
|
flickerstreak@30
|
1847 end
|
flickerstreak@30
|
1848
|
flickerstreak@30
|
1849 local self_OnEmbed = self.OnEmbed
|
flickerstreak@30
|
1850 if self_OnEmbed then
|
flickerstreak@30
|
1851 local success, ret = pcall(self_OnEmbed, self, object)
|
flickerstreak@30
|
1852 if not success then
|
flickerstreak@30
|
1853 geterrorhandler()(ret)
|
flickerstreak@30
|
1854 end
|
flickerstreak@30
|
1855 end
|
flickerstreak@30
|
1856
|
flickerstreak@30
|
1857 return object
|
flickerstreak@30
|
1858 end
|
flickerstreak@30
|
1859
|
flickerstreak@30
|
1860 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1861 Notes:
|
flickerstreak@30
|
1862 * This is exported to all libraries
|
flickerstreak@30
|
1863 * Unembeds all the methods previously set to export onto a table.
|
flickerstreak@30
|
1864 * This will error if the library is not embedded on the object
|
flickerstreak@30
|
1865 * This will call :OnUnembed(object) on the library if it is available.
|
flickerstreak@30
|
1866 Arguments:
|
flickerstreak@30
|
1867 table - the table with which to export methods onto.
|
flickerstreak@30
|
1868 Returns:
|
flickerstreak@30
|
1869 The table provided, after embedding.
|
flickerstreak@30
|
1870 Example:
|
flickerstreak@30
|
1871 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0", 50)
|
flickerstreak@30
|
1872 LibMonkey.FlingPoo = function(self)
|
flickerstreak@30
|
1873 return "Splat!"
|
flickerstreak@30
|
1874 end
|
flickerstreak@30
|
1875 LibMonkey:SetExportedMethods("FlingPoo")
|
flickerstreak@30
|
1876 -- later
|
flickerstreak@30
|
1877 local Darwin = {}
|
flickerstreak@30
|
1878 Rock("LibMonkey-1.0"):Embed(Darwin)
|
flickerstreak@30
|
1879 assert(Darwin:FlingPoo() == "Splat!")
|
flickerstreak@30
|
1880 Rock("LibMonkey-1.0"):Unembed(Darwin)
|
flickerstreak@30
|
1881 assert(Darwin.FlingPoo == nil)
|
flickerstreak@30
|
1882 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1883 function Rock:Unembed(object)
|
flickerstreak@30
|
1884 if not exportedMethods[self] then
|
flickerstreak@30
|
1885 error(("Cannot call `Unembed' for library %q if `SetExportedMethods' has not been called."):format(better_tostring(self)), 2)
|
flickerstreak@30
|
1886 end
|
flickerstreak@30
|
1887
|
flickerstreak@30
|
1888 if not mixinToObject[self] or not mixinToObject[self][object] then
|
flickerstreak@30
|
1889 error(("Cannot unembed library %q from object %q, since it is not embedded originally."):format(better_tostring(self), better_tostring(object)), 2)
|
flickerstreak@30
|
1890 end
|
flickerstreak@30
|
1891 local mixinToObject_self = mixinToObject[self]
|
flickerstreak@30
|
1892 mixinToObject_self[object] = nil
|
flickerstreak@30
|
1893 if not next(mixinToObject_self) then
|
flickerstreak@30
|
1894 mixinToObject[self] = del(mixinToObject_self)
|
flickerstreak@30
|
1895 end
|
flickerstreak@30
|
1896
|
flickerstreak@30
|
1897 local mixin_OnUnembed = self.OnUnembed
|
flickerstreak@30
|
1898 if mixin_OnUnembed then
|
flickerstreak@30
|
1899 local success, ret = pcall(mixin_OnUnembed, self, object)
|
flickerstreak@30
|
1900 if not success then
|
flickerstreak@30
|
1901 geterrorhandler()(ret)
|
flickerstreak@30
|
1902 end
|
flickerstreak@30
|
1903 end
|
flickerstreak@30
|
1904
|
flickerstreak@30
|
1905 for i,v in ipairs(exportedMethods[self]) do
|
flickerstreak@30
|
1906 object[v] = nil
|
flickerstreak@30
|
1907 end
|
flickerstreak@30
|
1908 end
|
flickerstreak@30
|
1909
|
flickerstreak@30
|
1910 local function embedAce2Mixin(mixin, object)
|
flickerstreak@30
|
1911 if not mixinToObject[mixin] then
|
flickerstreak@30
|
1912 mixinToObject[mixin] = setmetatable(newList(), weakKey)
|
flickerstreak@30
|
1913 end
|
flickerstreak@30
|
1914 mixinToObject[mixin][object] = true
|
flickerstreak@30
|
1915 mixin:embed(object)
|
flickerstreak@30
|
1916 end
|
flickerstreak@30
|
1917
|
flickerstreak@30
|
1918 local function embedLibStubMixin(mixin, object)
|
flickerstreak@30
|
1919 if not mixinToObject[mixin] then
|
flickerstreak@30
|
1920 mixinToObject[mixin] = setmetatable(newList(), weakKey)
|
flickerstreak@30
|
1921 end
|
flickerstreak@30
|
1922 mixinToObject[mixin][object] = true
|
flickerstreak@30
|
1923 mixin:Embed(object)
|
flickerstreak@30
|
1924 end
|
flickerstreak@30
|
1925
|
flickerstreak@30
|
1926 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
1927 Notes:
|
flickerstreak@30
|
1928 * create a new addon with the specified name.
|
flickerstreak@30
|
1929 Arguments:
|
flickerstreak@30
|
1930 string - name of the addon.
|
flickerstreak@30
|
1931 tuple - list of mixins with which to embed into this addon.
|
flickerstreak@30
|
1932 Returns:
|
flickerstreak@30
|
1933 addon
|
flickerstreak@30
|
1934 * table - the addon with which to manipulate
|
flickerstreak@30
|
1935 Example:
|
flickerstreak@30
|
1936 local MyAddon = Rock:NewAddon("MyAddon", "Mixin-1.0", "OtherMixin-2.0")
|
flickerstreak@30
|
1937 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
1938 function Rock:NewAddon(name, ...)
|
flickerstreak@30
|
1939 if type(name) ~= "string" then
|
flickerstreak@30
|
1940 error(("Bad argument #2 to `NewAddon'. Expected %q, got %q"):format("string", type(name)), 2)
|
flickerstreak@30
|
1941 end
|
flickerstreak@30
|
1942 if name:match("^Lib[A-Z]") then
|
flickerstreak@30
|
1943 error(("Bad argument #2 to `NewAddon'. Cannot start with %q, got %q."):format("Lib", name), 2)
|
flickerstreak@30
|
1944 end
|
flickerstreak@30
|
1945 if self == Rock and name:match("_") then
|
flickerstreak@30
|
1946 error(("Bad argument #2 to `NewAddon'. Cannot contain underscores, got %q."):format(name), 2)
|
flickerstreak@30
|
1947 end
|
flickerstreak@30
|
1948
|
flickerstreak@30
|
1949 if addons[name] then
|
flickerstreak@30
|
1950 error(("Bad argument #2 to `NewAddon'. Addon %q already created."):format(name), 2)
|
flickerstreak@30
|
1951 end
|
flickerstreak@30
|
1952 local addon = setmetatable(newList(), addon_mt)
|
flickerstreak@30
|
1953 addon.name = name
|
flickerstreak@30
|
1954
|
flickerstreak@30
|
1955 local mixinSet = newList()
|
flickerstreak@30
|
1956
|
flickerstreak@30
|
1957 for i = 1, select('#', ...) do
|
flickerstreak@30
|
1958 local libName = select(i, ...)
|
flickerstreak@30
|
1959 if mixinSet[libName] then
|
flickerstreak@30
|
1960 error(("Bad argument #%d to `NewAddon'. %q already stated."):format(i+2, tostring(libName)), 2)
|
flickerstreak@30
|
1961 end
|
flickerstreak@30
|
1962 mixinSet[libName] = true
|
flickerstreak@30
|
1963 TryToLoadStandalone(libName)
|
flickerstreak@30
|
1964 local library = Rock:GetLibrary(libName, false, true)
|
flickerstreak@30
|
1965 if not library then
|
flickerstreak@30
|
1966 error(("Bad argument #%d to `NewAddon'. Library %q is not found."):format(i+2, tostring(libName)), 2)
|
flickerstreak@30
|
1967 end
|
flickerstreak@30
|
1968
|
flickerstreak@30
|
1969 local style = 'rock'
|
flickerstreak@30
|
1970
|
flickerstreak@30
|
1971 if not exportedMethods[library] then
|
flickerstreak@30
|
1972 local good = false
|
flickerstreak@30
|
1973 if AceLibrary then
|
flickerstreak@30
|
1974 local AceOO = AceLibrary:HasInstance("AceOO-2.0", false) and AceLibrary("AceOO-2.0")
|
flickerstreak@30
|
1975 if AceOO.inherits(library, AceOO.Mixin) then
|
flickerstreak@30
|
1976 good = true
|
flickerstreak@30
|
1977 style = 'ace2'
|
flickerstreak@30
|
1978 end
|
flickerstreak@30
|
1979 end
|
flickerstreak@30
|
1980 if not good and type(rawget(library, 'Embed')) == "function" then
|
flickerstreak@30
|
1981 good = true
|
flickerstreak@30
|
1982 style = 'libstub'
|
flickerstreak@30
|
1983 end
|
flickerstreak@30
|
1984 if not good then
|
flickerstreak@30
|
1985 error(("Bad argument #%d to `NewAddon'. Library %q is not a mixin."):format(i+2, tostring(libName)), 2)
|
flickerstreak@30
|
1986 end
|
flickerstreak@30
|
1987 end
|
flickerstreak@30
|
1988
|
flickerstreak@30
|
1989 if library == Rock then
|
flickerstreak@30
|
1990 error(("Bad argument #%d to `NewAddon'. Cannot use %q as a mixin."):format(i+2, tostring(libName)), 2)
|
flickerstreak@30
|
1991 end
|
flickerstreak@30
|
1992
|
flickerstreak@30
|
1993 if style == 'rock' then
|
flickerstreak@30
|
1994 library:Embed(addon)
|
flickerstreak@30
|
1995 elseif style == 'ace2' then
|
flickerstreak@30
|
1996 embedAce2Mixin(library, addon)
|
flickerstreak@30
|
1997 elseif style == 'libstub' then
|
flickerstreak@30
|
1998 embedLibStubMixin(library, addon)
|
flickerstreak@30
|
1999 end
|
flickerstreak@30
|
2000 end
|
flickerstreak@30
|
2001
|
flickerstreak@30
|
2002 mixinSet = del(mixinSet)
|
flickerstreak@30
|
2003
|
flickerstreak@30
|
2004 addons[name] = addon
|
flickerstreak@30
|
2005 pendingAddons[#pendingAddons+1] = addon
|
flickerstreak@30
|
2006 pendingAddonsEnable[#pendingAddonsEnable+1] = addon
|
flickerstreak@30
|
2007 addonToFolder[addon] = figureCurrentAddon(self == Rock and 2 or 4)
|
flickerstreak@30
|
2008
|
flickerstreak@30
|
2009 frame:Show()
|
flickerstreak@30
|
2010
|
flickerstreak@30
|
2011 return addon
|
flickerstreak@30
|
2012 end
|
flickerstreak@30
|
2013
|
flickerstreak@30
|
2014 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2015 Arguments:
|
flickerstreak@30
|
2016 string - name of the addon.
|
flickerstreak@30
|
2017 Returns:
|
flickerstreak@30
|
2018 addon
|
flickerstreak@30
|
2019 * table or nil - the addon requested
|
flickerstreak@30
|
2020 Example:
|
flickerstreak@30
|
2021 local MyAddon = Rock:GetAddon("MyAddon")
|
flickerstreak@30
|
2022 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2023 function Rock:GetAddon(name)
|
flickerstreak@30
|
2024 if type(name) ~= "string" then
|
flickerstreak@30
|
2025 return nil
|
flickerstreak@30
|
2026 end
|
flickerstreak@30
|
2027 local addon = addons[name]
|
flickerstreak@30
|
2028 if addon then
|
flickerstreak@30
|
2029 return addon
|
flickerstreak@30
|
2030 end
|
flickerstreak@30
|
2031 name = name:lower()
|
flickerstreak@30
|
2032 for k, v in pairs(addons) do
|
flickerstreak@30
|
2033 if k:lower() == name then
|
flickerstreak@30
|
2034 return v
|
flickerstreak@30
|
2035 end
|
flickerstreak@30
|
2036 end
|
flickerstreak@30
|
2037 return nil
|
flickerstreak@30
|
2038 end
|
flickerstreak@30
|
2039
|
flickerstreak@30
|
2040 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2041 Arguments:
|
flickerstreak@30
|
2042 string or table - name of the addon or the addon itself.
|
flickerstreak@30
|
2043 Returns:
|
flickerstreak@30
|
2044 boolean - whether the addon requested exists.
|
flickerstreak@30
|
2045 Example:
|
flickerstreak@30
|
2046 local hasMyAddon = Rock:HasAddon("MyAddon")
|
flickerstreak@30
|
2047 -- or
|
flickerstreak@30
|
2048 local hasMyAddon = Rock:HasAddon(MyAddon)
|
flickerstreak@30
|
2049 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2050 function Rock:HasAddon(name)
|
flickerstreak@30
|
2051 if type(name) == "string" then
|
flickerstreak@30
|
2052 local addon = addons[name]
|
flickerstreak@30
|
2053 if addon then
|
flickerstreak@30
|
2054 return true
|
flickerstreak@30
|
2055 end
|
flickerstreak@30
|
2056 name = name:lower()
|
flickerstreak@30
|
2057 for k, v in pairs(addons) do
|
flickerstreak@30
|
2058 if k:lower() == name then
|
flickerstreak@30
|
2059 return true
|
flickerstreak@30
|
2060 end
|
flickerstreak@30
|
2061 end
|
flickerstreak@30
|
2062 elseif type(name) == "table" then
|
flickerstreak@30
|
2063 for k,v in pairs(addons) do
|
flickerstreak@30
|
2064 if v == name then
|
flickerstreak@30
|
2065 return true
|
flickerstreak@30
|
2066 end
|
flickerstreak@30
|
2067 end
|
flickerstreak@30
|
2068 end
|
flickerstreak@30
|
2069 return false
|
flickerstreak@30
|
2070 end
|
flickerstreak@30
|
2071
|
flickerstreak@30
|
2072 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2073 Returns:
|
flickerstreak@30
|
2074 an iterator to traverse all addons created with Rock.
|
flickerstreak@30
|
2075 Example:
|
flickerstreak@30
|
2076 for name, addon in Rock:IterateAddons() do
|
flickerstreak@30
|
2077 -- do something with name and addon
|
flickerstreak@30
|
2078 end
|
flickerstreak@30
|
2079 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2080 function Rock:IterateAddons()
|
flickerstreak@30
|
2081 return pairs(addons)
|
flickerstreak@30
|
2082 end
|
flickerstreak@30
|
2083
|
flickerstreak@30
|
2084 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2085 Arguments:
|
flickerstreak@30
|
2086 string - major version of the mixin library
|
flickerstreak@30
|
2087 Returns:
|
flickerstreak@30
|
2088 an iterator to traverse all objects that the given mixin has embedded into
|
flickerstreak@30
|
2089 Example:
|
flickerstreak@30
|
2090 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
2091 local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
|
flickerstreak@30
|
2092 for object in LibMonkey:IterateMixinObjects("LibMonkey-1.0") do
|
flickerstreak@30
|
2093 assert(object == Darwin)
|
flickerstreak@30
|
2094 end
|
flickerstreak@30
|
2095 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2096 function Rock:IterateMixinObjects(mixinName)
|
flickerstreak@30
|
2097 local mixin
|
flickerstreak@30
|
2098 if type(mixinName) == "table" then
|
flickerstreak@30
|
2099 mixin = mixinName
|
flickerstreak@30
|
2100 else
|
flickerstreak@30
|
2101 if type(mixinName) ~= "string" then
|
flickerstreak@30
|
2102 error(("Bad argument #2 to `IterateMixinObjects'. Expected %q or %q, got %q."):format("table", "string", type(mixinName)), 2)
|
flickerstreak@30
|
2103 end
|
flickerstreak@30
|
2104 mixin = libraries[mixinName]
|
flickerstreak@30
|
2105 end
|
flickerstreak@30
|
2106 local mixinToObject_mixin = mixinToObject[mixin]
|
flickerstreak@30
|
2107 if not mixinToObject_mixin then
|
flickerstreak@30
|
2108 return noop
|
flickerstreak@30
|
2109 end
|
flickerstreak@30
|
2110 return pairs(mixinToObject_mixin)
|
flickerstreak@30
|
2111 end
|
flickerstreak@30
|
2112
|
flickerstreak@30
|
2113 local function iter(object, mixin)
|
flickerstreak@30
|
2114 mixin = next(mixinToObject, mixin)
|
flickerstreak@30
|
2115 if not mixin then
|
flickerstreak@30
|
2116 return nil
|
flickerstreak@30
|
2117 elseif mixinToObject[mixin][object] then
|
flickerstreak@30
|
2118 return mixin
|
flickerstreak@30
|
2119 end
|
flickerstreak@30
|
2120 return iter(object, mixin) -- try next mixin
|
flickerstreak@30
|
2121 end
|
flickerstreak@30
|
2122 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2123 Returns:
|
flickerstreak@30
|
2124 an iterator to traverse all mixins that an object has embedded
|
flickerstreak@30
|
2125 Example:
|
flickerstreak@30
|
2126 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
2127 local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
|
flickerstreak@30
|
2128 for mixin in Rock:IterateObjectMixins(Darwin) do
|
flickerstreak@30
|
2129 assert(mixin == LibMonkey)
|
flickerstreak@30
|
2130 end
|
flickerstreak@30
|
2131 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2132 function Rock:IterateObjectMixins(object)
|
flickerstreak@30
|
2133 if type(object) ~= "table" then
|
flickerstreak@30
|
2134 error(("Bad argument #2 to `IterateObjectMixins'. Expected %q, got %q."):format("table", type(object)), 2)
|
flickerstreak@30
|
2135 end
|
flickerstreak@30
|
2136 return iter, object, nil
|
flickerstreak@30
|
2137 end
|
flickerstreak@30
|
2138
|
flickerstreak@30
|
2139 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2140 Arguments:
|
flickerstreak@30
|
2141 table - the object to check
|
flickerstreak@30
|
2142 string - the mixin to check
|
flickerstreak@30
|
2143 Returns:
|
flickerstreak@30
|
2144 boolean - whether the object has the given mixin embedded into it.
|
flickerstreak@30
|
2145 Example:
|
flickerstreak@30
|
2146 local LibMonkey = Rock:NewLibrary("LibMonkey-1.0")
|
flickerstreak@30
|
2147 local Darwin = Rock:NewAddon("Darwin", "LibMonkey-1.0")
|
flickerstreak@30
|
2148 assert(Rock:DoesObjectUseMixin(Darwin, "LibMonkey-1.0"))
|
flickerstreak@30
|
2149 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2150 function Rock:DoesObjectUseMixin(object, mixinName)
|
flickerstreak@30
|
2151 if type(object) ~= "table" then
|
flickerstreak@30
|
2152 error(("Bad argument #2 to `IterateObjectMixins'. Expected %q, got %q."):format("table", type(object)), 2)
|
flickerstreak@30
|
2153 end
|
flickerstreak@30
|
2154 local mixin
|
flickerstreak@30
|
2155 if type(mixinName) == "table" then
|
flickerstreak@30
|
2156 mixin = mixinName
|
flickerstreak@30
|
2157 else
|
flickerstreak@30
|
2158 if type(mixinName) ~= "string" then
|
flickerstreak@30
|
2159 error(("Bad argument #3 to `IterateMiDoesObjectUseMixininObjects'. Expected %q or %q, got %q."):format("table", "string", type(mixinName)), 2)
|
flickerstreak@30
|
2160 end
|
flickerstreak@30
|
2161 mixin = libraries[mixinName]
|
flickerstreak@30
|
2162 end
|
flickerstreak@30
|
2163 if not mixin then
|
flickerstreak@30
|
2164 return false
|
flickerstreak@30
|
2165 end
|
flickerstreak@30
|
2166
|
flickerstreak@30
|
2167 local mixinToObject_mixin = mixinToObject[mixin]
|
flickerstreak@30
|
2168 if not mixinToObject_mixin then
|
flickerstreak@30
|
2169 return false
|
flickerstreak@30
|
2170 end
|
flickerstreak@30
|
2171 return not not mixinToObject_mixin[object]
|
flickerstreak@30
|
2172 end
|
flickerstreak@30
|
2173
|
flickerstreak@30
|
2174 Rock.UID_NUM = oldRock and oldRock.UID_NUM or 0
|
flickerstreak@30
|
2175 --[[---------------------------------------------------------------------------
|
flickerstreak@30
|
2176 Notes:
|
flickerstreak@30
|
2177 * This UID is not unique across sessions. If you save a UID in a saved variable, the same UID can be generated in another session.
|
flickerstreak@30
|
2178 Returns:
|
flickerstreak@30
|
2179 number - a unique number.
|
flickerstreak@30
|
2180 Example:
|
flickerstreak@30
|
2181 local UID = Rock:GetUID()
|
flickerstreak@30
|
2182 -----------------------------------------------------------------------------]]
|
flickerstreak@30
|
2183 function Rock:GetUID()
|
flickerstreak@30
|
2184 local num = Rock.UID_NUM + 1
|
flickerstreak@30
|
2185 Rock.UID_NUM = num
|
flickerstreak@30
|
2186 return num
|
flickerstreak@30
|
2187 end
|
flickerstreak@30
|
2188
|
flickerstreak@30
|
2189 local function unobfuscateEmail(email)
|
flickerstreak@30
|
2190 return email:gsub(" AT ", "@"):gsub(" DOT ", ".")
|
flickerstreak@30
|
2191 end
|
flickerstreak@30
|
2192 local function fix(char)
|
flickerstreak@30
|
2193 return ("%%%02x"):format(char:byte())
|
flickerstreak@30
|
2194 end
|
flickerstreak@30
|
2195 local function urlencode(text)
|
flickerstreak@30
|
2196 return text:gsub("[^0-9A-Za-z]", fix)
|
flickerstreak@30
|
2197 end
|
flickerstreak@30
|
2198
|
flickerstreak@30
|
2199 local url
|
flickerstreak@30
|
2200 local function makeURLFrame()
|
flickerstreak@30
|
2201 makeURLFrame = nil
|
flickerstreak@30
|
2202 local function bumpFrameLevels(frame, amount)
|
flickerstreak@30
|
2203 frame:SetFrameLevel(frame:GetFrameLevel()+amount)
|
flickerstreak@30
|
2204 local children = newList(frame:GetChildren())
|
flickerstreak@30
|
2205 for _,v in ipairs(children) do
|
flickerstreak@30
|
2206 bumpFrameLevels(v, amount)
|
flickerstreak@30
|
2207 end
|
flickerstreak@30
|
2208 children = del(children)
|
flickerstreak@30
|
2209 end
|
flickerstreak@30
|
2210 -- some code borrowed from Prat here
|
flickerstreak@30
|
2211 StaticPopupDialogs["ROCK_SHOW_URL"] = {
|
flickerstreak@30
|
2212 text = not IsMacClient() and L["Press Ctrl-C to copy, then Alt-Tab out of the game, open your favorite web browser, and paste the link into the address bar."] or L["Press Cmd-C to copy, then Cmd-Tab out of the game, open your favorite web browser, and paste the link into the address bar."],
|
flickerstreak@30
|
2213 button2 = ACCEPT,
|
flickerstreak@30
|
2214 hasEditBox = 1,
|
flickerstreak@30
|
2215 hasWideEditBox = 1,
|
flickerstreak@30
|
2216 showAlert = 1, -- HACK : it's the only way I found to make de StaticPopup have sufficient width to show WideEditBox :(
|
flickerstreak@30
|
2217
|
flickerstreak@30
|
2218 OnShow = function()
|
flickerstreak@30
|
2219 local editBox = _G[this:GetName() .. "WideEditBox"]
|
flickerstreak@30
|
2220 editBox:SetText(url)
|
flickerstreak@30
|
2221 editBox:SetFocus()
|
flickerstreak@30
|
2222 editBox:HighlightText(0)
|
flickerstreak@30
|
2223 editBox:SetScript("OnTextChanged", function() StaticPopup_EditBoxOnTextChanged() end)
|
flickerstreak@30
|
2224
|
flickerstreak@30
|
2225 local button = _G[this:GetName() .. "Button2"]
|
flickerstreak@30
|
2226 button:ClearAllPoints()
|
flickerstreak@30
|
2227 button:SetWidth(200)
|
flickerstreak@30
|
2228 button:SetPoint("CENTER", editBox, "CENTER", 0, -30)
|
flickerstreak@30
|
2229
|
flickerstreak@30
|
2230 _G[this:GetName() .. "AlertIcon"]:Hide() -- HACK : we hide the false AlertIcon
|
flickerstreak@30
|
2231 this:SetFrameStrata("FULLSCREEN_DIALOG")
|
flickerstreak@30
|
2232 bumpFrameLevels(this, 30)
|
flickerstreak@30
|
2233 end,
|
flickerstreak@30
|
2234 OnHide = function()
|
flickerstreak@30
|
2235 local editBox = _G[this:GetName() .. "WideEditBox"]
|
flickerstreak@30
|
2236 editBox:SetScript("OnTextChanged", nil)
|
flickerstreak@30
|
2237 this:SetFrameStrata("DIALOG")
|
flickerstreak@30
|
2238 bumpFrameLevels(this, -30)
|
flickerstreak@30
|
2239 end,
|
flickerstreak@30
|
2240 OnAccept = function() end,
|
flickerstreak@30
|
2241 OnCancel = function() end,
|
flickerstreak@30
|
2242 EditBoxOnEscapePressed = function() this:GetParent():Hide() end,
|
flickerstreak@30
|
2243 EditBoxOnTextChanged = function()
|
flickerstreak@30
|
2244 this:SetText(url)
|
flickerstreak@30
|
2245 this:SetFocus()
|
flickerstreak@30
|
2246 this:HighlightText(0)
|
flickerstreak@30
|
2247 end,
|
flickerstreak@30
|
2248 timeout = 0,
|
flickerstreak@30
|
2249 whileDead = 1,
|
flickerstreak@30
|
2250 hideOnEscape = 1
|
flickerstreak@30
|
2251 }
|
flickerstreak@30
|
2252 end
|
flickerstreak@30
|
2253
|
flickerstreak@30
|
2254 function OpenDonationFrame(self)
|
flickerstreak@30
|
2255 if makeURLFrame then
|
flickerstreak@30
|
2256 makeURLFrame()
|
flickerstreak@30
|
2257 end
|
flickerstreak@30
|
2258
|
flickerstreak@30
|
2259 local donate = self.donate
|
flickerstreak@30
|
2260 if type(donate) ~= "string" then
|
flickerstreak@30
|
2261 donate = "Wowace"
|
flickerstreak@30
|
2262 end
|
flickerstreak@30
|
2263 local style, data = (":"):split(donate, 2)
|
flickerstreak@30
|
2264 style = style:lower()
|
flickerstreak@30
|
2265 if style ~= "website" and style ~= "paypal" then
|
flickerstreak@30
|
2266 style = "wowace"
|
flickerstreak@30
|
2267 end
|
flickerstreak@30
|
2268 if style == "wowace" then
|
flickerstreak@30
|
2269 url = "http://www.wowace.com/wiki/Donations"
|
flickerstreak@30
|
2270 elseif style == "website" then
|
flickerstreak@30
|
2271 url = data
|
flickerstreak@30
|
2272 else -- PayPal
|
flickerstreak@30
|
2273 local text = "https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=" .. urlencode(unobfuscateEmail(data))
|
flickerstreak@30
|
2274 local name
|
flickerstreak@30
|
2275 if type(self.title) == "string" then
|
flickerstreak@30
|
2276 name = self.title
|
flickerstreak@30
|
2277 elseif type(self.name) == "string" then
|
flickerstreak@30
|
2278 name = self.name
|
flickerstreak@30
|
2279 end
|
flickerstreak@30
|
2280 if name == MAJOR_VERSION then
|
flickerstreak@30
|
2281 name = "Rock"
|
flickerstreak@30
|
2282 end
|
flickerstreak@30
|
2283 if name then
|
flickerstreak@30
|
2284 name = name:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", "")
|
flickerstreak@30
|
2285 text = text .. "&item_name=" .. urlencode(name)
|
flickerstreak@30
|
2286 end
|
flickerstreak@30
|
2287 url = text
|
flickerstreak@30
|
2288 end
|
flickerstreak@30
|
2289
|
flickerstreak@30
|
2290 StaticPopup_Show("ROCK_SHOW_URL")
|
flickerstreak@30
|
2291 end
|
flickerstreak@30
|
2292 function OpenIssueFrame(self)
|
flickerstreak@30
|
2293 if makeURLFrame then
|
flickerstreak@30
|
2294 makeURLFrame()
|
flickerstreak@30
|
2295 end
|
flickerstreak@30
|
2296
|
flickerstreak@30
|
2297 local issueTracker = self.issueTracker
|
flickerstreak@30
|
2298 if type(issueTracker) ~= "string" then
|
flickerstreak@30
|
2299 return
|
flickerstreak@30
|
2300 end
|
flickerstreak@30
|
2301 local style, data = (":"):split(issueTracker, 2)
|
flickerstreak@30
|
2302 style = style:lower()
|
flickerstreak@30
|
2303 if style ~= "website" and style ~= "wowace" then
|
flickerstreak@30
|
2304 return
|
flickerstreak@30
|
2305 end
|
flickerstreak@30
|
2306 if style == "wowace" then
|
flickerstreak@30
|
2307 url = "http://jira.wowace.com/secure/CreateIssue.jspa?pid=" .. data
|
flickerstreak@30
|
2308 elseif style == "website" then
|
flickerstreak@30
|
2309 url = data
|
flickerstreak@30
|
2310 end
|
flickerstreak@30
|
2311
|
flickerstreak@30
|
2312 StaticPopup_Show("ROCK_SHOW_URL")
|
flickerstreak@30
|
2313 end
|
flickerstreak@30
|
2314 local function donate_hidden(addon)
|
flickerstreak@30
|
2315 return type(addon.donate) ~= "string"
|
flickerstreak@30
|
2316 end
|
flickerstreak@30
|
2317
|
flickerstreak@30
|
2318 local function issue_hidden(addon)
|
flickerstreak@30
|
2319 return type(addon.issueTracker) ~= "string"
|
flickerstreak@30
|
2320 end
|
flickerstreak@30
|
2321
|
flickerstreak@30
|
2322 -- #NODOC
|
flickerstreak@30
|
2323 function Rock:GetRockConfigOptions(addon)
|
flickerstreak@30
|
2324 return 'active', {
|
flickerstreak@30
|
2325 type = 'boolean',
|
flickerstreak@30
|
2326 name = L["Enabled"],
|
flickerstreak@30
|
2327 desc = L["Enable or disable this addon."],
|
flickerstreak@30
|
2328 get = 'IsActive',
|
flickerstreak@30
|
2329 set = 'ToggleActive',
|
flickerstreak@30
|
2330 handler = addon,
|
flickerstreak@30
|
2331 order = -1,
|
flickerstreak@30
|
2332 }, 'donate', {
|
flickerstreak@30
|
2333 type = 'execute',
|
flickerstreak@30
|
2334 name = L["Give donation"],
|
flickerstreak@30
|
2335 buttonText = L["Donate"],
|
flickerstreak@30
|
2336 desc = L["Give a much-needed donation to the author of this addon."],
|
flickerstreak@30
|
2337 func = OpenDonationFrame,
|
flickerstreak@30
|
2338 hidden = donate_hidden,
|
flickerstreak@30
|
2339 passValue = addon,
|
flickerstreak@30
|
2340 order = -2,
|
flickerstreak@30
|
2341 }, 'issue', {
|
flickerstreak@30
|
2342 type = 'execute',
|
flickerstreak@30
|
2343 name = L["File issue"],
|
flickerstreak@30
|
2344 buttonText = L["Report"],
|
flickerstreak@30
|
2345 desc = L["File a bug or request a new feature or an improvement to this addon."],
|
flickerstreak@30
|
2346 func = OpenIssueFrame,
|
flickerstreak@30
|
2347 hidden = issue_hidden,
|
flickerstreak@30
|
2348 passValue = addon,
|
flickerstreak@30
|
2349 order = -3,
|
flickerstreak@30
|
2350 }
|
flickerstreak@30
|
2351 end
|
flickerstreak@30
|
2352
|
flickerstreak@30
|
2353 local function initAddon(addon, name)
|
flickerstreak@30
|
2354 name = addonToFolder[addon] or name or ""
|
flickerstreak@30
|
2355 -- TOC checks
|
flickerstreak@30
|
2356 if addon.title == nil then
|
flickerstreak@30
|
2357 addon.title = GetAddOnMetadata(name, "Title")
|
flickerstreak@30
|
2358 end
|
flickerstreak@30
|
2359 if type(addon.title) == "string" then
|
flickerstreak@30
|
2360 addon.title = addon.title:gsub("|c%x%x%x%x%x%x%x%x", ""):gsub("|r", ""):gsub("%-Rock%-$", ""):trim()
|
flickerstreak@30
|
2361 end
|
flickerstreak@30
|
2362 if addon.notes == nil then
|
flickerstreak@30
|
2363 addon.notes = GetAddOnMetadata(name, "Notes")
|
flickerstreak@30
|
2364 end
|
flickerstreak@30
|
2365 if type(addon.notes) == "string" then
|
flickerstreak@30
|
2366 addon.notes = addon.notes:trim()
|
flickerstreak@30
|
2367 end
|
flickerstreak@30
|
2368 if addon.version == nil then
|
flickerstreak@30
|
2369 addon.version = GetAddOnMetadata(name, "Version")
|
flickerstreak@30
|
2370 end
|
flickerstreak@30
|
2371 if type(addon.version) == "string" then
|
flickerstreak@30
|
2372 addon.version = addon.version:trim()
|
flickerstreak@30
|
2373 end
|
flickerstreak@30
|
2374 if addon.author == nil then
|
flickerstreak@30
|
2375 addon.author = GetAddOnMetadata(name, "Author")
|
flickerstreak@30
|
2376 end
|
flickerstreak@30
|
2377 if type(addon.author) == "string" then
|
flickerstreak@30
|
2378 addon.author = addon.author:trim()
|
flickerstreak@30
|
2379 end
|
flickerstreak@30
|
2380 if addon.credits == nil then
|
flickerstreak@30
|
2381 addon.credits = GetAddOnMetadata(name, "X-Credits")
|
flickerstreak@30
|
2382 end
|
flickerstreak@30
|
2383 if type(addon.credits) == "string" then
|
flickerstreak@30
|
2384 addon.credits = addon.credits:trim()
|
flickerstreak@30
|
2385 end
|
flickerstreak@30
|
2386 if addon.donate == nil then
|
flickerstreak@30
|
2387 addon.donate = GetAddOnMetadata(name, "X-Donate")
|
flickerstreak@30
|
2388 end
|
flickerstreak@30
|
2389 if type(addon.donate) == "string" then
|
flickerstreak@30
|
2390 addon.donate = addon.donate:trim()
|
flickerstreak@30
|
2391 end
|
flickerstreak@30
|
2392 if addon.issueTracker == nil then
|
flickerstreak@30
|
2393 addon.issueTracker = GetAddOnMetadata(name, "X-IssueTracker")
|
flickerstreak@30
|
2394 end
|
flickerstreak@30
|
2395 if type(addon.issueTracker) == "string" then
|
flickerstreak@30
|
2396 addon.issueTracker = addon.issueTracker:trim()
|
flickerstreak@30
|
2397 end
|
flickerstreak@30
|
2398 if addon.category == nil then
|
flickerstreak@30
|
2399 addon.category = GetAddOnMetadata(name, "X-Category")
|
flickerstreak@30
|
2400 end
|
flickerstreak@30
|
2401 if type(addon.category) == "string" then
|
flickerstreak@30
|
2402 addon.category = addon.category:trim()
|
flickerstreak@30
|
2403 end
|
flickerstreak@30
|
2404 if addon.email == nil then
|
flickerstreak@30
|
2405 addon.email = GetAddOnMetadata(name, "X-eMail") or GetAddOnMetadata(name, "X-Email")
|
flickerstreak@30
|
2406 end
|
flickerstreak@30
|
2407 if type(addon.email) == "string" then
|
flickerstreak@30
|
2408 addon.email = addon.email:trim()
|
flickerstreak@30
|
2409 end
|
flickerstreak@30
|
2410 if addon.license == nil then
|
flickerstreak@30
|
2411 addon.license = GetAddOnMetadata(name, "X-License")
|
flickerstreak@30
|
2412 end
|
flickerstreak@30
|
2413 if type(addon.license) == "string" then
|
flickerstreak@30
|
2414 addon.license = addon.license:trim()
|
flickerstreak@30
|
2415 end
|
flickerstreak@30
|
2416 if addon.website == nil then
|
flickerstreak@30
|
2417 addon.website = GetAddOnMetadata(name, "X-Website")
|
flickerstreak@30
|
2418 end
|
flickerstreak@30
|
2419 if type(addon.website) == "string" then
|
flickerstreak@30
|
2420 addon.website = addon.website:trim()
|
flickerstreak@30
|
2421 end
|
flickerstreak@30
|
2422
|
flickerstreak@30
|
2423 for mixin in Rock:IterateObjectMixins(addon) do
|
flickerstreak@30
|
2424 local mixin_OnEmbedInitialize = mixin.OnEmbedInitialize
|
flickerstreak@30
|
2425 if mixin_OnEmbedInitialize then
|
flickerstreak@30
|
2426 local success, ret = pcall(mixin_OnEmbedInitialize, mixin, addon)
|
flickerstreak@30
|
2427 if not success then
|
flickerstreak@30
|
2428 geterrorhandler()(ret)
|
flickerstreak@30
|
2429 end
|
flickerstreak@30
|
2430 end
|
flickerstreak@30
|
2431 end
|
flickerstreak@30
|
2432
|
flickerstreak@30
|
2433 local addon_OnInitialize = addon.OnInitialize
|
flickerstreak@30
|
2434 if addon_OnInitialize then
|
flickerstreak@30
|
2435 local success, ret = pcall(addon_OnInitialize, addon)
|
flickerstreak@30
|
2436 if not success then
|
flickerstreak@30
|
2437 geterrorhandler()(ret)
|
flickerstreak@30
|
2438 end
|
flickerstreak@30
|
2439 end
|
flickerstreak@30
|
2440
|
flickerstreak@30
|
2441 if LibRockEvent then
|
flickerstreak@30
|
2442 Rock:DispatchEvent("AddonInitialized", addon)
|
flickerstreak@30
|
2443 end
|
flickerstreak@30
|
2444 end
|
flickerstreak@30
|
2445
|
flickerstreak@30
|
2446
|
flickerstreak@30
|
2447 local function manualEnable(addon)
|
flickerstreak@30
|
2448 for i,v in ipairs(pendingAddons) do
|
flickerstreak@30
|
2449 if v == addon then
|
flickerstreak@30
|
2450 return
|
flickerstreak@30
|
2451 end
|
flickerstreak@30
|
2452 end
|
flickerstreak@30
|
2453 if currentlyEnabledAddons[addon] then
|
flickerstreak@30
|
2454 return false
|
flickerstreak@30
|
2455 end
|
flickerstreak@30
|
2456 currentlyEnabledAddons[addon] = true
|
flickerstreak@30
|
2457
|
flickerstreak@30
|
2458 local first = not addonsAlreadyEnabled[addon]
|
flickerstreak@30
|
2459 addonsAlreadyEnabled[addon] = true
|
flickerstreak@30
|
2460
|
flickerstreak@30
|
2461 for mixin in Rock:IterateObjectMixins(addon) do
|
flickerstreak@30
|
2462 local mixin_OnEmbedEnable = mixin.OnEmbedEnable
|
flickerstreak@30
|
2463 if mixin_OnEmbedEnable then
|
flickerstreak@30
|
2464 local success, ret = pcall(mixin_OnEmbedEnable, mixin, addon, first)
|
flickerstreak@30
|
2465 if not success then
|
flickerstreak@30
|
2466 geterrorhandler()(ret)
|
flickerstreak@30
|
2467 end
|
flickerstreak@30
|
2468 end
|
flickerstreak@30
|
2469 end
|
flickerstreak@30
|
2470 local addon_OnEnable = addon.OnEnable
|
flickerstreak@30
|
2471 if addon_OnEnable then
|
flickerstreak@30
|
2472 local success, ret = pcall(addon_OnEnable, addon, first)
|
flickerstreak@30
|
2473 if not success then
|
flickerstreak@30
|
2474 geterrorhandler()(ret)
|
flickerstreak@30
|
2475 end
|
flickerstreak@30
|
2476 end
|
flickerstreak@30
|
2477
|
flickerstreak@30
|
2478 if LibRockEvent then
|
flickerstreak@30
|
2479 Rock:DispatchEvent("AddonEnabled", addon, first)
|
flickerstreak@30
|
2480 end
|
flickerstreak@30
|
2481
|
flickerstreak@30
|
2482 return true, first
|
flickerstreak@30
|
2483 end
|
flickerstreak@30
|
2484
|
flickerstreak@30
|
2485 local function manualDisable(addon)
|
flickerstreak@30
|
2486 if not currentlyEnabledAddons[addon] then
|
flickerstreak@30
|
2487 return false
|
flickerstreak@30
|
2488 end
|
flickerstreak@30
|
2489 currentlyEnabledAddons[addon] = nil
|
flickerstreak@30
|
2490
|
flickerstreak@30
|
2491 for mixin in Rock:IterateObjectMixins(addon) do
|
flickerstreak@30
|
2492 local mixin_OnEmbedDisable = mixin.OnEmbedDisable
|
flickerstreak@30
|
2493 if mixin_OnEmbedDisable then
|
flickerstreak@30
|
2494 local success, ret = pcall(mixin_OnEmbedDisable, mixin, addon)
|
flickerstreak@30
|
2495 if not success then
|
flickerstreak@30
|
2496 geterrorhandler()(ret)
|
flickerstreak@30
|
2497 end
|
flickerstreak@30
|
2498 end
|
flickerstreak@30
|
2499 end
|
flickerstreak@30
|
2500 local addon_OnDisable = addon.OnDisable
|
flickerstreak@30
|
2501 if addon_OnDisable then
|
flickerstreak@30
|
2502 local success, ret = pcall(addon_OnDisable, addon)
|
flickerstreak@30
|
2503 if not success then
|
flickerstreak@30
|
2504 geterrorhandler()(ret)
|
flickerstreak@30
|
2505 end
|
flickerstreak@30
|
2506 end
|
flickerstreak@30
|
2507
|
flickerstreak@30
|
2508 if LibRockEvent then
|
flickerstreak@30
|
2509 Rock:DispatchEvent("AddonDisabled", addon)
|
flickerstreak@30
|
2510 end
|
flickerstreak@30
|
2511 return true
|
flickerstreak@30
|
2512 end
|
flickerstreak@30
|
2513
|
flickerstreak@30
|
2514 local function enableAddon(addon)
|
flickerstreak@30
|
2515 for i,v in ipairs(pendingAddons) do
|
flickerstreak@30
|
2516 if v == addon then
|
flickerstreak@30
|
2517 return
|
flickerstreak@30
|
2518 end
|
flickerstreak@30
|
2519 end
|
flickerstreak@30
|
2520 if addon_mt___index.IsActive(addon) then
|
flickerstreak@30
|
2521 manualEnable(addon)
|
flickerstreak@30
|
2522 end
|
flickerstreak@30
|
2523 end
|
flickerstreak@30
|
2524
|
flickerstreak@30
|
2525 -- #NODOC
|
flickerstreak@30
|
2526 -- This is used by internal Rock libraries after updating the active state.
|
flickerstreak@30
|
2527 function Rock:RecheckEnabledStates()
|
flickerstreak@30
|
2528 local changed = false
|
flickerstreak@30
|
2529 for _,addon in pairs(addons) do
|
flickerstreak@30
|
2530 local good = true
|
flickerstreak@30
|
2531 for _,a in ipairs(pendingAddonsEnable) do
|
flickerstreak@30
|
2532 if addon == a then
|
flickerstreak@30
|
2533 good = false
|
flickerstreak@30
|
2534 break
|
flickerstreak@30
|
2535 end
|
flickerstreak@30
|
2536 end
|
flickerstreak@30
|
2537 if good then
|
flickerstreak@30
|
2538 if addon_mt___index.IsActive(addon) then
|
flickerstreak@30
|
2539 if manualEnable(addon) then
|
flickerstreak@30
|
2540 changed = true
|
flickerstreak@30
|
2541 end
|
flickerstreak@30
|
2542 else
|
flickerstreak@30
|
2543 if manualDisable(addon) then
|
flickerstreak@30
|
2544 changed = true
|
flickerstreak@30
|
2545 end
|
flickerstreak@30
|
2546 end
|
flickerstreak@30
|
2547 end
|
flickerstreak@30
|
2548 end
|
flickerstreak@30
|
2549 if changed then
|
flickerstreak@30
|
2550 return self:RecheckEnabledStates()
|
flickerstreak@30
|
2551 end
|
flickerstreak@30
|
2552 end
|
flickerstreak@30
|
2553
|
flickerstreak@30
|
2554 frame:UnregisterAllEvents()
|
flickerstreak@30
|
2555 frame:RegisterEvent("ADDON_LOADED")
|
flickerstreak@30
|
2556 frame:RegisterEvent("PLAYER_LOGIN")
|
flickerstreak@30
|
2557 local function runMainAddonLoadedChunk(name)
|
flickerstreak@30
|
2558 local tmp = newList()
|
flickerstreak@30
|
2559 tmp, pendingAddons = pendingAddons, tmp
|
flickerstreak@30
|
2560 for i, addon in ipairs(tmp) do
|
flickerstreak@30
|
2561 local folder = addonToFolder[addon]
|
flickerstreak@30
|
2562 if name and folder and not foldersLoaded[folder] then
|
flickerstreak@30
|
2563 for j = i, #tmp do
|
flickerstreak@30
|
2564 pendingAddons[#pendingAddons+1] = tmp[j]
|
flickerstreak@30
|
2565 tmp[j] = nil
|
flickerstreak@30
|
2566 end
|
flickerstreak@30
|
2567 break
|
flickerstreak@30
|
2568 end
|
flickerstreak@30
|
2569 initAddon(addon, name)
|
flickerstreak@30
|
2570 end
|
flickerstreak@30
|
2571
|
flickerstreak@30
|
2572 if IsLoggedIn() then
|
flickerstreak@30
|
2573 for i, addon in ipairs(tmp) do
|
flickerstreak@30
|
2574 for j, v in ipairs(pendingAddonsEnable) do
|
flickerstreak@30
|
2575 if v == addon then
|
flickerstreak@30
|
2576 table_remove(pendingAddonsEnable, i)
|
flickerstreak@30
|
2577 break
|
flickerstreak@30
|
2578 end
|
flickerstreak@30
|
2579 end
|
flickerstreak@30
|
2580 enableAddon(addon)
|
flickerstreak@30
|
2581 end
|
flickerstreak@30
|
2582 for i, addon in ipairs(pendingAddonsEnable) do
|
flickerstreak@30
|
2583 local good = true
|
flickerstreak@30
|
2584 for j, v in ipairs(pendingAddons) do
|
flickerstreak@30
|
2585 if v == addon then
|
flickerstreak@30
|
2586 good = false
|
flickerstreak@30
|
2587 break
|
flickerstreak@30
|
2588 end
|
flickerstreak@30
|
2589 end
|
flickerstreak@30
|
2590 if not good then
|
flickerstreak@30
|
2591 break
|
flickerstreak@30
|
2592 end
|
flickerstreak@30
|
2593 pendingAddonsEnable[i] = nil
|
flickerstreak@30
|
2594 enableAddon(addon)
|
flickerstreak@30
|
2595 end
|
flickerstreak@30
|
2596 end
|
flickerstreak@30
|
2597 tmp = del(tmp)
|
flickerstreak@30
|
2598 for library, addonName in pairs(pendingLibraries) do
|
flickerstreak@30
|
2599 if not name or foldersLoaded[addonName] then
|
flickerstreak@30
|
2600 local success, ret = pcall(error, ("Library %q not finalized before ADDON_LOADED."):format(better_tostring(library)), 3)
|
flickerstreak@30
|
2601 geterrorhandler()(ret)
|
flickerstreak@30
|
2602 Rock:FinalizeLibrary((library:GetLibraryVersion()))
|
flickerstreak@30
|
2603 end
|
flickerstreak@30
|
2604 end
|
flickerstreak@30
|
2605
|
flickerstreak@30
|
2606 if isStandalone then
|
flickerstreak@30
|
2607 local LibRock_1_0DB = _G.LibRock_1_0DB
|
flickerstreak@30
|
2608 if type(LibRock_1_0DB) ~= "table" then
|
flickerstreak@30
|
2609 LibRock_1_0DB = {}
|
flickerstreak@30
|
2610 _G.LibRock_1_0DB = LibRock_1_0DB
|
flickerstreak@30
|
2611 end
|
flickerstreak@30
|
2612 if type(LibRock_1_0DB.unitTests) ~= "table" then
|
flickerstreak@30
|
2613 LibRock_1_0DB.unitTests = {}
|
flickerstreak@30
|
2614 end
|
flickerstreak@30
|
2615 enableContracts = LibRock_1_0DB.contracts or false
|
flickerstreak@30
|
2616 unitTestDB = LibRock_1_0DB.unitTests
|
flickerstreak@30
|
2617 for namespace, data in pairs(unitTests) do
|
flickerstreak@30
|
2618 if not unitTestDB[namespace] then
|
flickerstreak@30
|
2619 if data then
|
flickerstreak@30
|
2620 del(data)
|
flickerstreak@30
|
2621 unitTests[namespace] = false
|
flickerstreak@30
|
2622 end
|
flickerstreak@30
|
2623 elseif data and (not name or data.addon == name) then
|
flickerstreak@30
|
2624 local stats = newList()
|
flickerstreak@30
|
2625 for i,v in ipairs(data) do
|
flickerstreak@30
|
2626 data[i] = nil
|
flickerstreak@30
|
2627
|
flickerstreak@30
|
2628 local libs = newList()
|
flickerstreak@30
|
2629 for k,v in pairs(libraries) do
|
flickerstreak@30
|
2630 libs[k] = v
|
flickerstreak@30
|
2631 end
|
flickerstreak@30
|
2632
|
flickerstreak@30
|
2633 local success, ret = pcall(v)
|
flickerstreak@30
|
2634 if not success then
|
flickerstreak@30
|
2635 geterrorhandler()(ret)
|
flickerstreak@30
|
2636 stats[i] = ret
|
flickerstreak@30
|
2637 else
|
flickerstreak@30
|
2638 stats[i] = false
|
flickerstreak@30
|
2639 end
|
flickerstreak@30
|
2640
|
flickerstreak@30
|
2641 for k in pairs(libraries) do
|
flickerstreak@30
|
2642 if not libs[k] then
|
flickerstreak@30
|
2643 __removeLibrary(k)
|
flickerstreak@30
|
2644 end
|
flickerstreak@30
|
2645 end
|
flickerstreak@30
|
2646 libs = del(libs)
|
flickerstreak@30
|
2647
|
flickerstreak@30
|
2648 local lastCount
|
flickerstreak@30
|
2649 repeat
|
flickerstreak@30
|
2650 lastCount = collectgarbage('count')
|
flickerstreak@30
|
2651 collectgarbage('collect')
|
flickerstreak@30
|
2652 until lastCount == collectgarbage('count')
|
flickerstreak@30
|
2653 end
|
flickerstreak@30
|
2654 del(data)
|
flickerstreak@30
|
2655 unitTests[namespace] = false
|
flickerstreak@30
|
2656 if #stats >= 1 then
|
flickerstreak@30
|
2657 local pass, fail = 0, 0
|
flickerstreak@30
|
2658 for i,v in ipairs(stats) do
|
flickerstreak@30
|
2659 if v then
|
flickerstreak@30
|
2660 fail = fail + 1
|
flickerstreak@30
|
2661 else
|
flickerstreak@30
|
2662 pass = pass + 1
|
flickerstreak@30
|
2663 end
|
flickerstreak@30
|
2664 end
|
flickerstreak@30
|
2665
|
flickerstreak@30
|
2666 local color
|
flickerstreak@30
|
2667 if fail == 0 then
|
flickerstreak@30
|
2668 _G.DEFAULT_CHAT_FRAME:AddMessage(("|cff00ff00%s: %d unit test(s) passed."):format(namespace, pass))
|
flickerstreak@30
|
2669 elseif pass > 0 then
|
flickerstreak@30
|
2670 _G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s: %d unit test(s) passed, %d unit test(s) failed."):format(namespace, pass, fail))
|
flickerstreak@30
|
2671 else
|
flickerstreak@30
|
2672 _G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s: %d unit test(s) failed."):format(namespace, fail))
|
flickerstreak@30
|
2673 end
|
flickerstreak@30
|
2674 for i,v in ipairs(stats) do
|
flickerstreak@30
|
2675 if v then
|
flickerstreak@30
|
2676 _G.DEFAULT_CHAT_FRAME:AddMessage(("|cffff0000%s|r"):format(tostring(v)))
|
flickerstreak@30
|
2677 end
|
flickerstreak@30
|
2678 end
|
flickerstreak@30
|
2679 if fail > 0 then
|
flickerstreak@30
|
2680 _G.DEFAULT_CHAT_FRAME:AddMessage("|cffff0000----------|r")
|
flickerstreak@30
|
2681 end
|
flickerstreak@30
|
2682 end
|
flickerstreak@30
|
2683 stats = del(stats)
|
flickerstreak@30
|
2684 end
|
flickerstreak@30
|
2685 end
|
flickerstreak@30
|
2686 end
|
flickerstreak@30
|
2687 if isStandalone and name == MAJOR_VERSION then
|
flickerstreak@30
|
2688 Rock("LibRockEvent-1.0", false, true) -- load if possible
|
flickerstreak@30
|
2689 Rock("LibRockConsole-1.0", false, true) -- load if possible - I like the default chat commands
|
flickerstreak@30
|
2690 Rock("LibRockComm-1.0", false, true) -- load if possible - has version checking and the like
|
flickerstreak@30
|
2691 Rock("LibRockConfig-1.0", false, true) -- load if possible - LibRock-1.0 registers with it.
|
flickerstreak@30
|
2692 end
|
flickerstreak@30
|
2693
|
flickerstreak@30
|
2694 for major, library in LibStub:IterateLibraries() do
|
flickerstreak@30
|
2695 manualFinalize(major, library)
|
flickerstreak@30
|
2696 end
|
flickerstreak@30
|
2697
|
flickerstreak@30
|
2698 if IsLoggedIn() then
|
flickerstreak@30
|
2699 collectgarbage('collect')
|
flickerstreak@30
|
2700 end
|
flickerstreak@30
|
2701 end
|
flickerstreak@30
|
2702
|
flickerstreak@30
|
2703 frame:Show()
|
flickerstreak@30
|
2704 frame:SetScript("OnUpdate", function(this, elapsed)
|
flickerstreak@30
|
2705 -- capture all un-initialized addons.
|
flickerstreak@30
|
2706 runMainAddonLoadedChunk()
|
flickerstreak@30
|
2707 collectgarbage('collect')
|
flickerstreak@30
|
2708 this:SetScript("OnUpdate", run)
|
flickerstreak@30
|
2709 end)
|
flickerstreak@30
|
2710 frame:SetScript("OnEvent", function(this, event, ...)
|
flickerstreak@30
|
2711 if event == "ADDON_LOADED" then
|
flickerstreak@30
|
2712 -- this creates a new table and flushes the old in case someone LoDs an addon inside ADDON_LOADED.
|
flickerstreak@30
|
2713 local name = ...
|
flickerstreak@30
|
2714 foldersLoaded[name] = true
|
flickerstreak@30
|
2715 runMainAddonLoadedChunk(name)
|
flickerstreak@30
|
2716 frame:Show()
|
flickerstreak@30
|
2717 elseif event == "PLAYER_LOGIN" then
|
flickerstreak@30
|
2718 for i, addon in ipairs(pendingAddonsEnable) do
|
flickerstreak@30
|
2719 local good = true
|
flickerstreak@30
|
2720 for _, a in ipairs(pendingAddons) do
|
flickerstreak@30
|
2721 if a == addon then
|
flickerstreak@30
|
2722 good = false
|
flickerstreak@30
|
2723 break
|
flickerstreak@30
|
2724 end
|
flickerstreak@30
|
2725 end
|
flickerstreak@30
|
2726 if good then
|
flickerstreak@30
|
2727 pendingAddonsEnable[i] = nil
|
flickerstreak@30
|
2728 enableAddon(addon)
|
flickerstreak@30
|
2729 end
|
flickerstreak@30
|
2730 end
|
flickerstreak@30
|
2731 collectgarbage('collect')
|
flickerstreak@30
|
2732 end
|
flickerstreak@30
|
2733 end)
|
flickerstreak@30
|
2734
|
flickerstreak@30
|
2735 Rock:SetExportedMethods("SetExportedMethods", "Embed", "Unembed", "GetLibraryVersion")
|
flickerstreak@30
|
2736
|
flickerstreak@30
|
2737 Rock:FinalizeLibrary(MAJOR_VERSION)
|
flickerstreak@30
|
2738
|
flickerstreak@30
|
2739 for major, library in LibStub:IterateLibraries() do
|
flickerstreak@30
|
2740 manualFinalize(major, library)
|
flickerstreak@30
|
2741 end
|
flickerstreak@30
|
2742
|
flickerstreak@30
|
2743 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2744 -- test recycling
|
flickerstreak@30
|
2745 local newList, newDict, newSet, del = Rock:GetRecyclingFunctions(MAJOR_VERSION .. "_UnitTest", "newList", "newDict", "newSet", "del", "Debug")
|
flickerstreak@30
|
2746 local t = newList("Alpha", "Bravo", "Charlie")
|
flickerstreak@30
|
2747 assert(t[1] == "Alpha")
|
flickerstreak@30
|
2748 assert(t[2] == "Bravo")
|
flickerstreak@30
|
2749 assert(t[3] == "Charlie")
|
flickerstreak@30
|
2750 t = del(t)
|
flickerstreak@30
|
2751 t = newList("Alpha", "Bravo", "Charlie")
|
flickerstreak@30
|
2752 -- check recycled table
|
flickerstreak@30
|
2753 assert(t[1] == "Alpha")
|
flickerstreak@30
|
2754 assert(t[2] == "Bravo")
|
flickerstreak@30
|
2755 assert(t[3] == "Charlie")
|
flickerstreak@30
|
2756 t = del(t)
|
flickerstreak@30
|
2757 t = newDict("Alpha", "Bravo", "Charlie", "Delta")
|
flickerstreak@30
|
2758 assert(t.Alpha == "Bravo")
|
flickerstreak@30
|
2759 assert(t.Charlie == "Delta")
|
flickerstreak@30
|
2760 t = del(t)
|
flickerstreak@30
|
2761 t = newSet("Alpha", "Bravo", "Charlie")
|
flickerstreak@30
|
2762 assert(t.Alpha)
|
flickerstreak@30
|
2763 assert(t.Bravo)
|
flickerstreak@30
|
2764 assert(t.Charlie)
|
flickerstreak@30
|
2765 t = del(t)
|
flickerstreak@30
|
2766
|
flickerstreak@30
|
2767 local debug = recycleData.debugPools[MAJOR_VERSION .. "_UnitTest"]
|
flickerstreak@30
|
2768 assert(debug.num == 0)
|
flickerstreak@30
|
2769 t = newList()
|
flickerstreak@30
|
2770 assert(debug.num == 1)
|
flickerstreak@30
|
2771 t[1] = newList()
|
flickerstreak@30
|
2772 assert(debug.num == 2)
|
flickerstreak@30
|
2773 t[2] = newList()
|
flickerstreak@30
|
2774 assert(debug.num == 3)
|
flickerstreak@30
|
2775 t[1] = del(t[1])
|
flickerstreak@30
|
2776 assert(debug.num == 2)
|
flickerstreak@30
|
2777 t[2] = del(t[2])
|
flickerstreak@30
|
2778 assert(debug.num == 1)
|
flickerstreak@30
|
2779 t = del(t)
|
flickerstreak@30
|
2780 assert(debug.num == 0)
|
flickerstreak@30
|
2781 end)
|
flickerstreak@30
|
2782
|
flickerstreak@30
|
2783 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2784 -- test :GetUID()
|
flickerstreak@30
|
2785 local t = {}
|
flickerstreak@30
|
2786 for i = 1, 10000 do
|
flickerstreak@30
|
2787 local uid = Rock:GetUID()
|
flickerstreak@30
|
2788 if t[i] then
|
flickerstreak@30
|
2789 error(("UID match for iteration %d, UID %s"):format(i, uid))
|
flickerstreak@30
|
2790 end
|
flickerstreak@30
|
2791 t[i] = true
|
flickerstreak@30
|
2792 end
|
flickerstreak@30
|
2793 end)
|
flickerstreak@30
|
2794
|
flickerstreak@30
|
2795 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2796 -- test basic creation and deletion
|
flickerstreak@30
|
2797 assert(not LibStub:GetLibrary("LibRockFakeLib-1.0", true))
|
flickerstreak@30
|
2798 assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2799 local lib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
|
flickerstreak@30
|
2800 Rock:FinalizeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2801 lib = nil
|
flickerstreak@30
|
2802 assert(LibStub:GetLibrary("LibRockFakeLib-1.0", true))
|
flickerstreak@30
|
2803 assert(Rock:HasLibrary("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2804 local good = false
|
flickerstreak@30
|
2805 for _, lib in pairs(libraries) do
|
flickerstreak@30
|
2806 if lib.name == "LibRockFakeLib-1.0" then
|
flickerstreak@30
|
2807 good = true
|
flickerstreak@30
|
2808 break
|
flickerstreak@30
|
2809 end
|
flickerstreak@30
|
2810 end
|
flickerstreak@30
|
2811 assert(good)
|
flickerstreak@30
|
2812 __removeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2813 for _, lib in pairs(libraries) do
|
flickerstreak@30
|
2814 assert(lib.name ~= "LibRockFakeLib-1.0")
|
flickerstreak@30
|
2815 end
|
flickerstreak@30
|
2816 assert(not LibStub:GetLibrary("LibRockFakeLib-1.0", true))
|
flickerstreak@30
|
2817 assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2818 end)
|
flickerstreak@30
|
2819
|
flickerstreak@30
|
2820 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2821 -- test library creation and the like
|
flickerstreak@30
|
2822 assert(not Rock:HasLibrary("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2823 for name in Rock:IterateLibraries() do
|
flickerstreak@30
|
2824 assert(name ~= "LibRockFakeLib-1.0")
|
flickerstreak@30
|
2825 end
|
flickerstreak@30
|
2826
|
flickerstreak@30
|
2827 local myLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
|
flickerstreak@30
|
2828 assert(myLib)
|
flickerstreak@30
|
2829 assert(myLib.name == "LibRockFakeLib-1.0")
|
flickerstreak@30
|
2830 assert(not oldLib)
|
flickerstreak@30
|
2831
|
flickerstreak@30
|
2832 assert(myLib:GetLibraryVersion() == "LibRockFakeLib-1.0")
|
flickerstreak@30
|
2833 assert(select(2, myLib:GetLibraryVersion()) == 1)
|
flickerstreak@30
|
2834
|
flickerstreak@30
|
2835 local good = false
|
flickerstreak@30
|
2836 for name in Rock:IterateLibraries() do
|
flickerstreak@30
|
2837 if name == "LibRockFakeLib-1.0" then
|
flickerstreak@30
|
2838 good = true
|
flickerstreak@30
|
2839 break
|
flickerstreak@30
|
2840 end
|
flickerstreak@30
|
2841 end
|
flickerstreak@30
|
2842 assert(good)
|
flickerstreak@30
|
2843 assert(Rock:HasLibrary("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2844 assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
|
flickerstreak@30
|
2845 assert(Rock("LibRockFakeLib-1.0") == myLib)
|
flickerstreak@30
|
2846
|
flickerstreak@30
|
2847 assert(not Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2848 function myLib:DoSomething()
|
flickerstreak@30
|
2849 return "Something"
|
flickerstreak@30
|
2850 end
|
flickerstreak@30
|
2851 myLib:SetExportedMethods("DoSomething")
|
flickerstreak@30
|
2852 assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2853 local t = {}
|
flickerstreak@30
|
2854 assert(not Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2855 assert(not t.DoSomething)
|
flickerstreak@30
|
2856 for mixin in Rock:IterateObjectMixins(t) do
|
flickerstreak@30
|
2857 assert(false)
|
flickerstreak@30
|
2858 end
|
flickerstreak@30
|
2859 for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
|
flickerstreak@30
|
2860 assert(false)
|
flickerstreak@30
|
2861 end
|
flickerstreak@30
|
2862 myLib:Embed(t)
|
flickerstreak@30
|
2863 assert(t:DoSomething() == "Something")
|
flickerstreak@30
|
2864 assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2865 for mixin in Rock:IterateObjectMixins(t) do
|
flickerstreak@30
|
2866 assert(mixin == myLib)
|
flickerstreak@30
|
2867 end
|
flickerstreak@30
|
2868 for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
|
flickerstreak@30
|
2869 assert(object == t)
|
flickerstreak@30
|
2870 end
|
flickerstreak@30
|
2871
|
flickerstreak@30
|
2872 Rock:FinalizeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2873
|
flickerstreak@30
|
2874 local myNewLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 2)
|
flickerstreak@30
|
2875 assert(myNewLib == myLib)
|
flickerstreak@30
|
2876 assert(oldLib)
|
flickerstreak@30
|
2877 assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
|
flickerstreak@30
|
2878
|
flickerstreak@30
|
2879 function myLib:DoSomething()
|
flickerstreak@30
|
2880 return "Something else"
|
flickerstreak@30
|
2881 end
|
flickerstreak@30
|
2882 function myLib:TrySomething()
|
flickerstreak@30
|
2883 return "Blah"
|
flickerstreak@30
|
2884 end
|
flickerstreak@30
|
2885 myLib:SetExportedMethods("DoSomething", "TrySomething")
|
flickerstreak@30
|
2886 assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2887 assert(t:DoSomething() == "Something else")
|
flickerstreak@30
|
2888 assert(t:TrySomething() == "Blah")
|
flickerstreak@30
|
2889 assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2890 for mixin in Rock:IterateObjectMixins(t) do
|
flickerstreak@30
|
2891 assert(mixin == myLib)
|
flickerstreak@30
|
2892 end
|
flickerstreak@30
|
2893 for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
|
flickerstreak@30
|
2894 assert(object == t)
|
flickerstreak@30
|
2895 end
|
flickerstreak@30
|
2896
|
flickerstreak@30
|
2897 Rock:FinalizeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2898
|
flickerstreak@30
|
2899 local myNewLib, oldLib = Rock:NewLibrary("LibRockFakeLib-1.0", 3)
|
flickerstreak@30
|
2900 assert(myNewLib == myLib)
|
flickerstreak@30
|
2901 assert(oldLib)
|
flickerstreak@30
|
2902 assert(Rock:GetLibrary("LibRockFakeLib-1.0") == myLib)
|
flickerstreak@30
|
2903
|
flickerstreak@30
|
2904 function myLib:DoSomething()
|
flickerstreak@30
|
2905 return "Something"
|
flickerstreak@30
|
2906 end
|
flickerstreak@30
|
2907 myLib:SetExportedMethods("DoSomething")
|
flickerstreak@30
|
2908 assert(Rock:IsLibraryMixin("LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2909 assert(t:DoSomething() == "Something")
|
flickerstreak@30
|
2910 assert(t.TrySomething == nil)
|
flickerstreak@30
|
2911 assert(Rock:DoesObjectUseMixin(t, "LibRockFakeLib-1.0"))
|
flickerstreak@30
|
2912 for mixin in Rock:IterateObjectMixins(t) do
|
flickerstreak@30
|
2913 assert(mixin == myLib)
|
flickerstreak@30
|
2914 end
|
flickerstreak@30
|
2915 for object in Rock:IterateMixinObjects("LibRockFakeLib-1.0") do
|
flickerstreak@30
|
2916 assert(object == t)
|
flickerstreak@30
|
2917 end
|
flickerstreak@30
|
2918
|
flickerstreak@30
|
2919 Rock:FinalizeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2920
|
flickerstreak@30
|
2921 assert(not Rock:NewLibrary("LibRockFakeLib-1.0", 2)) -- out of date
|
flickerstreak@30
|
2922 assert(not Rock:NewLibrary("LibRockFakeLib-1.0", 3)) -- same revision
|
flickerstreak@30
|
2923 end)
|
flickerstreak@30
|
2924
|
flickerstreak@30
|
2925 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2926 assert(not Rock:HasAddon("RockFakeAddon"))
|
flickerstreak@30
|
2927 for name in Rock:IterateAddons() do
|
flickerstreak@30
|
2928 assert(name ~= "RockFakeAddon")
|
flickerstreak@30
|
2929 end
|
flickerstreak@30
|
2930
|
flickerstreak@30
|
2931 local myAddon = Rock:NewAddon("RockFakeAddon")
|
flickerstreak@30
|
2932
|
flickerstreak@30
|
2933 assert(myAddon)
|
flickerstreak@30
|
2934 assert(myAddon.name == "RockFakeAddon")
|
flickerstreak@30
|
2935
|
flickerstreak@30
|
2936 local good = false
|
flickerstreak@30
|
2937 for name in Rock:IterateAddons() do
|
flickerstreak@30
|
2938 if name == "RockFakeAddon" then
|
flickerstreak@30
|
2939 good = true
|
flickerstreak@30
|
2940 break
|
flickerstreak@30
|
2941 end
|
flickerstreak@30
|
2942 end
|
flickerstreak@30
|
2943 assert(good)
|
flickerstreak@30
|
2944 assert(Rock:HasAddon("RockFakeAddon"))
|
flickerstreak@30
|
2945 assert(Rock:GetAddon("RockFakeAddon") == myAddon)
|
flickerstreak@30
|
2946 end)
|
flickerstreak@30
|
2947
|
flickerstreak@30
|
2948 Rock:AddUnitTest(MAJOR_VERSION, function()
|
flickerstreak@30
|
2949 -- test :OnLibraryLoad
|
flickerstreak@30
|
2950 local lib = Rock:NewLibrary("LibRockFakeLib-1.0", 1)
|
flickerstreak@30
|
2951 local triggered = false
|
flickerstreak@30
|
2952 function lib:OnLibraryLoad(major, instance)
|
flickerstreak@30
|
2953 if major == "LibRockFakeLib-2.0" then
|
flickerstreak@30
|
2954 triggered = true
|
flickerstreak@30
|
2955 end
|
flickerstreak@30
|
2956 end
|
flickerstreak@30
|
2957 Rock:FinalizeLibrary("LibRockFakeLib-1.0")
|
flickerstreak@30
|
2958
|
flickerstreak@30
|
2959 local lib = Rock:NewLibrary("LibRockFakeLib-2.0", 1)
|
flickerstreak@30
|
2960 assert(not triggered)
|
flickerstreak@30
|
2961 Rock:FinalizeLibrary("LibRockFakeLib-2.0")
|
flickerstreak@30
|
2962 assert(triggered)
|
flickerstreak@30
|
2963 triggered = false
|
flickerstreak@30
|
2964 local lib = Rock:NewLibrary("LibRockFakeLib-2.0", 2)
|
flickerstreak@30
|
2965 assert(not triggered)
|
flickerstreak@30
|
2966 Rock:FinalizeLibrary("LibRockFakeLib-2.0")
|
flickerstreak@30
|
2967 assert(not triggered)
|
flickerstreak@30
|
2968 end)
|