local core = require "core" ---@class runner local runner = { new = function(self, o) o = o or {} setmetatable(o, self) self.__index = self return o end, caps = { can_pause = false, can_continue = false, can_step_in = false, can_step_over = false, can_step_out = false, can_breakpoints = false, has_stack = false, has_locals = false, can_eval = false, }, run = function(self, target, name) end, ---@meta pause = function(self) end, --@meta continue = function(self) end, --@meta step_in = function(self) end, --@meta step_over = function(self) end, --@meta step_out = function(self) end, --@meta wait = function(self, time) end, ---@meta kill = function(self) end, ---@meta terminate = function(self) end, ---@meta -- Callbacks log = function(msg) end, ---@meta error = function(msg) end, ---@meta on_stdout = function(msg) end, ---@meta on_stderr = function(msg) end, ---@meta on_exit = function(exitcode) end, ---@meta on_state = function(state) end, ---@meta on_break = function(file, line, reason) end, --@meta on_stack = function(frames) end, ---@meta on_locals = function(frame, vars) end, ---@meta on_evaluated = function(expr, ok, value) end, ---@meta } local debugger = { runner = runner, -- Set here as member to let runners extend this base class debugwindow = nil, ---@type JPDebugView debugrunner = nil, ---@type runner|nil } function debugger.log(msg) core.log("[jpdebug][debugger] %s", msg) if debugger.debugwindow then debugger.debugwindow:push("meta", "debugger] "..msg) end end function debugger.error(msg) core.error("[jpdebug][debugger]"..msg) if debugger.debugwindow then debugger.debugwindow:push("meta", "debugger] ERROR: "..msg) end end function debugger.on_stdout(msg) if debugger.debugwindow then debugger.debugwindow:push("stdout", msg) end end function debugger.on_stderr(msg) if debugger.debugwindow then debugger.debugwindow:push("stderr", msg) end end function debugger.is_running() return debugger.debugrunner~=nil end function debugger.run(target, name, r, view) if debugger.debugrunner then debugger.error("Already an active session") return end debugger.debugwindow = view debugger.debugwindow:clear() debugger.log(string.format("Running %s", name)) -- Create new runner object debugger.debugrunner = r:new({ -- Set callbacks log = debugger.log, error = debugger.error, on_stdout = debugger.on_stdout, on_stderr = debugger.on_stderr, on_exit = debugger.on_exit, }) -- And run debugger.debugrunner:run(target, name) end function debugger.stop() if debugger.debugrunner then debugger.debugrunner.on_exit = function() end debugger.debugrunner:kill() local exitcode = debugger.debugrunner:wait(1000) -- TODO terminate if needed debugger.log(string.format("... Stoped with exit code %d", exitcode)) end debugger.debugrunner = nil end function debugger.on_exit(exitcode) debugger.log(string.format("exit: %d", exitcode)) debugger.debugrunner = nil end return debugger