util.lua

main 381 lines · 7.6 KB Raw
Alex Alex Commit Client Upload Part 2 19/10/2026 00:06
1-- @docfuncs @{
2function print(...)
3 local msg = ""
4 local args = { ... }
5 local appendSpace = #args > 1
6 for i,v in ipairs(args) do
7 msg = msg .. tostring(v)
8 if appendSpace and i < #args then
9 msg = msg .. ' '
10 end
11 end
12 g_logger.log(LogInfo, msg)
13end
14
15function pinfo(msg)
16 g_logger.log(LogInfo, msg)
17end
18
19function perror(msg)
20 g_logger.log(LogError, msg)
21end
22
23function pwarning(msg)
24 g_logger.log(LogWarning, msg)
25end
26
27function pdebug(msg)
28 g_logger.log(LogDebug, msg)
29end
30
31function fatal(msg)
32 g_logger.log(LogFatal, msg)
33end
34
35function exit()
36 g_app.exit()
37end
38
39function quit()
40 g_app.exit()
41end
42
43function connect(object, arg1, arg2, arg3)
44 if not object then
45 perror("connect: object is nil")
46 return
47 end
48 local signalsAndSlots
49 local pushFront
50 if type(arg1) == 'string' then
51 signalsAndSlots = { [arg1] = arg2 }
52 pushFront = arg3
53 else
54 signalsAndSlots = arg1
55 pushFront = arg2
56 end
57
58 for signal,slot in pairs(signalsAndSlots) do
59 if not object[signal] then
60 local mt = getmetatable(object)
61 if mt and type(object) == 'userdata' then
62 object[signal] = function(...)
63 return signalcall(mt[signal], ...)
64 end
65 end
66 end
67
68 if not object[signal] then
69 object[signal] = slot
70 elseif type(object[signal]) == 'function' then
71 object[signal] = { object[signal] }
72 end
73
74 if type(slot) ~= 'function' then
75 perror(debug.traceback('unable to connect a non function value'))
76 end
77
78 if type(object[signal]) == 'table' then
79 if pushFront then
80 table.insert(object[signal], 1, slot)
81 else
82 table.insert(object[signal], #object[signal]+1, slot)
83 end
84 end
85 end
86end
87
88function disconnect(object, arg1, arg2)
89 local signalsAndSlots
90 if type(arg1) == 'string' then
91 if arg2 == nil then
92 object[arg1] = nil
93 return
94 end
95 signalsAndSlots = { [arg1] = arg2 }
96 elseif type(arg1) == 'table' then
97 signalsAndSlots = arg1
98 else
99 return -- Evitamos error: unable to disconnect
100 end
101
102 for signal,slot in pairs(signalsAndSlots) do
103 if not object[signal] then
104 elseif type(object[signal]) == 'function' then
105 if object[signal] == slot then
106 object[signal] = nil
107 end
108 elseif type(object[signal]) == 'table' then
109 for k,func in pairs(object[signal]) do
110 if func == slot then
111 table.remove(object[signal], k)
112
113 if #object[signal] == 1 then
114 object[signal] = object[signal][1]
115 end
116 break
117 end
118 end
119 end
120 end
121end
122
123function newclass(name)
124 if not name then
125 perror(debug.traceback('new class has no name.'))
126 end
127
128 local class = {}
129 function class.internalCreate()
130 local instance = {}
131 for k,v in pairs(class) do
132 instance[k] = v
133 end
134 return instance
135 end
136
137 class.create = class.internalCreate
138 class.__class = name
139 class.getClassName = function() return name end
140 return class
141end
142
143function extends(base, name)
144 if not name then
145 perror(debug.traceback('extended class has no name.'))
146 end
147
148 local derived = {}
149 function derived.internalCreate()
150 local instance = base.create()
151 for k,v in pairs(derived) do
152 instance[k] = v
153 end
154 return instance
155 end
156
157 derived.create = derived.internalCreate
158 derived.__class = name
159 derived.getClassName = function() return name end
160 return derived
161end
162
163function runinsandbox(func, ...)
164 if type(func) == 'string' then
165 func, err = loadfile(resolvepath(func, 2))
166 if not func then
167 error(err)
168 end
169 end
170 local env = { }
171 local oldenv = getfenv(0)
172 setmetatable(env, { __index = oldenv } )
173 setfenv(0, env)
174 func(...)
175 setfenv(0, oldenv)
176 return env
177end
178
179function loadasmodule(name, file)
180 file = file or resolvepath(name, 2)
181 if package.loaded[name] then
182 return package.loaded[name]
183 end
184 local env = runinsandbox(file)
185 package.loaded[name] = env
186 return env
187end
188
189local function module_loader(modname)
190 local module = g_modules.getModule(modname)
191 if not module then
192 return '\n\tno module \'' .. modname .. '\''
193 end
194 return function()
195 if not module:load() then
196 error('unable to load required module ' .. modname)
197 end
198 return module:getSandbox()
199 end
200end
201table.insert(package.loaders, 1, module_loader)
202
203function import(table)
204 assert(type(table) == 'table')
205 local env = getfenv(2)
206 for k,v in pairs(table) do
207 env[k] = v
208 end
209end
210
211function export(what, key)
212 if key ~= nil then
213 _G[key] = what
214 else
215 for k,v in pairs(what) do
216 _G[k] = v
217 end
218 end
219end
220
221function unexport(key)
222 if type(key) == 'table' then
223 for _k,v in pairs(key) do
224 _G[v] = nil
225 end
226 else
227 _G[key] = nil
228 end
229end
230
231function getfsrcpath(depth)
232 depth = depth or 2
233 local info = debug.getinfo(1+depth, "Sn")
234 local path
235 if info.short_src then
236 path = info.short_src:match("(.*)/.*")
237 end
238 if not path then
239 path = '/'
240 elseif path:sub(0, 1) ~= '/' then
241 path = '/' .. path
242 end
243 return path
244end
245
246function resolvepath(filePath, depth)
247 if not filePath then return nil end
248 depth = depth or 1
249 if filePath then
250 if filePath:sub(0, 1) ~= '/' then
251 local basepath = getfsrcpath(depth+1)
252 if basepath:sub(#basepath) ~= '/' then basepath = basepath .. '/' end
253 return basepath .. filePath
254 else
255 return filePath
256 end
257 else
258 local basepath = getfsrcpath(depth+1)
259 if basepath:sub(#basepath) ~= '/' then basepath = basepath .. '/' end
260 return basepath
261 end
262end
263
264function toboolean(v)
265 if type(v) == 'string' then
266 v = v:trim():lower()
267 if v == '1' or v == 'true' then
268 return true
269 end
270 elseif type(v) == 'number' then
271 if v == 1 then
272 return true
273 end
274 elseif type(v) == 'boolean' then
275 return v
276 end
277 return false
278end
279
280function fromboolean(boolean)
281 if boolean then
282 return 'true'
283 else
284 return 'false'
285 end
286end
287
288function booleantonumber(boolean)
289 if boolean then
290 return 1
291 else
292 return 0
293 end
294end
295
296function numbertoboolean(number)
297 if number ~= 0 then
298 return true
299 else
300 return false
301 end
302end
303
304function protectedcall(func, ...)
305 local status, ret = pcall(func, ...)
306 if status then
307 return ret
308 end
309
310 perror(ret)
311 return false
312end
313
314function signalcall(param, ...)
315 if type(param) == 'function' then
316 local status, ret = pcall(param, ...)
317 if status then
318 return ret
319 else
320 perror(ret)
321 end
322 elseif type(param) == 'table' then
323 for k,v in pairs(param) do
324 local status, ret = pcall(v, ...)
325 if status then
326 if ret then return true end
327 else
328 perror(ret)
329 end
330 end
331 elseif param ~= nil then
332 error('attempt to call a non function value')
333 end
334 return false
335end
336
337function tr(s, ...)
338 return string.format(s, ...)
339end
340
341function getOppositeAnchor(anchor)
342 if anchor == AnchorLeft then
343 return AnchorRight
344 elseif anchor == AnchorRight then
345 return AnchorLeft
346 elseif anchor == AnchorTop then
347 return AnchorBottom
348 elseif anchor == AnchorBottom then
349 return AnchorTop
350 elseif anchor == AnchorVerticalCenter then
351 return AnchorHorizontalCenter
352 elseif anchor == AnchorHorizontalCenter then
353 return AnchorVerticalCenter
354 end
355 return anchor
356end
357
358function makesingleton(obj)
359 local singleton = {}
360 if obj.getClassName then
361 for key,value in pairs(_G[obj:getClassName()]) do
362 if type(value) == 'function' then
363 singleton[key] = function(...) return value(obj, ...) end
364 end
365 end
366 end
367 return singleton
368end
369
370function comma_value(amount)
371 local formatted = amount
372 while true do
373 formatted, k = string.gsub(formatted, "^(-?%d+)(%d%d%d)", '%1,%2')
374 if (k==0) then
375 break
376 end
377 end
378 return formatted
379end
380
381-- @}
Top