common.lua 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. local common = {}
  2. function common.is_utf8_cont(char)
  3. local byte = char:byte()
  4. return byte >= 0x80 and byte < 0xc0
  5. end
  6. function common.utf8_chars(text)
  7. return text:gmatch("[\0-\x7f\xc2-\xf4][\x80-\xbf]*")
  8. end
  9. function common.clamp(n, lo, hi)
  10. return math.max(math.min(n, hi), lo)
  11. end
  12. function common.round(n)
  13. return n >= 0 and math.floor(n + 0.5) or math.ceil(n - 0.5)
  14. end
  15. function common.lerp(a, b, t)
  16. if type(a) ~= "table" then
  17. return a + (b - a) * t
  18. end
  19. local res = {}
  20. for k, v in pairs(b) do
  21. res[k] = common.lerp(a[k], v, t)
  22. end
  23. return res
  24. end
  25. function common.color(str)
  26. local r, g, b, a = str:match("#(%x%x)(%x%x)(%x%x)")
  27. if r then
  28. r = tonumber(r, 16)
  29. g = tonumber(g, 16)
  30. b = tonumber(b, 16)
  31. a = 1
  32. elseif str:match("rgba?%s*%([%d%s%.,]+%)") then
  33. local f = str:gmatch("[%d.]+")
  34. r = (f() or 0)
  35. g = (f() or 0)
  36. b = (f() or 0)
  37. a = f() or 1
  38. else
  39. error(string.format("bad color string '%s'", str))
  40. end
  41. return r, g, b, a * 0xff
  42. end
  43. local function compare_score(a, b)
  44. return a.score > b.score
  45. end
  46. local function fuzzy_match_items(items, needle)
  47. local res = {}
  48. for i, item in ipairs(items) do
  49. local score = system.fuzzy_match(tostring(item), needle)
  50. if score then
  51. table.insert(res, { text = item, score = score })
  52. end
  53. end
  54. table.sort(res, compare_score)
  55. for i, item in ipairs(res) do
  56. res[i] = item.text
  57. end
  58. return res
  59. end
  60. function common.fuzzy_match(haystack, needle)
  61. if type(haystack) == "table" then
  62. return fuzzy_match_items(haystack, needle)
  63. end
  64. return system.fuzzy_match(haystack, needle)
  65. end
  66. function common.path_suggest(text)
  67. local path, name = text:match("^(.-)([^/\\]*)$")
  68. local ok, files = pcall(system.list_dir, path == "" and "." or path)
  69. if not ok then return {} end
  70. local res = {}
  71. for _, file in ipairs(files) do
  72. file = path .. file
  73. local info = system.get_file_info(file)
  74. if info then
  75. if info.type == "dir" then
  76. file = file .. _PATHSEP
  77. end
  78. if file:lower():find(text:lower(), nil, true) == 1 then
  79. table.insert(res, file)
  80. end
  81. end
  82. end
  83. return res
  84. end
  85. function common.draw_text(font, color, text, align, x,y,w,h)
  86. local tw, th = font:get_width(text), font:get_height(text)
  87. if align == "center" then
  88. x = x + (w - tw) / 2
  89. elseif align == "right" then
  90. x = x + (w - tw)
  91. end
  92. y = math.ceil(y + (h - th) / 2)
  93. return renderer.draw_text(font, text, x, y, color), y + th
  94. end
  95. function common.bench(name, fn, ...)
  96. local start = system.get_time()
  97. local res = fn(...)
  98. local t = system.get_time() - start
  99. local ms = t * 1000
  100. local per = (t / (1 / 60)) * 100
  101. print(string.format("*** %-16s : %8.3fms %6.2f%%", name, ms, per))
  102. return res
  103. end
  104. return common