vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 
2 -- Add the module to the tree
3 local mod = klhtm
4 local me = {}
5 mod.out = me
6  
7 --[[
8 Output.lua. These comments last updated R17.8.
9  
10 This module controls printing. For a normal print to the user that will always occur, call mod.out.print(<message>).
11 The second part of this module is trace printing. This is a printout that assists with debugging, which you might not want most users to see. The module provides methods to determine which debug prints should be sent to the user. Then to make a debug print, first call mod.out.checktrace(). If it returns non-nil, call mod.out.printtrace() with the actual message.
12 Defaults are set by <me.default> around line 27, overrides are set by <me.setprintstatus()> calls around line 128.
13 ]]
14  
15 --[[
16 --------------------------------------------------------------------------
17 Trace Printing for Debugging or Extra Information
18 --------------------------------------------------------------------------
19  
20 The idea of this section is to provide a detailed method to evaluate whether a specific trace message should be printed. We have a few data structures that are print options of the form "if the print is <x>, do / dont print it".
21 The more specific a print option is, the higher the priority it has. So the defaults, which just say "always print on <error>" or "never print on <info>" are the least specific and will be overridden by <me.setprintstatus>.
22 For a release version, it is sufficient to set "error" = true, and the rest = "false", but for a debug version, you might only want to focus on specific sections of code for trace prints.
23  
24 ]]
25  
26 -- These are default printing options. For a release version, error only. For a debug version, maybe warnings too.
27 me.default =
28 {
29 info = false,
30 warning = false,
31 error = true,
32 }
33  
34 me.onload = function()
35  
36 -- optional debug specification
37  
38 --me.setprintstatus("boss", nil, "info", true)
39 --me.setprintstatus("boss", "target", "info", false)
40  
41 end
42  
43 --[[
44 Suppose the following method calls were made:
45 me.setprintstatus("boss", nil, "warning", true)
46 me.setprintstatus("boss", "event", "info", true)
47  
48 Then me.override would look like
49 me.override =
50 {
51 boss =
52 {
53 warning = true
54 error = true
55 sections =
56 {
57 event =
58 {
59 info = true
60 warning = true
61 error = true
62 }
63 }
64 }
65 }
66  
67 See <me.setprintstatus> for more information
68 ]]
69 me.override = { }
70  
71 --[[
72 me.setprintstatus(modulename, sectionname, messagetype, value)
73 Overrides the default print option for a specific trace print.
74 <modulename> is a string, the source of the print, e.g. "out" for this module.
75 <sectionname> is a string, a feature in the source module. e.g. "trace" for this section.
76 <messagetype> is either "info" or "warning" or "error".
77 <value> is a boolean, true to enable the print, false to disable it.
78  
79 <sectionname> is an optional parameter. If it is nil, the override will apply to the whole module, but it is now less specific, so an individual section inside that module may be overriden again.
80 <messagetype> will automatically cascade. "error" is assumed to be more important than "warning", which is more important than "info". So if you turn "warning" off, it will turn "info off as well"; if you turn "info" on, "warning" and "error" will be turned on too.
81 ]]
82 me.setprintstatus = function(modulename, sectionname, messagetype, value)
83  
84 -- check module exists
85 if me.override[modulename] == nil then
86 me.override[modulename] = { }
87 end
88  
89 local printdata = me.override[modulename]
90  
91 -- is this for the whole module, or more specific?
92 if sectionname then
93  
94 -- check whether any sections have been defined for this module
95 if printdata.sections == nil then
96 printdata.sections = { }
97 end
98  
99 printdata = printdata.sections
100  
101 -- check whether this section has been defined in the sections list
102 if printdata[sectionname] == nil then
103 printdata[sectionname] = { }
104 end
105  
106 printdata = printdata[sectionname]
107 end
108  
109 -- set
110 printdata[messagetype] = value
111  
112 -- cascade
113 if value == true then
114 if messagetype == "info" then
115 printdata.warning = true
116 messagetype = "warning"
117 end
118  
119 if messagetype == "warning" then
120 printdata.error = true
121 end
122  
123 elseif value == false then
124 if messagetype == "error" then
125 printdata.warning = false
126 messagetype = "warning"
127 end
128  
129 if messagetype == "warning" then
130 printdata.info = false
131 end
132 end
133  
134 end
135  
136  
137  
138 --[[
139 This is a reverse lookup of the top level of the list <mod>. <mod> has keys that are strings like "out", and values that are modules (lists), like <me>. <me.modulelookup> reverses this, giving us the name of a module from a reference to it.
140 Calls to <me.checktrace> supply a module reference and we might like to name the module. However we wouldn't want to search for the module name every time that method is called, since we want it in particular to be fast.
141 We don't fill me.modulelookup at runtime, but each time <me.checktrace> is called with a <module> parameter that is not a key to <me.modulelookup>, we will search to find that module.
142 ]]
143 me.modulelookup = { }
144  
145 --[[
146 me.getmodulename(module)
147 Given a reference to a module (subtree of <local mod>), returns the name, which is the key in <mod> of the module.
148 ]]
149 me.getmodulename = function(module)
150  
151 -- have we already found this module before?
152 local try = me.modulelookup[module]
153 if try then
154 return try
155 end
156  
157 -- manual search
158 local key, value
159  
160 for key, value in mod do
161 if value == module then
162 me.modulelookup[module] = key
163 return key
164 end
165 end
166  
167 return "unknown"
168  
169 end
170  
171 --[[
172 mod.out.checktrace(messagetype, module, sectionname)
173 Checks whether a debug print with the given properties should be printed.
174 Return: non-nil iff the message should be printed.
175 <messagetype> must be one of "error", "warning" or "info"
176 <module> should always be <me> in the calling context
177 <sectionname> is a description of the feature in <module> that the message concerns.
178 ]]
179 me.checktrace = function(messagetype, module, sectionname)
180  
181 -- start with default print value
182 local value = me.default[messagetype]
183 me.printargs.overridelevel = "default"
184  
185 -- convert module reference to name
186 local modulename = me.getmodulename(module)
187  
188 -- are there any overrides for that module?
189 local printdata = me.override[modulename]
190  
191 if printdata then
192 if printdata[messagetype] then
193 value = printdata[messagetype]
194 me.printargs.overridelevel = "module"
195 end
196  
197 -- are there overrides for this section of the module?
198 if printdata.sections and printdata.sections[sectionname] and (printdata.sections[sectionname][messagetype] ~= nil) then
199 value = printdata.sections[sectionname][messagetype]
200 me.printargs.overridelevel = "section"
201 end
202 end
203  
204 -- pre-return: load arguments for me.printtrace
205 me.printargs.modulename = modulename
206 me.printargs.sectionname = sectionname
207 me.printargs.messagetype = messagetype
208  
209 -- return: nil or non-nil
210 if value == true then
211 return true
212 end
213  
214 end
215  
216 -- This stores the options supplied to <me.checktrace>, which will slightly affect the printout.
217 me.printargs =
218 {
219 messagetype = "",
220 modulename = "",
221 sectionname = "",
222 overridelevel = "",
223 }
224  
225 --[[
226 mod.out.printtrace(message)
227 Prints a message that has been OK'd by <me.checktrace>.
228 ]]
229 me.printtrace = function(message)
230  
231 -- setup the colour. Error = red, warning = yellow, info = blue. Lightish colours.
232 local header = ""
233  
234 if me.printargs.messagetype == "info" then
235 header = "|cff8888ff"
236  
237 elseif me.printargs.messagetype == "warning" then
238 header = "|cffffff44"
239  
240 elseif me.printargs.messagetype == "error" then
241 header = "|cffff8888"
242 end
243  
244 header = header .. "<" .. me.printargs.modulename .. "." .. me.printargs.sectionname .. "> "
245  
246 -- print!
247 me.print(header .. message)
248  
249 end
250  
251  
252 --[[
253 ----------------------------------------------------------------------
254 Normal Printing to the Console
255 ----------------------------------------------------------------------
256 ]]
257  
258 --[[
259 mod.out.print(message, [chatframeindex, noheader])
260 Prints out <message> to chat.
261 To print to ChatFrame3, set <chatframeindex> to 3, etc.
262 Adds a header "KTM: " to the message, unless <noheader> is non-nil.
263 ]]
264 me.print = function(message, chatframeindex, noheader)
265  
266 -- Get a Frame to write to
267 local chatframe
268  
269 if chatframeindex == nil then
270 chatframe = DEFAULT_CHAT_FRAME
271  
272 else
273 chatframe = getglobal("ChatFrame" .. chatframeindex)
274  
275 if chatframe == nil then
276 chatframe = DEFAULT_CHAT_FRAME
277 end
278 end
279  
280 -- touch up message
281 message = message or "<nil>"
282  
283 if noheader == nil then
284 message = "KTM: " .. message
285 end
286  
287 -- write
288 chatframe:AddMessage(message)
289  
290 end
291  
292 --[[
293 mod.out.booltostring(boolean)
294 Converts a Boolean value (true or false) to a string representation.
295 true -> "true", false -> "false", nil -> "nil"
296 ]]
297 me.booltostring = function(boolean)
298  
299 if boolean == true then
300 return "true"
301 elseif boolean == false then
302 return "false"
303 else
304 return "nil"
305 end
306  
307 end
308  
309 --[[
310 mod.out.announce(message)
311 Sends a chat message to Raid if possible, or Party if possible, or finally Say.
312 ]]
313 me.announce = function(message)
314  
315 local channel = "SAY"
316  
317 if GetNumRaidMembers() > 0 then
318 channel = "RAID"
319  
320 elseif GetNumPartyMembers() > 0 then
321 channel = "PARTY"
322 end
323  
324 SendChatMessage(message, channel)
325  
326 end