Mercurial > wow > skeletonkey
comparison LibKraken/LibKraken.lua @ 59:d8bb2629fea8
LKT
- organized addon templates a little
- centralized ticker
author | Nenue |
---|---|
date | Sat, 27 Aug 2016 10:31:48 -0400 |
parents | 9eebce04e69b |
children | 256585077cdd |
comparison
equal
deleted
inserted
replaced
58:39cfd8e142f9 | 59:d8bb2629fea8 |
---|---|
39 local LIBKT_MAJOR, LIBKT_MINOR = "LibKraken", 2 | 39 local LIBKT_MAJOR, LIBKT_MINOR = "LibKraken", 2 |
40 local KT = LibStub:NewLibrary(LIBKT_MAJOR, LIBKT_MINOR) | 40 local KT = LibStub:NewLibrary(LIBKT_MAJOR, LIBKT_MINOR) |
41 | 41 |
42 --GLOBALS: KTErrorFrame, LibKTError, SlashCmdList, SLASH_RL1, SLASH_UI1 | 42 --GLOBALS: KTErrorFrame, LibKTError, SlashCmdList, SLASH_RL1, SLASH_UI1 |
43 local CreateFrame, debugstack, tostring, select = CreateFrame, debugstack, tostring, select | 43 local CreateFrame, debugstack, tostring, select = CreateFrame, debugstack, tostring, select |
44 local max, unpack, tinsert = max, unpack, tinsert | 44 local max, unpack, tinsert, tremove = max, unpack, tinsert, tremove |
45 local ipairs, xpcall, next, safecall = ipairs, xpcall, next, safecall | 45 local ipairs, pairs, xpcall = ipairs, pairs, xpcall |
46 local UI_TOGGLE = false | 46 local type, assert = type, assert |
47 local IsLoggedIn = IsLoggedIn | |
47 local db | 48 local db |
48 | 49 |
50 local print = DEVIAN_WORKSPACE and function(...) _G.print('LKT', ...) end or function() end | |
51 local noFunc = function() end | |
49 | 52 |
50 KT.handler = CreateFrame('Frame', 'LibKTHostFrame', UIParent) | 53 KT.handler = CreateFrame('Frame', 'LibKTHostFrame', UIParent) |
51 KT.addons = {} | 54 KT.addons = {} |
52 KT.initStack = {} | 55 KT.initStack = {} |
53 KT.varsStack = {} | 56 local libInitialized = false |
54 local print = DEVIAN_WORKSPACE and function(...) _G.print('LKT', ...) end or function() end | |
55 local registeredHandles = {} | 57 local registeredHandles = {} |
58 local initialized = {} | |
59 local enabled = {} | |
56 local handlers = {} | 60 local handlers = {} |
57 | 61 |
58 | 62 |
59 --- /rl | 63 |
60 -- ReloadUI shortcut | 64 local debuggers = {} |
61 SLASH_RL1 = "/rl" | 65 local pending = {} |
62 SlashCmdList.RL = function () | 66 |
63 ReloadUI() | 67 |
64 end | 68 local Embed = function (target, template) |
65 | 69 for k,v in pairs(template) do |
66 --- /ui | 70 if not target[k] then |
67 -- Run any addon:ui() methods | 71 target[k] = template[k] |
68 SLASH_UI1 = "/ui" | 72 end |
69 SlashCmdList.UI = function () | 73 end |
70 if UI_TOGGLE then | 74 end |
71 UI_TOGGLE = false | 75 |
72 else | 76 local LibKT_Error = function(msg) |
73 UI_TOGGLE = true | |
74 end | |
75 for i, frame in pairs(KT.frames) do | |
76 if UI_TOGGLE then | |
77 if frame.close then | |
78 frame.close() | |
79 else | |
80 frame:Hide() | |
81 end | |
82 else | |
83 if frame.ui then | |
84 frame.ui() | |
85 end | |
86 frame:Show() | |
87 end | |
88 end | |
89 end | |
90 | |
91 LibKTError = function(msg) | |
92 local dstack = debugstack(2) | 77 local dstack = debugstack(2) |
93 :gsub("Interface\\AddOns\\",'') | 78 :gsub("Interface\\AddOns\\",'') |
94 :gsub("<(.-)>", function(a) return '|cFF00FFFF<'.. a ..'>|r' end) | 79 :gsub("<(.-)>", function(a) return '|cFF00FFFF<'.. a ..'>|r' end) |
95 | 80 |
96 | 81 |
99 KTErrorFrame.debugstack:SetText(dstack) | 84 KTErrorFrame.debugstack:SetText(dstack) |
100 KTErrorFrame:SetHeight(KTErrorFrame.debugstack:GetStringHeight() + KTErrorFrame.errmsg:GetStringHeight() + 12) | 85 KTErrorFrame:SetHeight(KTErrorFrame.debugstack:GetStringHeight() + KTErrorFrame.errmsg:GetStringHeight() + 12) |
101 KTErrorFrame:Show() | 86 KTErrorFrame:Show() |
102 end | 87 end |
103 | 88 |
104 local debuggers = {} | 89 local LibKT_OnLoad = function(self) |
105 local pending = {} | 90 --- /rl |
106 local processing = false | 91 -- ReloadUI shortcut |
107 local isHandled = false | 92 SLASH_RL1 = "/rl" |
108 local nodebug = false | 93 SlashCmdList.RL = function () |
109 function KT.OnEvent (addon, event, ...) | 94 ReloadUI() |
110 if processing then | 95 end |
111 local args = {...} | 96 libInitialized = true |
112 C_Timer.After(0, function() KT.OnEvent(addon, event, unpack(args)) end) | 97 end |
113 return | 98 |
114 else | 99 local LibKT_OnEvent = function(self, event, arg1) |
115 | 100 print(event, arg1) |
116 end | 101 if (event == 'ADDON_LOADED' and arg1 ~= 'Blizzard_DebugTools') or event == 'PLAYER_LOGIN' then |
117 --- reset state | 102 if not libInitialized then |
118 processing = true | 103 LibKT_OnLoad(self) |
119 isHandled = false | 104 end |
120 nodebug = false | 105 |
121 | 106 |
122 | 107 -- run any init blocks left in the queue |
123 if addon.event then | 108 for i, addon in ipairs(KT.initStack) do |
124 nodebug = addon.event(addon, event, ...) | 109 if not initialized[addon] then |
125 end | 110 print('|cFF0088FF'..tostring(addon)..'|r:init()') |
126 | 111 if addon.init then |
127 if addon[event] then | 112 xpcall(addon.init, LibKT_Error) |
128 nodebug = addon[event](addon, event, ...) or nodebug | 113 end |
129 addon.missed = 0 | 114 |
130 addon.handled = addon.handled + 1 | 115 if addon.event then |
131 isHandled = true | 116 addon:SetScript('OnEvent', addon.event) |
132 else | 117 end |
133 addon.firstEvent = false | 118 |
134 addon.unhandled = addon.unhandled + 1 | 119 initialized[addon] = true |
135 addon.missed = addon.missed + 1 | 120 end |
136 end | 121 |
137 | 122 if #addon.modules >= 1 then |
138 for i, module in ipairs(addon.modules) do | 123 for i, module in ipairs(addon.modules) do |
139 --print(i, module) | 124 if not initialized[module] then |
140 if module[event] then | 125 print(i .. ' |cFF0088FF'..tostring(addon)..'|r.|cFF00FFFF'..tostring(module)..'|r:init()') |
141 nodebug = module[event](addon, event, ...) or nodebug | 126 if module.init then |
127 xpcall(module.init, LibKT_Error) | |
128 end | |
129 | |
130 if module.event then | |
131 module:SetScript('OnEvent', module.event) | |
132 end | |
133 initialized[module] = true | |
134 end | |
135 end | |
136 end | |
137 | |
138 end | |
139 | |
140 -- run any variables blocks if player variables are ready | |
141 if IsLoggedIn() then | |
142 | |
143 for i, addon in ipairs(KT.initStack) do | |
144 print('|cFF88FF00'..tostring(addon)..'|r') | |
145 if initialized[addon] then | |
146 if not enabled[addon] then | |
147 print('|cFF88FF00'..tostring(addon)..'|r:variables()') | |
148 if addon.variables then | |
149 xpcall(addon.variables, LibKT_Error) | |
150 end | |
151 enabled[addon] = true | |
152 end | |
153 | |
154 if addon.modules and enabled[addon] then | |
155 for i, module in ipairs(addon.modules) do | |
156 print(i .. ' |cFF88FF00'..tostring(module)..'|r') | |
157 if not enabled[module] then | |
158 if module.variables then | |
159 print(i..' |cFF88FF00'..tostring(addon)..'|r.|cFF00FFFF'.. tostring(module)..'|r:variables()') | |
160 xpcall(module.variables, LibKT_Error) | |
161 end | |
162 enabled[module] = true | |
163 end | |
164 end | |
165 end | |
166 end | |
167 end | |
168 end | |
169 end | |
170 end | |
171 | |
172 --- GUI bits | |
173 local defaultGUIAddon = {} | |
174 do | |
175 local GetButtonTemplate = function(name, parent, template, onClick) | |
176 if _G[name] then | |
177 return _G[name] | |
178 end | |
179 | |
180 local button = CreateFrame('Button', name, parent, template) | |
181 button:RegisterForClicks('AnyUp') | |
182 button:SetScript('OnClick', onClick) | |
183 return button | |
184 end | |
185 | |
186 local SetButtonAnchor = function(self, collector, anchor, growth) | |
187 if self:GetID() == 0 then | |
188 self:SetID(#collector) | |
189 print('registered TabButton #', self:GetID()) | |
190 end | |
191 | |
192 if self:GetID() == 1 then | |
193 self:SetPoint(unpack(anchor)) | |
194 else | |
195 growth[2] = collector[self:GetID()-1] | |
196 self:SetPoint(unpack(growth)) | |
197 end | |
198 end | |
199 | |
200 defaultGUIAddon.tab = function(self, name, tooltip, texture, coords) | |
201 local button = GetButtonTemplate(name, self, 'KTTabButton', self.SelectTab) | |
202 button.icon:SetTexture(texture) | |
203 button.tooltip = tooltip | |
204 button:SetSize(unpack(self.tabSize)) | |
205 if coords then | |
206 button.icon:SetTexCoord(unpack(coords)) | |
207 end | |
208 SetButtonAnchor(button, self.tabButtons, self.tabAnchor, self.tabGrowth) | |
209 return button | |
210 end | |
211 | |
212 defaultGUIAddon.button = function(self, name, text, tooltip, onClick) | |
213 local button = GetButtonTemplate(name, self, 'KTButton', onClick) | |
214 | |
215 button.tooltip = tooltip | |
216 button:SetText(text) | |
217 button:SetWidth(max(button:GetWidth(), button:GetFontString():GetStringWidth() + 12)) | |
218 | |
219 SetButtonAnchor(button, self.controls, self.controlsAnchor, self.controlsGrowth) | |
220 return button | |
221 end | |
222 | |
223 defaultGUIAddon.uibutton = function(self, name, text, tooltip, onClick, texture, coords) | |
224 local button = GetButtonTemplate(name, self, 'KTUIPanelButton', onClick) | |
225 | |
226 button.tooltip = tooltip | |
227 button:SetText(text) | |
228 | |
229 if self.UIPanelIcon then | |
230 local w, h, anchor, x, y = unpack(self.UIPanelIcon) | |
231 button.icon:SetTexture(texture) | |
232 button.icon:SetSize(w, h) | |
233 button.icon:ClearAllPoints() | |
234 button.icon:SetPoint(anchor, button, anchor, x, y) | |
235 end | |
236 | |
237 if not self.UIPanelSize then | |
238 button:SetWidth(button:GetFontString():GetStringWidth() + button.icon:GetWidth()/1.5) | |
239 else | |
240 button:SetSize(unpack(self.UIPanelSize)) | |
241 end | |
242 if coords then | |
243 button.icon:SetTexCoord(unpack(coords)) | |
244 end | |
245 SetButtonAnchor(button, self.UIPanels, self.UIPanelAnchor, self.UIPanelGrowth) | |
246 return button | |
247 end | |
248 end | |
249 | |
250 | |
251 local defaultAddon = {} | |
252 do | |
253 defaultAddon.print = function(module, ...) | |
254 local msg = '|cFF00FFFF'..module:GetName()..'|r:' | |
255 for i = 1, select('#', ...) do | |
256 msg = msg .. ' ' .. tostring(select(i, ...)) | |
257 end | |
258 DEFAULT_CHAT_FRAME:AddMessage(msg) | |
259 end | |
260 | |
261 | |
262 local tickerQueue = {} | |
263 local ticker | |
264 defaultAddon.tick = function() | |
265 | |
266 if #tickerQueue == 0 then | |
267 ticker:Cancel() | |
268 ticker = nil | |
269 end | |
270 local func = tremove(tickerQueue, 1) | |
271 if func then | |
272 --print('#', #tickerQueue) | |
273 func() | |
274 end | |
275 end | |
276 | |
277 defaultAddon.next = function(f) | |
278 if not ticker then | |
279 --print('create ticker') | |
280 ticker = C_Timer.NewTicker(.001, defaultAddon.tick) | |
281 end | |
282 tinsert(tickerQueue, f) | |
283 | |
284 return #tickerQueue | |
285 end | |
286 | |
287 | |
288 --- default OnEvent | |
289 | |
290 local processing = false | |
291 local isHandled = false | |
292 local nodebug = false | |
293 defaultAddon.event = function (addon, event, ...) | |
294 if processing then | |
295 local args = {...} | |
296 C_Timer.After(0, function() KT.OnEvent(addon, event, unpack(args)) end) | |
297 return | |
298 else | |
299 | |
300 end | |
301 --- reset state | |
302 processing = true | |
303 isHandled = false | |
304 nodebug = false | |
305 | |
306 | |
307 if addon.event then | |
308 nodebug = addon.event(addon, event, ...) | |
309 elseif addon[event] then | |
310 nodebug = addon[event](addon, event, ...) or nodebug | |
142 addon.missed = 0 | 311 addon.missed = 0 |
143 addon.handled = addon.handled + 1 | 312 addon.handled = addon.handled + 1 |
144 isHandled = true | 313 isHandled = true |
145 else | 314 else |
146 addon.firstEvent = false | 315 addon.firstEvent = false |
147 addon.unhandled = addon.unhandled + 1 | 316 addon.unhandled = addon.unhandled + 1 |
148 addon.missed = addon.missed + 1 | 317 addon.missed = addon.missed + 1 |
149 end | 318 end |
150 | 319 |
151 end | 320 if addon.modules then |
152 --if nodebug then | 321 for i, module in ipairs(addon.modules) do |
322 --print(i, module, event) | |
323 if module.event then | |
324 module.event(module, event, ...) | |
325 elseif module[event] then | |
326 nodebug = module[event](addon, event, ...) or nodebug | |
327 addon.missed = 0 | |
328 addon.handled = addon.handled + 1 | |
329 isHandled = true | |
330 else | |
331 addon.firstEvent = false | |
332 addon.unhandled = addon.unhandled + 1 | |
333 addon.missed = addon.missed + 1 | |
334 end | |
335 end | |
336 end | |
337 --if nodebug then | |
153 processing = false | 338 processing = false |
154 return | 339 return |
155 --else | 340 --else |
156 -- KT.UpdateEventStatus(addon, event, ...) | 341 -- KT.UpdateEventStatus(addon, event, ...) |
157 -- processing = false | 342 -- processing = false |
158 --end | 343 --end |
159 | 344 |
160 end | 345 end |
161 | 346 defaultAddon.wrap = function(addon, module, name) |
162 KT.UpdateEventStatus = function(addon, event, ...) | 347 local moduleName = name or tostring(module) |
163 if (addon.DEVIAN_PNAME and addon.DEVIAN_PNAME == DEVIAN_PNAME) or ((not addon.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then | 348 print(addon, module) |
164 print(addon:GetName(), event, ...) | 349 print('|cFF0088FF'..tostring(addon)..'|r:wrap(|cFF00FFFF'.. moduleName .. '|r|cFFFFFF00)|r') |
165 end | 350 |
166 | 351 addon.modules = addon.modules or {} |
167 -- debug outputs | 352 tinsert(addon.modules, module) |
168 if addon.status then | 353 |
169 addon.status:SetText(event .. '\n|cFF00FF00' .. addon.handled .. '|r |cFFFF8800' .. addon.missed .. '|r |cFFFF4400' .. addon.unhandled .. '|r') | 354 |
170 if isHandled then | 355 if (module.DEVIAN_PNAME and DEVIAN_PNAME == module.DEVIAN_PNAME) or ((not module.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then |
171 addon.status:SetTextColor(0,1,0) | 356 debuggers[module] = function(...) _G.print(moduleName, ...) end |
172 if addon.log then | 357 else |
173 local logtext = event | 358 debuggers[module] = noFunc |
174 for i = 1, select('#',...) do | 359 end |
175 logtext = logtext .. '\n' .. i .. ':' .. tostring(select(i,...)) | 360 return debuggers[module] |
176 end | 361 end |
177 addon.log:SetText('|cFFFFFF00last|r\n' .. logtext) | 362 |
178 local newWidth = addon.log:GetStringWidth() | 363 defaultAddon.GetName = function(self) return tostring(self) end |
179 | 364 end |
180 if addon.logfirst then | 365 |
181 if not addon.firstEvent then | 366 --- Frame registration |
182 addon.firstEvent = event | |
183 addon.logfirst:SetText('|cFF00FF88first|r\n' .. logtext) | |
184 end | |
185 | |
186 newWidth = newWidth + addon.logfirst:GetStringWidth() | |
187 end | |
188 if addon.logdiff then | |
189 if not event ~= addon.firstEvent then | |
190 addon.firstEvent = event | |
191 addon.logdiff:SetText('|cFF0088FFdiff|r\n' .. logtext) | |
192 end | |
193 newWidth = newWidth + addon.logdiff:GetStringWidth() | |
194 end | |
195 --addon:SetWidth(newWidth) | |
196 end | |
197 else | |
198 addon.status:SetTextColor(1,0,0) | |
199 end | |
200 end | |
201 end | |
202 | |
203 KT.map = function(addon, addonTable) | |
204 setmetatable(addonTable, { | |
205 __index = function(_,k) | |
206 return addon[k] | |
207 end, | |
208 __newindex = function(_, k, v) | |
209 addon[k] = v | |
210 end | |
211 }) | |
212 end | |
213 | |
214 local emptyFunc = function() end | |
215 | |
216 KT.register = function(addon, arg, noGUI) | 367 KT.register = function(addon, arg, noGUI) |
217 | 368 --print('register(', addon, arg, ')') |
218 local name, handler | 369 local name, handler |
219 if type(addon) == 'string' and type(arg) == 'table' then | 370 if type(addon) == 'string' and type(arg) == 'table' then |
371 name = addon | |
220 -- it's a string, i.e. file vararg was passed | 372 -- it's a string, i.e. file vararg was passed |
221 if _G[addon] then | 373 if _G[addon] then |
222 -- check if it's the name of a frame and use that | 374 -- check if it's the name of a frame and use that |
223 handler = _G[addon] | 375 handler = _G[addon] |
224 else | 376 else |
225 -- re-arrange | 377 -- re-arrange |
226 name = addon | |
227 handler = arg | 378 handler = arg |
228 end | 379 end |
229 else | 380 else |
230 handler = addon | 381 handler = addon |
231 assert(type(handler) == 'table', 'Unable to parse ('..tostring(type(addon))..', '..tostring(type(arg))..')') | 382 assert(type(handler) == 'table', 'Usage: KT.register(name, table) or KT.register(table, plugin)') |
232 end | 383 end |
233 | 384 |
234 | 385 |
235 local loadedName | |
236 local printName | 386 local printName |
237 local isModule | 387 local isModule |
238 | 388 |
239 -- if exists, then second argument is probably a module name | 389 local scriptName = debugstack(2,1,0):match(".+\\(%S+)%.lua") |
240 if registeredHandles[handler] then | 390 if registeredHandles[handler] then |
391 -- addon is already register; treat second argument as plugin target | |
392 isModule = true | |
241 if type(arg) == 'table' then | 393 if type(arg) == 'table' then |
242 tinsert(handler.modules, arg) | 394 local mt = getmetatable(arg) |
243 else | 395 setmetatable(arg, {__index = mt.__index, __tostring = function() return scriptName end}) |
244 name = arg or debugstack(2,1,0):match(".+\\(%S+)%.lua") | 396 local debugger = handler:wrap(arg) |
245 end | 397 return handler, debugger |
246 isModule = true | 398 else |
247 | 399 print(' + "|cFF00FFFF'..scriptName..'|r"') |
248 if not name then | 400 end |
249 name = debugstack(2,1,0):match(".+\\(%S+)%.lua") | |
250 end | |
251 local handlerName = handler:GetName() | |
252 loadedName = '|cFF00FF88'.. tostring(handlerName) .. '|r:|cFFFFFF00'.. tostring(name) | |
253 else | 401 else |
254 if handler.GetName then | 402 -- new addon |
255 name = handler:GetName() | 403 --local scriptName = debugstack(2,1,0):match(".+\\(%S+)%.lua") |
256 elseif not name then | 404 local mt = getmetatable(handler) |
257 name = debugstack(2,1,0):match(".+\\(%S+)%.lua") | 405 local nmt = {__index = mt.__index, __tostring = function() return scriptName end } |
258 end | 406 handler = setmetatable(handler, nmt) |
259 | 407 Embed(handler, defaultAddon) |
260 loadedName = '|cFF00FFFF'.. tostring(name) .. '|r' | 408 name = tostring(handler) |
261 | |
262 registeredHandles[handler] = name | 409 registeredHandles[handler] = name |
263 if handler.SetScript then | 410 if handler.SetScript then |
264 handler:SetScript('OnEvent', KT.OnEvent) | 411 handler:SetScript('OnEvent', handler.event) |
265 end | 412 end |
266 handler.unhandled = 0 | 413 handler.unhandled = 0 |
267 handler.missed = 0 | 414 handler.missed = 0 |
268 handler.handled = 0 | 415 handler.handled = 0 |
269 handler.firstEvent = false | 416 handler.firstEvent = false |
270 handler.modules = {} | 417 handler.modules = {} |
271 tinsert(KT.initStack, handler) | 418 tinsert(KT.initStack, handler) |
272 tinsert(KT.varsStack, handler) | 419 |
273 | 420 if not noGUI then |
274 if handler.GetName and (not noGUI) then | |
275 handler.UIPanelAnchor = {'TOPLEFT', handler, 'TOPLEFT', 12, -12 } | 421 handler.UIPanelAnchor = {'TOPLEFT', handler, 'TOPLEFT', 12, -12 } |
276 handler.UIPanelGrowth = {'TOPLEFT', 'TOPRIGHT', 14, 0} | 422 handler.UIPanelGrowth = {'TOPLEFT', 'TOPRIGHT', 14, 0} |
277 handler.button = KT.button | 423 Embed(handler, defaultGUIAddon) |
278 handler.uibutton = KT.uibutton | 424 end |
279 handler.tab = KT.tab | 425 |
280 handler.print = KT.print | 426 print('|cFF0088FF'..tostring(addon)..'|r') |
281 end | 427 end |
282 end | 428 |
283 | 429 local debugFunc = noFunc |
284 local debugFunc = emptyFunc | |
285 --@debug@ | 430 --@debug@ |
286 local debugID = isModule and name or handler | 431 local debugID = isModule and name or handler |
287 if (handler.DEVIAN_PNAME and DEVIAN_PNAME == handler.DEVIAN_PNAME) or ((not handler.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then | 432 if (handler.DEVIAN_PNAME and DEVIAN_PNAME == handler.DEVIAN_PNAME) or ((not handler.DEVIAN_PNAME) and DEVIAN_WORKSPACE) then |
288 debuggers[debugID] = debuggers[debugID] or function(...) _G.print(name, ...) end | 433 debuggers[debugID] = debuggers[debugID] or function(...) _G.print(name, ...) end |
289 debugFunc = debuggers[debugID] | 434 debugFunc = debuggers[debugID] |
290 end | 435 end |
291 print(loadedName) | |
292 --@end-debug@ | 436 --@end-debug@ |
293 return handler, debugFunc, KT.wrap | 437 return handler, debugFunc |
294 end | |
295 | |
296 | |
297 | |
298 local onEvent = function(self, event, arg1) | |
299 if (event == 'ADDON_LOADED' and arg1 ~= 'Blizzard_DebugTools') or event == 'PLAYER_LOGIN' then | |
300 -- run any init blocks left in the queue | |
301 while #KT.initStack >= 1 do | |
302 local addon = tremove(KT.initStack, 1) | |
303 print('KT', addon:GetName(), 'init') | |
304 if addon.init then | |
305 xpcall(addon.init, LibKTError) | |
306 for i, module in ipairs(addon.modules) do | |
307 if module.init then | |
308 xpcall(module.init, LibKTError) | |
309 end | |
310 end | |
311 end | |
312 end | |
313 | |
314 -- run any variables blocks if player variables are ready | |
315 if IsLoggedIn() and #KT.varsStack >= 1 then | |
316 while #KT.varsStack >= 1 do | |
317 local addon = tremove(KT.varsStack, 1) | |
318 print(addon:GetName()) | |
319 if addon.variables then | |
320 xpcall(addon.variables, LibKTError) | |
321 for i, module in ipairs(addon.modules) do | |
322 if module.variables then | |
323 xpcall(module.variables, LibKTError) | |
324 end | |
325 end | |
326 end | |
327 end | |
328 end | |
329 end | |
330 end | |
331 | |
332 KT.print = function(module, ...) | |
333 local msg = '|cFF00FFFF'..module:GetName()..'|r:' | |
334 for i = 1, select('#', ...) do | |
335 msg = msg .. ' ' .. tostring(select(i, ...)) | |
336 end | |
337 DEFAULT_CHAT_FRAME:AddMessage(msg) | |
338 end | |
339 | |
340 --- Button generators | |
341 | |
342 local GetButtonTemplate = function(name, parent, template, onClick) | |
343 if _G[name] then | |
344 return _G[name] | |
345 end | |
346 | |
347 local button = CreateFrame('Button', name, parent, template) | |
348 button:RegisterForClicks('AnyUp') | |
349 button:SetScript('OnClick', onClick) | |
350 return button | |
351 end | |
352 | |
353 local SetButtonAnchor = function(self, collector, anchor, growth) | |
354 if self:GetID() == 0 then | |
355 self:SetID(#collector) | |
356 print('registered TabButton #', self:GetID()) | |
357 end | |
358 | |
359 if self:GetID() == 1 then | |
360 self:SetPoint(unpack(anchor)) | |
361 else | |
362 growth[2] = collector[self:GetID()-1] | |
363 self:SetPoint(unpack(growth)) | |
364 end | |
365 end | |
366 | |
367 KT.tab = function(self, name, tooltip, texture, coords) | |
368 local button = GetButtonTemplate(name, self, 'KTTabButton', self.SelectTab) | |
369 button.icon:SetTexture(texture) | |
370 button.tooltip = tooltip | |
371 button:SetSize(unpack(self.tabSize)) | |
372 if coords then | |
373 button.icon:SetTexCoord(unpack(coords)) | |
374 end | |
375 SetButtonAnchor(button, self.tabButtons, self.tabAnchor, self.tabGrowth) | |
376 return button | |
377 end | |
378 | |
379 KT.button = function(self, name, text, tooltip, onClick) | |
380 local button = GetButtonTemplate(name, self, 'KTButton', onClick) | |
381 | |
382 button.tooltip = tooltip | |
383 button:SetText(text) | |
384 button:SetWidth(max(button:GetWidth(), button:GetFontString():GetStringWidth() + 12)) | |
385 | |
386 SetButtonAnchor(button, self.controls, self.controlsAnchor, self.controlsGrowth) | |
387 return button | |
388 end | |
389 | |
390 KT.uibutton = function(self, name, text, tooltip, onClick, texture, coords) | |
391 local button = GetButtonTemplate(name, self, 'KTUIPanelButton', onClick) | |
392 | |
393 button.tooltip = tooltip | |
394 button:SetText(text) | |
395 | |
396 if self.UIPanelIcon then | |
397 local w, h, anchor, x, y = unpack(self.UIPanelIcon) | |
398 button.icon:SetTexture(texture) | |
399 button.icon:SetSize(w, h) | |
400 button.icon:ClearAllPoints() | |
401 button.icon:SetPoint(anchor, button, anchor, x, y) | |
402 end | |
403 | |
404 if not self.UIPanelSize then | |
405 button:SetWidth(button:GetFontString():GetStringWidth() + button.icon:GetWidth()/1.5) | |
406 else | |
407 button:SetSize(unpack(self.UIPanelSize)) | |
408 end | |
409 if coords then | |
410 button.icon:SetTexCoord(unpack(coords)) | |
411 end | |
412 SetButtonAnchor(button, self.UIPanels, self.UIPanelAnchor, self.UIPanelGrowth) | |
413 return button | |
414 end | |
415 | |
416 --- Co-routine Handler kajigger | |
417 do | |
418 local tickerQueue = {} | |
419 local ticker | |
420 local instant = false | |
421 KT.tick = function() | |
422 | |
423 if #tickerQueue == 0 then | |
424 ticker:Cancel() | |
425 ticker = nil | |
426 end | |
427 local func = tremove(tickerQueue, 1) | |
428 if func then | |
429 --print('#', #tickerQueue) | |
430 func() | |
431 end | |
432 end | |
433 | |
434 KT.wrap = function(f) | |
435 if not ticker then | |
436 --print('create ticker') | |
437 ticker = C_Timer.NewTicker(.001, KT.tick) | |
438 end | |
439 tinsert(tickerQueue, f) | |
440 | |
441 return #tickerQueue | |
442 | |
443 end | |
444 end | 438 end |
445 | 439 |
446 KT.handler:RegisterEvent('ADDON_LOADED') | 440 KT.handler:RegisterEvent('ADDON_LOADED') |
447 KT.handler:RegisterEvent('PLAYER_LOGIN') | 441 KT.handler:RegisterEvent('PLAYER_LOGIN') |
448 KT.handler:SetScript('OnEvent', onEvent) | 442 KT.handler:SetScript('OnEvent', LibKT_OnEvent) |