Merge remote-tracking branch 'remotes/onefifth/master'
This commit is contained in:
commit
071bc6d9e1
@ -1,3 +1,7 @@
|
|||||||
|
### NOTE
|
||||||
|
This is a modified fork of the [original GRLD project](https://github.com/neuoy/GRLD/master/) for personal use and should be considered **unstable**. Anyone looking to use GRLD should check out the [official repo](https://github.com/neuoy/GRLD/master/) unless they are specifically looking for the modifications provided in this version. The original readme contents remain below.
|
||||||
|
|
||||||
|
|
||||||
# GRLD
|
# GRLD
|
||||||
Graphical Remote Lua Debugger, a debugger for the lua programming language
|
Graphical Remote Lua Debugger, a debugger for the lua programming language
|
||||||
|
|
||||||
|
@ -57,16 +57,22 @@ end
|
|||||||
function meta.__index:init()
|
function meta.__index:init()
|
||||||
self.frame = wx.wxFrame( wx.NULL, wx.wxID_ANY, "GRLD server", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxDEFAULT_FRAME_STYLE + wx.wxMAXIMIZE)
|
self.frame = wx.wxFrame( wx.NULL, wx.wxID_ANY, "GRLD server", wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxDEFAULT_FRAME_STYLE + wx.wxMAXIMIZE)
|
||||||
mainthread.init( self.frame )
|
mainthread.init( self.frame )
|
||||||
|
|
||||||
self:initLayout_()
|
self:initLayout_()
|
||||||
|
|
||||||
self.mountPathPopup = ui.promptMountPath.new()
|
self.mountPathPopup = ui.promptMountPath.new()
|
||||||
self.notificationPopup = ui.notification.new()
|
self.notificationPopup = ui.notification.new()
|
||||||
|
|
||||||
self.idleUpdates = {}
|
self.idleUpdates = {}
|
||||||
self.frame:Connect( wx.wxEVT_IDLE, function( event ) self:onIdleUpdate_( event ) end )
|
self.frame:Connect( wx.wxEVT_IDLE, function( event ) self:onIdleUpdate_( event ) end )
|
||||||
|
|
||||||
self.events = { onBreakPointChanged = {}, onFileOpen = {}, onFileClosed = {}, onApplicationExiting = {} }
|
self.events = {
|
||||||
|
onBreakPointChanged = {},
|
||||||
|
onFileOpen = {},
|
||||||
|
onFileClosed = {},
|
||||||
|
onApplicationExiting = {},
|
||||||
|
onScrollChanged = {}
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
function meta.__index:show( show )
|
function meta.__index:show( show )
|
||||||
@ -81,37 +87,37 @@ function meta.__index:initLayout_()
|
|||||||
self.root = wx.wxSplitterWindow( self.frame, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 ) -- root widget
|
self.root = wx.wxSplitterWindow( self.frame, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 ) -- root widget
|
||||||
self.sourceBook = wx.wxNotebook( self.root, wx.wxID_ANY ) -- book of source code pages
|
self.sourceBook = wx.wxNotebook( self.root, wx.wxID_ANY ) -- book of source code pages
|
||||||
self.debugRoot = wx.wxSplitterWindow( self.root, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 )
|
self.debugRoot = wx.wxSplitterWindow( self.root, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 )
|
||||||
|
|
||||||
-- threads window
|
-- threads window
|
||||||
self.threads = ui.threads.new( self.debugRoot, self.frame )
|
self.threads = ui.threads.new( self.debugRoot, self.frame )
|
||||||
|
|
||||||
self.debugBooks = wx.wxSplitterWindow( self.debugRoot, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 )
|
self.debugBooks = wx.wxSplitterWindow( self.debugRoot, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, 0 )
|
||||||
self.debugBookL = wx.wxNotebook( self.debugBooks, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxNB_BOTTOM )
|
self.debugBookL = wx.wxNotebook( self.debugBooks, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxNB_BOTTOM )
|
||||||
self.debugBookR = wx.wxNotebook( self.debugBooks, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxNB_BOTTOM )
|
self.debugBookR = wx.wxNotebook( self.debugBooks, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxDefaultSize, wx.wxNB_BOTTOM )
|
||||||
|
|
||||||
-- callstack window
|
-- callstack window
|
||||||
self.callstack = ui.callstack.new( self.debugBookL )
|
self.callstack = ui.callstack.new( self.debugBookL )
|
||||||
self.debugBookL:AddPage( self.callstack:getRoot(), "Call stack" )
|
self.debugBookL:AddPage( self.callstack:getRoot(), "Call stack" )
|
||||||
|
|
||||||
-- automatic variables window
|
-- automatic variables window
|
||||||
self.auto = ui.luaExplorer.new( self.debugBookR, false )
|
self.auto = ui.luaExplorer.new( self.debugBookR, false )
|
||||||
self.debugBookR:AddPage( self.auto:getRoot(), "Automatic variables" )
|
self.debugBookR:AddPage( self.auto:getRoot(), "Automatic variables" )
|
||||||
|
|
||||||
-- watch window
|
-- watch window
|
||||||
self.watch = ui.luaExplorer.new( self.debugBookR, true )
|
self.watch = ui.luaExplorer.new( self.debugBookR, true )
|
||||||
self.debugBookR:AddPage( self.watch:getRoot(), "Watch" )
|
self.debugBookR:AddPage( self.watch:getRoot(), "Watch" )
|
||||||
|
|
||||||
self.root:SplitHorizontally( self.sourceBook, self.debugRoot, -200 )
|
self.root:SplitHorizontally( self.sourceBook, self.debugRoot, -200 )
|
||||||
self.debugRoot:SplitVertically( self.threads:getRoot(), self.debugBooks, 250 )
|
self.debugRoot:SplitVertically( self.threads:getRoot(), self.debugBooks, 250 )
|
||||||
self.debugBooks:SplitVertically( self.debugBookL, self.debugBookR )
|
self.debugBooks:SplitVertically( self.debugBookL, self.debugBookR )
|
||||||
|
|
||||||
self.sourcePages = {}
|
self.sourcePages = {}
|
||||||
|
|
||||||
local fileMenu = wx.wxMenu()
|
local fileMenu = wx.wxMenu()
|
||||||
fileMenu:Append( ID_FILE_OPEN, "&Open\tCtrl-O", "Open a source file" )
|
fileMenu:Append( ID_FILE_OPEN, "&Open\tCtrl-O", "Open a source file" )
|
||||||
fileMenu:Append( ID_FILE_CLOSE, "&Close\tCtrl-F4", "Close the current source file" )
|
fileMenu:Append( ID_FILE_CLOSE, "&Close\tCtrl-F4", "Close the current source file" )
|
||||||
fileMenu:Append( ID_EXIT, "E&xit\tAlt-F4", "Exit the GRLD server" )
|
fileMenu:Append( ID_EXIT, "E&xit\tAlt-F4", "Exit the GRLD server" )
|
||||||
|
|
||||||
local debugMenu = wx.wxMenu()
|
local debugMenu = wx.wxMenu()
|
||||||
debugMenu:Append( ID_BREAK, "&Break\tF12", "Stop execution of the program at the next executed line of code" )
|
debugMenu:Append( ID_BREAK, "&Break\tF12", "Stop execution of the program at the next executed line of code" )
|
||||||
debugMenu:Append( ID_CONTINUE, "&Continue\tF5", "Run the program at full speed" )
|
debugMenu:Append( ID_CONTINUE, "&Continue\tF5", "Run the program at full speed" )
|
||||||
@ -119,17 +125,17 @@ function meta.__index:initLayout_()
|
|||||||
debugMenu:Append( ID_STEP_INTO, "Step &into\tF11", "Step into a line" )
|
debugMenu:Append( ID_STEP_INTO, "Step &into\tF11", "Step into a line" )
|
||||||
debugMenu:Append( ID_STEP_OUT, "Step &out\tShift-F11", "Step out of the current function" )
|
debugMenu:Append( ID_STEP_OUT, "Step &out\tShift-F11", "Step out of the current function" )
|
||||||
debugMenu:Append( ID_TOGGLE_BREAKPOINT, "&Toggle breakpoint\tF9", "Toggle the breakpoint on the current line" )
|
debugMenu:Append( ID_TOGGLE_BREAKPOINT, "&Toggle breakpoint\tF9", "Toggle the breakpoint on the current line" )
|
||||||
|
|
||||||
local helpMenu = wx.wxMenu()
|
local helpMenu = wx.wxMenu()
|
||||||
helpMenu:Append( ID_HELP_MANUAL, "&Manual", "Send the GRLD manual to your web browser" )
|
helpMenu:Append( ID_HELP_MANUAL, "&Manual", "Send the GRLD manual to your web browser" )
|
||||||
helpMenu:Append( ID_HELP_ABOUT, "&About", "Open a window with various information about GRLD" )
|
helpMenu:Append( ID_HELP_ABOUT, "&About", "Open a window with various information about GRLD" )
|
||||||
|
|
||||||
local menuBar = wx.wxMenuBar()
|
local menuBar = wx.wxMenuBar()
|
||||||
menuBar:Append( fileMenu, "&File" )
|
menuBar:Append( fileMenu, "&File" )
|
||||||
menuBar:Append( debugMenu, "&Debug" )
|
menuBar:Append( debugMenu, "&Debug" )
|
||||||
menuBar:Append( helpMenu, "&Help" )
|
menuBar:Append( helpMenu, "&Help" )
|
||||||
self.frame:SetMenuBar( menuBar )
|
self.frame:SetMenuBar( menuBar )
|
||||||
|
|
||||||
self.frame:Connect( ID_FILE_OPEN, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onFileOpen_( ... ) end )
|
self.frame:Connect( ID_FILE_OPEN, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onFileOpen_( ... ) end )
|
||||||
self.frame:Connect( ID_FILE_CLOSE, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onFileClose_( ... ) end )
|
self.frame:Connect( ID_FILE_CLOSE, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onFileClose_( ... ) end )
|
||||||
self.frame:Connect( ID_HELP_MANUAL, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onHelpManual_( ... ) end )
|
self.frame:Connect( ID_HELP_MANUAL, wx.wxEVT_COMMAND_MENU_SELECTED, function( ... ) self:onHelpManual_( ... ) end )
|
||||||
@ -170,7 +176,7 @@ function meta.__index:onFileOpen_( event )
|
|||||||
fullPath = fileDialog:GetPath()
|
fullPath = fileDialog:GetPath()
|
||||||
end
|
end
|
||||||
fileDialog:Destroy()
|
fileDialog:Destroy()
|
||||||
|
|
||||||
if fullPath ~= nil then
|
if fullPath ~= nil then
|
||||||
self:runEvents_( "onFileOpen", fullPath )
|
self:runEvents_( "onFileOpen", fullPath )
|
||||||
end
|
end
|
||||||
@ -199,22 +205,22 @@ end
|
|||||||
|
|
||||||
function meta.__index:onHelpManual_()
|
function meta.__index:onHelpManual_()
|
||||||
local docPath = "../doc/index.html"
|
local docPath = "../doc/index.html"
|
||||||
|
|
||||||
-- get the command to start the default web browser from the registry (MS Windows only)
|
-- get the command to start the default web browser from the registry (MS Windows only)
|
||||||
local pipe = io.popen( "reg query HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command" )
|
local pipe = io.popen( "reg query HKEY_CLASSES_ROOT\\HTTP\\shell\\open\\command" )
|
||||||
local data = pipe:read( "*a" )
|
local data = pipe:read( "*a" )
|
||||||
pipe:close()
|
pipe:close()
|
||||||
|
|
||||||
-- example of returned data (Windows XP):
|
-- example of returned data (Windows XP):
|
||||||
--! REG.EXE VERSION 3.0
|
--! REG.EXE VERSION 3.0
|
||||||
--
|
--
|
||||||
--HKEY_CLASSES_ROOT\HTTP\shell\open\command
|
--HKEY_CLASSES_ROOT\HTTP\shell\open\command
|
||||||
-- <SANS NOM> REG_SZ "E:\Outils\Firefox\firefox.exe" -requestPending -osint -url "%1"
|
-- <SANS NOM> REG_SZ "E:\Outils\Firefox\firefox.exe" -requestPending -osint -url "%1"
|
||||||
|
|
||||||
-- other example (on Vista)
|
-- other example (on Vista)
|
||||||
--HKEY_CLASSES_ROOT\HTTP\shell\open\command
|
--HKEY_CLASSES_ROOT\HTTP\shell\open\command
|
||||||
-- (par défaut) REG_SZ "C:\Program Files\Mozilla Firefox\firefox.exe" -requestPending -osint -url "%1"
|
-- (par défaut) REG_SZ "C:\Program Files\Mozilla Firefox\firefox.exe" -requestPending -osint -url "%1"
|
||||||
|
|
||||||
-- parse returned data
|
-- parse returned data
|
||||||
local _, _, cmd = string.find( data, "REG_SZ%s+(.+)" )
|
local _, _, cmd = string.find( data, "REG_SZ%s+(.+)" )
|
||||||
local result = -1
|
local result = -1
|
||||||
@ -228,7 +234,7 @@ function meta.__index:onHelpManual_()
|
|||||||
cmd = cmd.."\""..docPath.."\""
|
cmd = cmd.."\""..docPath.."\""
|
||||||
end
|
end
|
||||||
print( cmd )
|
print( cmd )
|
||||||
|
|
||||||
-- start the default browser with the GRLD documentation as parameter
|
-- start the default browser with the GRLD documentation as parameter
|
||||||
result = os.execute( "start \"GRLD documentation\" "..cmd )
|
result = os.execute( "start \"GRLD documentation\" "..cmd )
|
||||||
end
|
end
|
||||||
@ -272,6 +278,7 @@ function meta.__index:getSourcePage( source )
|
|||||||
page.pageIdx = self.sourceBook:GetPageCount()
|
page.pageIdx = self.sourceBook:GetPageCount()
|
||||||
self.sourceBook:AddPage( page:getRoot(), name )
|
self.sourceBook:AddPage( page:getRoot(), name )
|
||||||
page:registerEvent( "onBreakPointChanged", function( ... ) self:runEvents_( "onBreakPointChanged", source, ... ) end )
|
page:registerEvent( "onBreakPointChanged", function( ... ) self:runEvents_( "onBreakPointChanged", source, ... ) end )
|
||||||
|
page:registerEvent( "onScrollChanged", function( ... ) self:runEvents_( "onScrollChanged", source, ... ) end )
|
||||||
end
|
end
|
||||||
return page
|
return page
|
||||||
end
|
end
|
||||||
@ -341,6 +348,10 @@ function meta.__index:setActive()
|
|||||||
self.active = true
|
self.active = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function meta.__index:raise()
|
||||||
|
self.frame:Raise()
|
||||||
|
end
|
||||||
|
|
||||||
function meta.__index:onIdleUpdate_( event )
|
function meta.__index:onIdleUpdate_( event )
|
||||||
local currentPageIdx = self.sourceBook:GetSelection()
|
local currentPageIdx = self.sourceBook:GetSelection()
|
||||||
for _, page in pairs( self.sourcePages ) do
|
for _, page in pairs( self.sourcePages ) do
|
||||||
@ -351,7 +362,7 @@ function meta.__index:onIdleUpdate_( event )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.active = false
|
self.active = false
|
||||||
for _, func in pairs( self.idleUpdates ) do
|
for _, func in pairs( self.idleUpdates ) do
|
||||||
local ok, msg = xpcall( func, debug.traceback )
|
local ok, msg = xpcall( func, debug.traceback )
|
||||||
|
@ -5,6 +5,8 @@ local ui =
|
|||||||
editor = require( "ui.editor" ),
|
editor = require( "ui.editor" ),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
local wx = require( "wx" )
|
||||||
|
|
||||||
local lfs = require( "lfs" )
|
local lfs = require( "lfs" )
|
||||||
|
|
||||||
local assert = assert
|
local assert = assert
|
||||||
@ -23,7 +25,10 @@ function new( parent, source )
|
|||||||
local page = {}
|
local page = {}
|
||||||
setmetatable( page, meta )
|
setmetatable( page, meta )
|
||||||
page.editor = ui.editor.new( parent )
|
page.editor = ui.editor.new( parent )
|
||||||
page.events = { onBreakPointChanged = {} }
|
page.events = {
|
||||||
|
onBreakPointChanged = {},
|
||||||
|
onScrollChanged = {},
|
||||||
|
}
|
||||||
page:setSource_( source )
|
page:setSource_( source )
|
||||||
page.editor.breakpointCallback = function( line )
|
page.editor.breakpointCallback = function( line )
|
||||||
page:runEvents_( "onBreakPointChanged", line )
|
page:runEvents_( "onBreakPointChanged", line )
|
||||||
@ -53,6 +58,9 @@ function meta.__index:update()
|
|||||||
assert( string.sub( self.source, 1, 1 ) == "@" )
|
assert( string.sub( self.source, 1, 1 ) == "@" )
|
||||||
local fileName = string.sub( self.source, 2 )
|
local fileName = string.sub( self.source, 2 )
|
||||||
|
|
||||||
|
local scrollPosition = self:GetScrollPos()
|
||||||
|
self:runEvents_( "onScrollChanged", scrollPosition )
|
||||||
|
|
||||||
local newDate = lfs.attributes( fileName, "modification" ) or 0
|
local newDate = lfs.attributes( fileName, "modification" ) or 0
|
||||||
if newDate > self.sourceDate then
|
if newDate > self.sourceDate then
|
||||||
print( "reloading source file "..fileName )
|
print( "reloading source file "..fileName )
|
||||||
@ -78,6 +86,14 @@ function meta.__index:getFocus()
|
|||||||
return ed:GetCurrentLine() + 1
|
return ed:GetCurrentLine() + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function meta.__index:SetScrollPos( pos )
|
||||||
|
self.editor.editor:LineScroll(0, pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
function meta.__index:GetScrollPos()
|
||||||
|
return self.editor.editor:GetScrollPos( wx.wxVERTICAL )
|
||||||
|
end
|
||||||
|
|
||||||
function meta.__index:setCurrentLine( line )
|
function meta.__index:setCurrentLine( line )
|
||||||
local editor = self.editor.editor
|
local editor = self.editor.editor
|
||||||
if self.currentLine == line then return end
|
if self.currentLine == line then return end
|
||||||
|
@ -11,6 +11,8 @@ local ui =
|
|||||||
}
|
}
|
||||||
local lfs = require( "lfs" )
|
local lfs = require( "lfs" )
|
||||||
|
|
||||||
|
local wx = require( "wx" )
|
||||||
|
|
||||||
require( "coxpcall" )
|
require( "coxpcall" )
|
||||||
local coxpcall = coxpcall
|
local coxpcall = coxpcall
|
||||||
local copcall = copcall
|
local copcall = copcall
|
||||||
@ -37,6 +39,15 @@ local meta = { __index = {} }
|
|||||||
|
|
||||||
local complexValueManagerMeta = { __index = {} }
|
local complexValueManagerMeta = { __index = {} }
|
||||||
|
|
||||||
|
local function createClientConfig(name)
|
||||||
|
return {
|
||||||
|
name = name,
|
||||||
|
mappings = {},
|
||||||
|
breakpoints = {},
|
||||||
|
scrollPositions = {},
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
function new( engine, window )
|
function new( engine, window )
|
||||||
local res =
|
local res =
|
||||||
{
|
{
|
||||||
@ -101,9 +112,9 @@ end
|
|||||||
|
|
||||||
function meta.__index:run_()
|
function meta.__index:run_()
|
||||||
self:sleep_()
|
self:sleep_()
|
||||||
|
|
||||||
--@GRLD_PROTECTION@
|
--@GRLD_PROTECTION@
|
||||||
|
|
||||||
self.engine.init()
|
self.engine.init()
|
||||||
for _, listener in ipairs( self.toListen ) do
|
for _, listener in ipairs( self.toListen ) do
|
||||||
self.engine.listen( listener.ip, listener.port )
|
self.engine.listen( listener.ip, listener.port )
|
||||||
@ -114,7 +125,7 @@ function meta.__index:run_()
|
|||||||
for _, cbName in ipairs( { "onNewClient", "onClientBreak", "onClientLost" } ) do
|
for _, cbName in ipairs( { "onNewClient", "onClientBreak", "onClientLost" } ) do
|
||||||
self.engine.registerEvent( cbName, function( ... ) return self[cbName.."_"]( self, ... ) end )
|
self.engine.registerEvent( cbName, function( ... ) return self[cbName.."_"]( self, ... ) end )
|
||||||
end
|
end
|
||||||
|
|
||||||
local wrapCb = function( cb )
|
local wrapCb = function( cb )
|
||||||
return function( ... )
|
return function( ... )
|
||||||
if self:ready_() then
|
if self:ready_() then
|
||||||
@ -122,30 +133,31 @@ function meta.__index:run_()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.window:registerEvent( ui.mainWindow.ID_BREAK, wrapCb( function() self:onDebugCommand_( "breaknow", "running" ) end ) )
|
self.window:registerEvent( ui.mainWindow.ID_BREAK, wrapCb( function() self:onDebugCommand_( "breaknow", "running" ) end ) )
|
||||||
self.window:registerEvent( ui.mainWindow.ID_CONTINUE, wrapCb( function() self:onDebugCommand_( "run", "break" ) end ) )
|
self.window:registerEvent( ui.mainWindow.ID_CONTINUE, wrapCb( function() self:onDebugCommand_( "run", "break" ) end ) )
|
||||||
self.window:registerEvent( ui.mainWindow.ID_STEP_OVER, wrapCb( function() self:onDebugCommand_( "stepover", "break" ) end ) )
|
self.window:registerEvent( ui.mainWindow.ID_STEP_OVER, wrapCb( function() self:onDebugCommand_( "stepover", "break" ) end ) )
|
||||||
self.window:registerEvent( ui.mainWindow.ID_STEP_INTO, wrapCb( function() self:onDebugCommand_( "stepin", "break" ) end ) )
|
self.window:registerEvent( ui.mainWindow.ID_STEP_INTO, wrapCb( function() self:onDebugCommand_( "stepin", "break" ) end ) )
|
||||||
self.window:registerEvent( ui.mainWindow.ID_STEP_OUT, wrapCb( function() self:onDebugCommand_( "stepout", "break" ) end ) )
|
self.window:registerEvent( ui.mainWindow.ID_STEP_OUT, wrapCb( function() self:onDebugCommand_( "stepout", "break" ) end ) )
|
||||||
self.window:registerEvent( ui.mainWindow.ID_TOGGLE_BREAKPOINT, wrapCb( function() self:onToggleBreakpoint_() end ) )
|
self.window:registerEvent( ui.mainWindow.ID_TOGGLE_BREAKPOINT, wrapCb( function() self:onToggleBreakpoint_() end ) )
|
||||||
|
|
||||||
self.window:registerEvent( "onBreakPointChanged", wrapCb( function( ... ) self:onBreakPointChanged_( ... ) end ) )
|
self.window:registerEvent( "onBreakPointChanged", wrapCb( function( ... ) self:onBreakPointChanged_( ... ) end ) )
|
||||||
self.window:registerEvent( "onFileOpen", wrapCb( function( ... ) self:onFileOpen_( ... ) end ) )
|
self.window:registerEvent( "onFileOpen", wrapCb( function( ... ) self:onFileOpen_( ... ) end ) )
|
||||||
self.window:registerEvent( "onFileClosed", wrapCb( function( ... ) self:onFileClosed_( ... ) end ) )
|
self.window:registerEvent( "onFileClosed", wrapCb( function( ... ) self:onFileClosed_( ... ) end ) )
|
||||||
|
self.window:registerEvent( "onScrollChanged", wrapCb(function( ... ) self:onScrollChanged_( ...) end ) )
|
||||||
|
|
||||||
self.window:registerEvent( "onApplicationExiting", wrapCb( function( ... ) self:onApplicationExiting_( ... ) end ) )
|
self.window:registerEvent( "onApplicationExiting", wrapCb( function( ... ) self:onApplicationExiting_( ... ) end ) )
|
||||||
|
|
||||||
self.window.threads:registerEvent( "onThreadClicked", wrapCb( function( ... ) self:onThreadClicked_( ... ) end ) )
|
self.window.threads:registerEvent( "onThreadClicked", wrapCb( function( ... ) self:onThreadClicked_( ... ) end ) )
|
||||||
self.window.threads:registerEvent( "onBreakOnConnectionChanged", wrapCb( function( ... ) self:onBreakOnConnectionChanged_( ... ) end ) )
|
self.window.threads:registerEvent( "onBreakOnConnectionChanged", wrapCb( function( ... ) self:onBreakOnConnectionChanged_( ... ) end ) )
|
||||||
|
|
||||||
self.window.callstack:registerEvent( "onCallstackClicked", wrapCb( function( ... ) self:onCallstackClicked_( ... ) end ) )
|
self.window.callstack:registerEvent( "onCallstackClicked", wrapCb( function( ... ) self:onCallstackClicked_( ... ) end ) )
|
||||||
|
|
||||||
self.window.watch.evaluateCallback = wrapCb( function( expr ) return self:evaluateExpression_( expr ) end )
|
self.window.watch.evaluateCallback = wrapCb( function( expr ) return self:evaluateExpression_( expr ) end )
|
||||||
|
|
||||||
self.configs.global = { name = "global", breakpoints = {} }
|
self.configs.global = createClientConfig('global')
|
||||||
self:loadConfig_( "global" )
|
self:loadConfig_( "global" )
|
||||||
|
|
||||||
self:sleep_()
|
self:sleep_()
|
||||||
while not self.exiting do
|
while not self.exiting do
|
||||||
for clientId, clientData in pairs( self.clients ) do
|
for clientId, clientData in pairs( self.clients ) do
|
||||||
@ -188,18 +200,34 @@ function meta.__index:run_()
|
|||||||
end
|
end
|
||||||
end, function( msg ) print( "Error refreshing client "..clientId ) print( msg ) print( debug.traceback() ) end )
|
end, function( msg ) print( "Error refreshing client "..clientId ) print( msg ) print( debug.traceback() ) end )
|
||||||
end
|
end
|
||||||
|
|
||||||
if self.threadsDirty then
|
if self.threadsDirty then
|
||||||
coxpcall( function()
|
coxpcall( function()
|
||||||
self.threadsDirty = false
|
self.threadsDirty = false
|
||||||
self:refreshThreads_()
|
self:refreshThreads_()
|
||||||
end, function( msg ) print( "Error refreshing threads" ) print( msg ) print( debug.traceback() ) end )
|
end, function( msg ) print( "Error refreshing threads" ) print( msg ) print( debug.traceback() ) end )
|
||||||
end
|
end
|
||||||
|
|
||||||
self:sleep_()
|
self:sleep_()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function meta.__index:getActiveClientConfig_()
|
||||||
|
local activeClientId = self.activeClient
|
||||||
|
|
||||||
|
if activeClientId == nil then
|
||||||
|
return self.configs.global
|
||||||
|
end
|
||||||
|
|
||||||
|
local clientData = self.clients[activeClientId]
|
||||||
|
|
||||||
|
if clientData == nil then
|
||||||
|
return self.configs.global
|
||||||
|
end
|
||||||
|
|
||||||
|
return clientData.config
|
||||||
|
end
|
||||||
|
|
||||||
function meta.__index:evaluateExpression_( expr )
|
function meta.__index:evaluateExpression_( expr )
|
||||||
local clientId = self.activeClient
|
local clientId = self.activeClient
|
||||||
local client = self.engine.getClient( clientId )
|
local client = self.engine.getClient( clientId )
|
||||||
@ -224,6 +252,7 @@ function meta.__index:refreshSourcePageFocus_( remoteSource, line )
|
|||||||
local clientData = assert( self.clients[clientId] )
|
local clientData = assert( self.clients[clientId] )
|
||||||
local sourceType = string.sub( remoteSource, 1, 1 )
|
local sourceType = string.sub( remoteSource, 1, 1 )
|
||||||
if sourceType == "@" then
|
if sourceType == "@" then
|
||||||
|
self.window:raise()
|
||||||
print( "Setting focus to "..remoteSource.."("..line..")" )
|
print( "Setting focus to "..remoteSource.."("..line..")" )
|
||||||
remoteSource = grldc.utilities.normalizePath( string.sub( remoteSource, 2 ) )
|
remoteSource = grldc.utilities.normalizePath( string.sub( remoteSource, 2 ) )
|
||||||
local source, remotePath, remoteFile = self:getLocalSource_( clientId, remoteSource )
|
local source, remotePath, remoteFile = self:getLocalSource_( clientId, remoteSource )
|
||||||
@ -243,16 +272,16 @@ function meta.__index:refreshSourcePageFocus_( remoteSource, line )
|
|||||||
clientData.config.mappings[mount] = path
|
clientData.config.mappings[mount] = path
|
||||||
clientData.config.dirty = true
|
clientData.config.dirty = true
|
||||||
source = self:getLocalSource_( clientId, remoteSource )
|
source = self:getLocalSource_( clientId, remoteSource )
|
||||||
assert( source ~= nil )
|
assert( source ~= nil )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if source ~= nil then
|
if source ~= nil then
|
||||||
print( source )
|
print( source )
|
||||||
source = grldc.utilities.normalizePath( source )
|
source = grldc.utilities.normalizePath( source )
|
||||||
self:setSourceFocus_( "@"..source, line )
|
self:setSourceFocus_( "@"..source, line )
|
||||||
end
|
end
|
||||||
|
|
||||||
--print( source )
|
--print( source )
|
||||||
return source
|
return source
|
||||||
end
|
end
|
||||||
@ -264,12 +293,12 @@ function meta.__index:refreshSourceFocus_( callstack, level )
|
|||||||
if type( callstack ) == "table" and callstack[level] ~= nil then
|
if type( callstack ) == "table" and callstack[level] ~= nil then
|
||||||
local remoteSource = callstack[level].source
|
local remoteSource = callstack[level].source
|
||||||
local line = callstack[level].line
|
local line = callstack[level].line
|
||||||
|
|
||||||
local source = self:refreshSourcePageFocus_( remoteSource, line )
|
local source = self:refreshSourcePageFocus_( remoteSource, line )
|
||||||
|
|
||||||
self:setPointers_( level, source, line )
|
self:setPointers_( level, source, line )
|
||||||
self:refreshPointers_()
|
self:refreshPointers_()
|
||||||
|
|
||||||
self:refreshWatches_( level )
|
self:refreshWatches_( level )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -333,10 +362,10 @@ function meta.__index:onBreakPointChanged_( source, line )
|
|||||||
else
|
else
|
||||||
local clientData = self.clients[clientId]
|
local clientData = self.clients[clientId]
|
||||||
if clientData == nil then return end
|
if clientData == nil then return end
|
||||||
|
|
||||||
config = clientData.config
|
config = clientData.config
|
||||||
end
|
end
|
||||||
|
|
||||||
if config.breakpoints[source] == nil then
|
if config.breakpoints[source] == nil then
|
||||||
config.breakpoints[source] = {}
|
config.breakpoints[source] = {}
|
||||||
end
|
end
|
||||||
@ -345,9 +374,9 @@ function meta.__index:onBreakPointChanged_( source, line )
|
|||||||
if not newValue then
|
if not newValue then
|
||||||
config.breakpoints[source][line] = nil
|
config.breakpoints[source][line] = nil
|
||||||
end
|
end
|
||||||
|
|
||||||
print( "Setting breakpoint at "..source.."("..line..") to "..tostring(newValue) )
|
print( "Setting breakpoint at "..source.."("..line..") to "..tostring(newValue) )
|
||||||
|
|
||||||
assert( string.sub( source, 1, 1 ) == "@" )
|
assert( string.sub( source, 1, 1 ) == "@" )
|
||||||
source = string.sub( source, 2 )
|
source = string.sub( source, 2 )
|
||||||
for clientId, clientData in pairs( self.clients ) do
|
for clientId, clientData in pairs( self.clients ) do
|
||||||
@ -375,7 +404,7 @@ function meta.__index:onBreakPointChanged_( source, line )
|
|||||||
assert( remoteSource ~= nil )
|
assert( remoteSource ~= nil )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if remoteSource ~= nil then
|
if remoteSource ~= nil then
|
||||||
client:setbreakpoint( "@"..remoteSource, line, newValue )
|
client:setbreakpoint( "@"..remoteSource, line, newValue )
|
||||||
clientData.config.dirty = true
|
clientData.config.dirty = true
|
||||||
@ -396,6 +425,17 @@ function meta.__index:onApplicationExiting_()
|
|||||||
self.window.threads:setData( nil )
|
self.window.threads:setData( nil )
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function meta.__index:refreshScrollPosition_()
|
||||||
|
local config = self:getActiveClientConfig_()
|
||||||
|
|
||||||
|
for source, sp in pairs( config.scrollPositions ) do
|
||||||
|
local page = self.window:getSourcePage( source )
|
||||||
|
if page ~= nil then
|
||||||
|
page:SetScrollPos(sp)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function meta.__index:refreshBreakPoints_()
|
function meta.__index:refreshBreakPoints_()
|
||||||
local clientId = self.activeClient
|
local clientId = self.activeClient
|
||||||
local config = nil
|
local config = nil
|
||||||
@ -406,14 +446,14 @@ function meta.__index:refreshBreakPoints_()
|
|||||||
config = self.clients[clientId].config
|
config = self.clients[clientId].config
|
||||||
client = self.engine.getClient( clientId )
|
client = self.engine.getClient( clientId )
|
||||||
end
|
end
|
||||||
|
|
||||||
local remoteBreakPoints = {}
|
local remoteBreakPoints = {}
|
||||||
if client ~= nil then
|
if client ~= nil then
|
||||||
remoteBreakPoints = client:breakpoints()
|
remoteBreakPoints = client:breakpoints()
|
||||||
end
|
end
|
||||||
self.window:clearBreakPoints()
|
self.window:clearBreakPoints()
|
||||||
local goodBreakpoints = {}
|
local goodBreakpoints = {}
|
||||||
|
|
||||||
for remoteSource, lines in pairs( remoteBreakPoints ) do
|
for remoteSource, lines in pairs( remoteBreakPoints ) do
|
||||||
if next( lines ) ~= nil then
|
if next( lines ) ~= nil then
|
||||||
local source = self:getLocalSource_( clientId, string.sub( remoteSource, 2 ) )
|
local source = self:getLocalSource_( clientId, string.sub( remoteSource, 2 ) )
|
||||||
@ -437,7 +477,7 @@ function meta.__index:refreshBreakPoints_()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for source, lines in pairs( config.breakpoints ) do
|
for source, lines in pairs( config.breakpoints ) do
|
||||||
local page = self.window:findSourcePage( source )
|
local page = self.window:findSourcePage( source )
|
||||||
if page ~= nil then
|
if page ~= nil then
|
||||||
@ -459,6 +499,7 @@ function meta.__index:onFileOpen_( path )
|
|||||||
self:setSourceFocus_( source, 1 )
|
self:setSourceFocus_( source, 1 )
|
||||||
self:refreshPointers_()
|
self:refreshPointers_()
|
||||||
self:refreshBreakPoints_()
|
self:refreshBreakPoints_()
|
||||||
|
self:refreshScrollPosition_()
|
||||||
end
|
end
|
||||||
|
|
||||||
function meta.__index:onFileClosed_( source )
|
function meta.__index:onFileClosed_( source )
|
||||||
@ -467,6 +508,12 @@ function meta.__index:onFileClosed_( source )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function meta.__index:onScrollChanged_( source, position )
|
||||||
|
local clientConfig = self:getActiveClientConfig_()
|
||||||
|
clientConfig.scrollPositions[source] = position
|
||||||
|
clientConfig.dirty = true
|
||||||
|
end
|
||||||
|
|
||||||
function meta.__index:onThreadClicked_( clientId, threadId )
|
function meta.__index:onThreadClicked_( clientId, threadId )
|
||||||
print( "Thread clicked: client="..clientId..", thread="..threadId )
|
print( "Thread clicked: client="..clientId..", thread="..threadId )
|
||||||
local clientData = self.clients[clientId]
|
local clientData = self.clients[clientId]
|
||||||
@ -492,9 +539,9 @@ function meta.__index:onDebugCommand_( command, neededState, targetClientId )
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
if neededState ~= nil and client:status() ~= neededState then return end
|
if neededState ~= nil and client:status() ~= neededState then return end
|
||||||
|
|
||||||
self:invalidateState_( false )
|
self:invalidateState_( false )
|
||||||
|
|
||||||
local clientData = assert( self.clients[targetClientId] )
|
local clientData = assert( self.clients[targetClientId] )
|
||||||
local ok, msg = xpcall( function() client[command]( client ) end, debug.traceback )
|
local ok, msg = xpcall( function() client[command]( client ) end, debug.traceback )
|
||||||
if not ok then
|
if not ok then
|
||||||
@ -514,7 +561,7 @@ function meta.__index:invalidateState_( immediate )
|
|||||||
self.window:clearMarkers()
|
self.window:clearMarkers()
|
||||||
self.window.callstack:setData( nil )
|
self.window.callstack:setData( nil )
|
||||||
self:refreshBreakPoints_()
|
self:refreshBreakPoints_()
|
||||||
|
|
||||||
local client = self.engine.getClient( self.activeClient )
|
local client = self.engine.getClient( self.activeClient )
|
||||||
if client == nil then
|
if client == nil then
|
||||||
self.window.auto:clear()
|
self.window.auto:clear()
|
||||||
@ -636,7 +683,7 @@ function meta.__index:refreshThreads_()
|
|||||||
cdata.status = client:status()
|
cdata.status = client:status()
|
||||||
cdata.active = (clientId == self.activeClient)
|
cdata.active = (clientId == self.activeClient)
|
||||||
cdata.breakOnConnection = clientData.config.breakOnConnection
|
cdata.breakOnConnection = clientData.config.breakOnConnection
|
||||||
|
|
||||||
if cdata.status == "break" then
|
if cdata.status == "break" then
|
||||||
local current = client:getcurrentthread()
|
local current = client:getcurrentthread()
|
||||||
local active = client:getactivethread()
|
local active = client:getactivethread()
|
||||||
@ -644,7 +691,7 @@ function meta.__index:refreshThreads_()
|
|||||||
active = current
|
active = current
|
||||||
end
|
end
|
||||||
table.insert( cdata.coroutines, { id = "main", current = (current == "main"), active = (active=="main" and cdata.clientId == self.activeClient and client:getactivethread() ~= "current") } )
|
table.insert( cdata.coroutines, { id = "main", current = (current == "main"), active = (active=="main" and cdata.clientId == self.activeClient and client:getactivethread() ~= "current") } )
|
||||||
|
|
||||||
local coroutines = client:coroutines()
|
local coroutines = client:coroutines()
|
||||||
--print( coroutines )
|
--print( coroutines )
|
||||||
for _, data in ipairs( coroutines ) do
|
for _, data in ipairs( coroutines ) do
|
||||||
@ -655,7 +702,7 @@ function meta.__index:refreshThreads_()
|
|||||||
table.insert( cdata.coroutines, codata )
|
table.insert( cdata.coroutines, codata )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
table.insert( data, cdata )
|
table.insert( data, cdata )
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -683,15 +730,15 @@ function meta.__index:onNewClient_( clientId )
|
|||||||
local client = self.engine.getClient( clientId )
|
local client = self.engine.getClient( clientId )
|
||||||
local name = client:name()
|
local name = client:name()
|
||||||
if self.configs[name] == nil then
|
if self.configs[name] == nil then
|
||||||
self.configs[name] = { name = name, mappings = {}, breakpoints = {} }
|
self.configs[name] = createClientConfig(name)
|
||||||
self:loadConfig_( name )
|
self:loadConfig_( name )
|
||||||
end
|
end
|
||||||
self.clients[clientId] = { dirty = true, activeThread = "current", activeLevel = 1, config = self.configs[name] }
|
self.clients[clientId] = { dirty = true, activeThread = "current", activeLevel = 1, config = self.configs[name] }
|
||||||
|
|
||||||
for source, lines in pairs( self.configs[name].breakpoints ) do
|
for source, lines in pairs( self.configs[name].breakpoints ) do
|
||||||
assert( string.sub( source, 1, 1 ) == "@" )
|
assert( string.sub( source, 1, 1 ) == "@" )
|
||||||
source = string.sub( source, 2 )
|
source = string.sub( source, 2 )
|
||||||
local remoteSource, dir = self:getRemoteSource_( clientId, source )
|
local remoteSource, dir = self:getRemoteSource_( clientId, source )
|
||||||
if remoteSource ~= nil then
|
if remoteSource ~= nil then
|
||||||
for line, value in pairs( lines ) do
|
for line, value in pairs( lines ) do
|
||||||
if value then
|
if value then
|
||||||
@ -700,12 +747,12 @@ function meta.__index:onNewClient_( clientId )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
self.threadsDirty = true
|
self.threadsDirty = true
|
||||||
if self.activeClient == nil then
|
if self.activeClient == nil then
|
||||||
self:setActiveClient_( clientId )
|
self:setActiveClient_( clientId )
|
||||||
end
|
end
|
||||||
|
|
||||||
if not self.configs[name].breakOnConnection then
|
if not self.configs[name].breakOnConnection then
|
||||||
self.clients[clientId].ignoreNextBreak = true
|
self.clients[clientId].ignoreNextBreak = true
|
||||||
end
|
end
|
||||||
@ -717,7 +764,7 @@ function meta.__index:onClientBreak_( clientId )
|
|||||||
clientData.dirty = true
|
clientData.dirty = true
|
||||||
clientData.activeLevel = 1
|
clientData.activeLevel = 1
|
||||||
self.threadsDirty = true
|
self.threadsDirty = true
|
||||||
|
|
||||||
if clientData.ignoreNextBreak then
|
if clientData.ignoreNextBreak then
|
||||||
clientData.ignoreNextBreak = false
|
clientData.ignoreNextBreak = false
|
||||||
self:onDebugCommand_( "run", "break", clientId )
|
self:onDebugCommand_( "run", "break", clientId )
|
||||||
@ -741,12 +788,19 @@ function meta.__index:saveConfig_( name )
|
|||||||
openFiles[page.pageIdx+1] = source
|
openFiles[page.pageIdx+1] = source
|
||||||
end
|
end
|
||||||
local breakpoints = clientConfig.breakpoints
|
local breakpoints = clientConfig.breakpoints
|
||||||
|
local scrollPositions = clientConfig.scrollPositions
|
||||||
|
|
||||||
local path = "clients/"..name.."/config.lua"
|
local path = "clients/"..name.."/config.lua"
|
||||||
lfs.mkdir( "clients" )
|
lfs.mkdir( "clients" )
|
||||||
lfs.mkdir( "clients/"..name )
|
lfs.mkdir( "clients/"..name )
|
||||||
local file = assert( io.open( path, "w" ) )
|
local file = assert( io.open( path, "w" ) )
|
||||||
file:write( grldc.net.serialize( { mappings = clientConfig.mappings, openFiles = openFiles, breakpoints = breakpoints, breakOnConnection = clientConfig.breakOnConnection } ) )
|
file:write( grldc.net.serialize( {
|
||||||
|
mappings = clientConfig.mappings,
|
||||||
|
openFiles = openFiles,
|
||||||
|
breakpoints = breakpoints,
|
||||||
|
scrollPositions = scrollPositions,
|
||||||
|
breakOnConnection = clientConfig.breakOnConnection
|
||||||
|
} ) )
|
||||||
file:close()
|
file:close()
|
||||||
print( "Saved config \""..name.."\"" )
|
print( "Saved config \""..name.."\"" )
|
||||||
clientConfig.lastConfigSave = os.time()
|
clientConfig.lastConfigSave = os.time()
|
||||||
@ -774,6 +828,12 @@ function meta.__index:loadConfig_( name )
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if config.scrollPositions ~= nil then
|
||||||
|
for source, sp in pairs( config.scrollPositions ) do
|
||||||
|
clientConfig.scrollPositions[source] = sp
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
if clientConfig.breakOnConnection == nil then
|
if clientConfig.breakOnConnection == nil then
|
||||||
clientConfig.breakOnConnection = true
|
clientConfig.breakOnConnection = true
|
||||||
|
Loading…
Reference in New Issue
Block a user