123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- local common = {}
- function common.is_utf8_cont(char)
- local byte = char:byte()
- return byte >= 0x80 and byte < 0xc0
- end
- function common.utf8_chars(text)
- return text:gmatch("[\0-\x7f\xc2-\xf4][\x80-\xbf]*")
- end
- function common.clamp(n, lo, hi)
- return math.max(math.min(n, hi), lo)
- end
- function common.round(n)
- return n >= 0 and math.floor(n + 0.5) or math.ceil(n - 0.5)
- end
- function common.lerp(a, b, t)
- if type(a) ~= "table" then
- return a + (b - a) * t
- end
- local res = {}
- for k, v in pairs(b) do
- res[k] = common.lerp(a[k], v, t)
- end
- return res
- end
- function common.color(str)
- local r, g, b, a = str:match("#(%x%x)(%x%x)(%x%x)")
- if r then
- r = tonumber(r, 16)
- g = tonumber(g, 16)
- b = tonumber(b, 16)
- a = 1
- elseif str:match("rgba?%s*%([%d%s%.,]+%)") then
- local f = str:gmatch("[%d.]+")
- r = (f() or 0)
- g = (f() or 0)
- b = (f() or 0)
- a = f() or 1
- else
- error(string.format("bad color string '%s'", str))
- end
- return r, g, b, a * 0xff
- end
- local function compare_score(a, b)
- return a.score > b.score
- end
- local function fuzzy_match_items(items, needle)
- local res = {}
- for i, item in ipairs(items) do
- local score = system.fuzzy_match(tostring(item), needle)
- if score then
- table.insert(res, { text = item, score = score })
- end
- end
- table.sort(res, compare_score)
- for i, item in ipairs(res) do
- res[i] = item.text
- end
- return res
- end
- function common.fuzzy_match(haystack, needle)
- if type(haystack) == "table" then
- return fuzzy_match_items(haystack, needle)
- end
- return system.fuzzy_match(haystack, needle)
- end
- function common.path_suggest(text)
- local path, name = text:match("^(.-)([^/\\]*)$")
- local ok, files = pcall(system.list_dir, path == "" and "." or path)
- if not ok then return {} end
- local res = {}
- for _, file in ipairs(files) do
- file = path .. file
- local info = system.get_file_info(file)
- if info then
- if info.type == "dir" then
- file = file .. _PATHSEP
- end
- if file:lower():find(text:lower(), nil, true) == 1 then
- table.insert(res, file)
- end
- end
- end
- return res
- end
- function common.draw_text(font, color, text, align, x,y,w,h)
- local tw, th = font:get_width(text), font:get_height(text)
- if align == "center" then
- x = x + (w - tw) / 2
- elseif align == "right" then
- x = x + (w - tw)
- end
- y = math.ceil(y + (h - th) / 2)
- return renderer.draw_text(font, text, x, y, color), y + th
- end
- function common.bench(name, fn, ...)
- local start = system.get_time()
- local res = fn(...)
- local t = system.get_time() - start
- local ms = t * 1000
- local per = (t / (1 / 60)) * 100
- print(string.format("*** %-16s : %8.3fms %6.2f%%", name, ms, per))
- return res
- end
- return common
|