Skip to content

Commit

Permalink
Still more WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
SpartanJ committed Jan 4, 2025
1 parent a96e033 commit c4bd884
Show file tree
Hide file tree
Showing 10 changed files with 251 additions and 113 deletions.
3 changes: 2 additions & 1 deletion src/tools/ecode/plugins/debugger/dap/protocol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,8 @@ template <> struct std::hash<ecode::dap::SourceBreakpoint> {
};

template <> struct std::hash<ecode::dap::SourceBreakpointStateful> {
std::size_t operator()( ecode::dap::SourceBreakpointStateful const& breakpoint ) const noexcept {
std::size_t
operator()( ecode::dap::SourceBreakpointStateful const& breakpoint ) const noexcept {
size_t h1 = std::hash<int>()( breakpoint.line );
size_t h2 = breakpoint.column ? std::hash<int>()( *breakpoint.column ) : 0;
size_t h3 = breakpoint.condition ? std::hash<std::string>()( *breakpoint.condition ) : 0;
Expand Down
208 changes: 123 additions & 85 deletions src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@

namespace ecode {

static std::vector<SourceBreakpoint> fromSet( const UnorderedSet<SourceBreakpointStateful>& set ) {
std::vector<SourceBreakpoint>
DebuggerClientListener::fromSet( const EE::UnorderedSet<SourceBreakpointStateful>& set ) {
std::vector<SourceBreakpoint> bps;
bps.reserve( set.size() );
for ( const auto& bp : set )
Expand All @@ -13,72 +14,6 @@ static std::vector<SourceBreakpoint> fromSet( const UnorderedSet<SourceBreakpoin
return bps;
}

DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin ) :
mClient( client ), mPlugin( plugin ) {
eeASSERT( mClient && mPlugin );
}

void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
if ( state == DebuggerClient::State::Initializing ) {
mPlugin->getManager()->getUISceneNode()->runOnMainThread( [this] {
getStatusDebuggerController()->createWidget();

mPlugin->getManager()
->getPluginContext()
->getStatusAppOutputController()
->initNewOutput( {}, false );
} );
}
}

void DebuggerClientListener::initialized() {
Lock l( mPlugin->mBreakpointsMutex );
for ( const auto& fileBps : mPlugin->mBreakpoints )
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
}

void DebuggerClientListener::launched() {}

void DebuggerClientListener::configured() {}

void DebuggerClientListener::failed() {}

void DebuggerClientListener::debuggeeRunning() {}

void DebuggerClientListener::debuggeeTerminated() {}

void DebuggerClientListener::capabilitiesReceived( const Capabilities& /*capabilities*/ ) {}

void DebuggerClientListener::debuggeeExited( int /*exitCode*/ ) {
mPlugin->exitDebugger();
}

void DebuggerClientListener::debuggeeStopped( const StoppedEvent& event ) {
Log::debug( "DebuggerClientListener::debuggeeStopped: reason %s", event.reason );
mClient->threads();
if ( event.threadId )
mClient->stackTrace( *event.threadId );
}

void DebuggerClientListener::debuggeeContinued( const ContinuedEvent& ) {}

void DebuggerClientListener::outputProduced( const Output& output ) {
if ( Output::Category::Stdout == output.category ||
Output::Category::Stderr == output.category ) {
mPlugin->getManager()->getPluginContext()->getStatusAppOutputController()->insertBuffer(
output.output );
}
}

void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {}

void DebuggerClientListener::errorResponse( const std::string& /*summary*/,
const std::optional<Message>& /*message*/ ) {}

void DebuggerClientListener::threadChanged( const ThreadEvent& ) {}

void DebuggerClientListener::moduleChanged( const ModuleEvent& ) {}

class ThreadsModel : public Model {
public:
ThreadsModel( const std::vector<Thread>& threads ) : mThreads( threads ) {}
Expand All @@ -102,16 +37,11 @@ class ThreadsModel : public Model {
std::vector<Thread> mThreads;
};

void DebuggerClientListener::threads( const std::vector<Thread>& threads ) {
getStatusDebuggerController()->getUIThreads()->setModel(
std::make_shared<ThreadsModel>( threads ) );
}

class StackModel : public Model {
public:
StackModel( const StackTraceInfo& stack ) : mStack( stack ) {}
virtual size_t rowCount( const ModelIndex& ) const { return mStack.stackFrames.size(); }
virtual size_t columnCount( const ModelIndex& ) const { return 5; }
virtual size_t columnCount( const ModelIndex& ) const { return 6; }

virtual std::string columnName( const size_t& colIdx ) const {
switch ( colIdx ) {
Expand Down Expand Up @@ -160,6 +90,99 @@ class StackModel : public Model {
StackTraceInfo mStack;
};

DebuggerClientListener::DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin ) :
mClient( client ), mPlugin( plugin ) {
eeASSERT( mClient && mPlugin );
}

void DebuggerClientListener::stateChanged( DebuggerClient::State state ) {
if ( state == DebuggerClient::State::Initializing ) {
mPlugin->getManager()->getUISceneNode()->runOnMainThread( [this] {
getStatusDebuggerController()->createWidget();

mPlugin->getManager()
->getPluginContext()
->getStatusAppOutputController()
->initNewOutput( {}, false );
} );
}
}

void DebuggerClientListener::initialized() {
Lock l( mPlugin->mBreakpointsMutex );
for ( const auto& fileBps : mPlugin->mBreakpoints )
mClient->setBreakpoints( fileBps.first, fromSet( fileBps.second ) );
}

void DebuggerClientListener::launched() {}

void DebuggerClientListener::configured() {}

void DebuggerClientListener::failed() {}

void DebuggerClientListener::debuggeeRunning() {}

void DebuggerClientListener::debuggeeTerminated() {}

void DebuggerClientListener::capabilitiesReceived( const Capabilities& /*capabilities*/ ) {}

void DebuggerClientListener::debuggeeExited( int /*exitCode*/ ) {
mPlugin->exitDebugger();
}

void DebuggerClientListener::debuggeeStopped( const StoppedEvent& event ) {
Log::debug( "DebuggerClientListener::debuggeeStopped: reason %s", event.reason );

mStoppedData = event;

if ( mPausedToRefreshBreakpoints ) {
mPlugin->sendPendingBreakpoints();
mClient->resume( 1 );
mPausedToRefreshBreakpoints = false;
return;
}

mClient->threads();

if ( event.threadId )
mClient->stackTrace( *event.threadId );
}

void DebuggerClientListener::debuggeeContinued( const ContinuedEvent& ) {
mStoppedData = {};

// Reset models
mScope.clear();

getStatusDebuggerController()->getUIThreads()->setModel(
std::make_shared<ThreadsModel>( std::vector<Thread>{} ) );

getStatusDebuggerController()->getUIStack()->setModel(
std::make_shared<StackModel>( StackTraceInfo{} ) );
}

void DebuggerClientListener::outputProduced( const Output& output ) {
if ( Output::Category::Stdout == output.category ||
Output::Category::Stderr == output.category ) {
mPlugin->getManager()->getPluginContext()->getStatusAppOutputController()->insertBuffer(
output.output );
}
}

void DebuggerClientListener::debuggingProcess( const ProcessInfo& ) {}

void DebuggerClientListener::errorResponse( const std::string& /*summary*/,
const std::optional<Message>& /*message*/ ) {}

void DebuggerClientListener::threadChanged( const ThreadEvent& ) {}

void DebuggerClientListener::moduleChanged( const ModuleEvent& ) {}

void DebuggerClientListener::threads( const std::vector<Thread>& threads ) {
getStatusDebuggerController()->getUIThreads()->setModel(
std::make_shared<ThreadsModel>( threads ) );
}

void DebuggerClientListener::stackTrace( const int /*threadId*/, const StackTraceInfo& stack ) {
getStatusDebuggerController()->getUIStack()->setModel( std::make_shared<StackModel>( stack ) );

Expand All @@ -168,17 +191,27 @@ void DebuggerClientListener::stackTrace( const int /*threadId*/, const StackTrac
}
}

void DebuggerClientListener::scopes( const int /*frameId**/, const std::vector<Scope>& scopes ) {
// if ( !scopes.empty() ) {
// mClient->variables( scopes[0].variablesReference );
// }
void DebuggerClientListener::scopes( const int /*frameId*/, const std::vector<Scope>& scopes ) {
if ( !scopes.empty() ) {
for ( const auto& scope : scopes ) {
ModelScope mscope;
mscope.name = scope.name;
mscope.variablesReference = scope.variablesReference;
mScope.emplace_back( std::move( mscope ) );
mClient->variables( scope.variablesReference );
}
}
}

void DebuggerClientListener::variables( const int /*variablesReference*/,
void DebuggerClientListener::variables( const int variablesReference,
const std::vector<Variable>& vars ) {
// if ( !vars.empty() ) {
// mClient->resume( 1 );
// }
auto scopeIt =
std::find_if( mScope.begin(), mScope.end(), [variablesReference]( const ModelScope& cur ) {
return cur.variablesReference == variablesReference;
} );
if ( scopeIt == mScope.end() )
return;
scopeIt->variables = vars;
}

void DebuggerClientListener::modules( const ModulesInfo& ) {}
Expand All @@ -199,14 +232,19 @@ void DebuggerClientListener::expressionEvaluated( const std::string& /*expressio
void DebuggerClientListener::gotoTargets( const Source& /*source*/, const int /*line*/,
const std::vector<GotoTarget>& /*targets*/ ) {}

StatusDebuggerController* DebuggerClientListener::getStatusDebuggerController() const {
bool DebuggerClientListener::isStopped() const {
return mStoppedData ? true : false;
}

std::optional<StoppedEvent> DebuggerClientListener::getStoppedData() const {
return mStoppedData;
}

StatusDebuggerController* DebuggerClientListener::getStatusDebuggerController() const {
auto debuggerElement =
mPlugin->getManager()->getPluginContext()->getStatusBar()->getStatusBarElement(
"status_app_debugger" );

if ( !debuggerElement )
return nullptr;
eeASSERT( debuggerElement );
return static_cast<StatusDebuggerController*>( debuggerElement.get() );
}

Expand Down
18 changes: 18 additions & 0 deletions src/tools/ecode/plugins/debugger/debuggerclientlistener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,17 @@ namespace ecode {

class DebuggerPlugin;

struct ModelScope {
std::string name;
int variablesReference;
std::vector<Variable> variables;
};

class DebuggerClientListener : public DebuggerClient::Listener {
public:
static std::vector<SourceBreakpoint>
fromSet( const EE::UnorderedSet<SourceBreakpointStateful>& set );

DebuggerClientListener( DebuggerClient* client, DebuggerPlugin* plugin );

void stateChanged( DebuggerClient::State );
Expand Down Expand Up @@ -42,9 +51,18 @@ class DebuggerClientListener : public DebuggerClient::Listener {
void gotoTargets( const Source& source, const int line,
const std::vector<GotoTarget>& targets );

bool isStopped() const;

std::optional<StoppedEvent> getStoppedData() const;

void setPausedToRefreshBreakpoints() { mPausedToRefreshBreakpoints = true; }

protected:
DebuggerClient* mClient{ nullptr };
DebuggerPlugin* mPlugin{ nullptr };
std::optional<StoppedEvent> mStoppedData;
std::vector<ModelScope> mScope;
bool mPausedToRefreshBreakpoints{ false };

StatusDebuggerController* getStatusDebuggerController() const;
};
Expand Down
Loading

0 comments on commit c4bd884

Please sign in to comment.