init.lua 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. local class = require("class")
  2. local DebugWindow = require("debug_overlay.debugwindow")
  3. require "imgui"
  4. local commands = require("debug_overlay.console.commands")
  5. local Console = class(DebugWindow)
  6. local INFO = 1
  7. local DEBUG = 2
  8. local LOG = 3
  9. local WARN = 4
  10. local ERROR = 5
  11. local function bind(new_self, fun, ...)
  12. return function(...)
  13. fun(new_self, ...)
  14. end
  15. end
  16. local function splitArgs(text)
  17. local result = {}
  18. local e = 0
  19. while true do
  20. local b = e+1
  21. b = text:find("%S",b)
  22. if b==nil then break end
  23. if text:sub(b,b)=="'" then
  24. e = text:find("'",b+1)
  25. b = b+1
  26. elseif text:sub(b,b)=='"' then
  27. e = text:find('"',b+1)
  28. b = b+1
  29. else
  30. e = text:find("%s",b+1)
  31. end
  32. if e==nil then e=#text+1 end
  33. result[#result+1] = text:sub(b,e-1)
  34. end
  35. return result
  36. end
  37. function Console:init()
  38. self.shortcut = "f12"
  39. self.logs = {}
  40. self.logs_filter_toggles = {}
  41. self.visible = false;
  42. self.input_text = "";
  43. self.commands = {}
  44. self.command_helps = {}
  45. self.take_focus = false
  46. self.scroll_to_bottom = true
  47. for i=1,5 do
  48. self.logs_filter_toggles[i] = true
  49. end
  50. for i,v in pairs(commands) do
  51. self:registerCommand(i, bind(self, commands[i].fun), v.help)
  52. end
  53. end
  54. function Console:render()
  55. imgui.SetNextWindowPos(0, love.graphics.getHeight() - 200, 1);
  56. imgui.SetNextWindowSize(love.graphics.getWidth(), 200);
  57. imgui.Begin("Console", nil, {"NoCollapse", "NoResize", "NoMove", "NoTitleBar"})
  58. if imgui.Button("Bottom") then self.scroll_to_bottom = true end
  59. for k,v in ipairs({"Info", "Debug", "Log", "Warn", "Error"}) do
  60. imgui.SameLine()
  61. if imgui.Checkbox(v, self.logs_filter_toggles[k]) then
  62. self.logs_filter_toggles[k] = not self.logs_filter_toggles[k]
  63. end
  64. end
  65. imgui.BeginChild("Console log", 0,-imgui.GetItemsLineHeightWithSpacing())
  66. for k,l in ipairs(self.logs) do
  67. local color = 0xFFFFFF
  68. if self.logs_filter_toggles[l.level] then
  69. if l.level == 1 then
  70. imgui.PushStyleColor("Text", 0.6,0.6,0.6,1)
  71. elseif l.level == 2 then
  72. imgui.PushStyleColor("Text", 0.4,0.4,0.6,1)
  73. elseif l.level == 3 then
  74. imgui.PushStyleColor("Text", 1,1,1,1)
  75. elseif l.level == 4 then
  76. imgui.PushStyleColor("Text", 1,1,0,1)
  77. elseif l.level == 5 then
  78. imgui.PushStyleColor("Text", 1,0.2,0.2,1)
  79. end
  80. imgui.TextUnformatted(l.msg)
  81. imgui.PopStyleColor(1)
  82. end
  83. end
  84. if self.scroll_to_bottom then
  85. imgui.SetScrollHere();
  86. self.scroll_to_bottom = false;
  87. end
  88. imgui.EndChild()
  89. local status = false
  90. imgui.PushItemWidth(imgui.GetContentRegionAvailWidth())
  91. status, self.input_text = imgui.InputText("", self.input_text, 256, {"EnterReturnsTrue"})
  92. imgui.PopItemWidth()
  93. if self.take_focus then
  94. imgui.SetKeyboardFocusHere(0)
  95. self.take_focus = false
  96. end
  97. if status then
  98. if self.input_text == "" then return end
  99. local command_line = self.input_text
  100. local parts = splitArgs(command_line)
  101. local args = {}
  102. for i=2,#parts do
  103. args[i-1] = parts[i]
  104. end
  105. self:log("> "..self.input_text, 1)
  106. local fun_name = parts[1]:lower()
  107. local command = self.commands[fun_name]
  108. if not command then
  109. self:log("Command not found : "..fun_name, ERROR)
  110. else
  111. local processed_commands = {}
  112. local f = function()
  113. command(unpack(args))
  114. end
  115. local success, result = xpcall(f, function(err) return debug.traceback(err) end)
  116. if not success then
  117. self:log(result, ERROR)
  118. end
  119. end
  120. self.input_text = ""
  121. self.take_focus = true
  122. end
  123. imgui.End()
  124. end
  125. function Console:toggle()
  126. DebugWindow.toggle(self)
  127. if self.visible then
  128. self.take_focus = true
  129. end
  130. end
  131. function Console:log(str, level)
  132. self.logs[#self.logs + 1] = {
  133. msg = str,
  134. level = level or 3
  135. }
  136. self.scroll_to_bottom = true
  137. end
  138. function Console:info(str)
  139. self:log(str, INFO)
  140. end
  141. function Console:warn(str)
  142. self:log(str, WARN)
  143. end
  144. function Console:debug(str)
  145. self:log(str, DEBUG)
  146. end
  147. function Console:error(str)
  148. self:log(str, ERROR)
  149. end
  150. function Console:registerCommand(name, fun, help)
  151. self.commands[name] = fun
  152. if help then
  153. self.command_helps[name] = help
  154. end
  155. end
  156. return Console