Do I continue like this? or just integrate the mdb runner itself into luadebug?
121 lines
2.5 KiB
Lua
121 lines
2.5 KiB
Lua
local core = require "core"
|
|
local process = require "process"
|
|
|
|
-- tiny helpers
|
|
local function join(a, b) return (a:sub(-1) == "/" and a or (a .. "/")) .. b end
|
|
|
|
---@class mdb
|
|
local mdb = {
|
|
proc = nil, ---@type process|nil
|
|
state = 'idle',
|
|
}
|
|
|
|
---@meta
|
|
function mdb.log(msg) end
|
|
---@meta
|
|
function mdb.error(msg) end
|
|
---@meta
|
|
function mdb.on_connected() end
|
|
---@meta
|
|
function mdb.on_pause(file, line) end
|
|
|
|
function mdb:new(o)
|
|
o = o or {}
|
|
setmetatable(o, self)
|
|
self.__index = self
|
|
return o
|
|
end
|
|
|
|
function mdb:set_state(newstate)
|
|
self.state = newstate
|
|
end
|
|
|
|
function mdb:parse_line(line)
|
|
self.log('mdb> '..line)
|
|
local words = {}
|
|
for w in line:gmatch("%w+") do table.insert(words, w) end
|
|
|
|
if words[1] == 'Paused' then
|
|
-- Breakpoint hit
|
|
if #words ~= 7 then return end
|
|
local file = words[4]
|
|
local linenr = tonumber(words[7])
|
|
self:set_state("paused")
|
|
core.add_thread(function() self.on_pause(file, linenr) end)
|
|
elseif words[1] == "Type" then
|
|
-- mobdebug started
|
|
self:set_state("paused")
|
|
core.add_thread(function() self.on_connected() end)
|
|
end
|
|
end
|
|
|
|
function mdb:spawn(lua, root)
|
|
local vendor_glob = join(root, "vendor/?.lua")
|
|
|
|
local cmd = {}
|
|
if type(lua) == "table" then
|
|
for i=1, #lua do table.insert(cmd, lua[i]) end
|
|
else
|
|
table.insert(cmd, lua)
|
|
end
|
|
table.insert(cmd, "-e")
|
|
table.insert(cmd, string.format([[
|
|
package.path = %q .. ";" .. package.path
|
|
require("mobdebug").listen()
|
|
]], vendor_glob))
|
|
|
|
self:set_state('spawning')
|
|
|
|
local proc = process.start(cmd, {
|
|
stdout = process.REDIRECT_PIPE,
|
|
stderr = process.REDIRECT_PIPE,
|
|
})
|
|
self.proc = proc
|
|
|
|
self:set_state('connecting')
|
|
|
|
core.add_thread(function()
|
|
while true do
|
|
core.redraw = true
|
|
coroutine.yield(0.016) -- 60FPS
|
|
local sout = self.proc:read_stdout()
|
|
local serr = self.proc:read_stderr()
|
|
if sout == nil and serr == nil then
|
|
-- mdb exited
|
|
break
|
|
end
|
|
if sout and sout~="" then
|
|
for l in string.gmatch(sout, "([^\n]+)") do
|
|
self:parse_line(l)
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
function mdb:cmd(c)
|
|
-- commands are only possible when mdb is paused
|
|
if self.state == "paused" then
|
|
self.log('>>>'..c)
|
|
self.proc:write(c..'\n')
|
|
else
|
|
self.error('mdb not paused')
|
|
end
|
|
end
|
|
|
|
function mdb:run()
|
|
self:cmd("run")
|
|
end
|
|
|
|
function mdb:setb(file, line)
|
|
self:cmd(string.format("setb %s %d", file, line))
|
|
end
|
|
|
|
function mdb:kill()
|
|
self.proc:kill()
|
|
self.proc:kill()
|
|
end
|
|
|
|
return mdb
|
|
|