Skip to content

Commit

Permalink
WIP expanded scope childs persistency (not working).
Browse files Browse the repository at this point in the history
Fix enable/disable vertical scrollbar in editor not updating line-wrap.
  • Loading branch information
SpartanJ committed Jan 14, 2025
1 parent 0e5337d commit 4913443
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/eepp/ui/uicodeeditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3407,6 +3407,7 @@ bool UICodeEditor::getVerticalScrollBarEnabled() const {
void UICodeEditor::setVerticalScrollBarEnabled( const bool& verticalScrollBarEnabled ) {
if ( verticalScrollBarEnabled != mVerticalScrollBarEnabled ) {
mVerticalScrollBarEnabled = verticalScrollBarEnabled;
invalidateLongestLineWidth();
updateScrollBar();
}
}
Expand Down
11 changes: 11 additions & 0 deletions src/tools/ecode/plugins/debugger/debuggerclientlistener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ void DebuggerClientListener::initUI() {
ModelVariableNode* node =
static_cast<ModelVariableNode*>( modelEvent->getModelIndex().internalData() );
mClient->variables( node->var.variablesReference );
mVariablesHolder->saveExpandedState( modelEvent->getModelIndex() );
}
} );

Expand Down Expand Up @@ -277,6 +278,9 @@ void DebuggerClientListener::scopes( const int /*frameId*/, std::vector<Scope>&&
mClient->variables( scope.variablesReference );
}

for ( auto& scope : scopes )
mScopeRef[scope.variablesReference] = std::move( scope );

auto sdc = getStatusDebuggerController();
if ( nullptr == sdc )
return;
Expand All @@ -293,6 +297,13 @@ void DebuggerClientListener::scopes( const int /*frameId*/, std::vector<Scope>&&
void DebuggerClientListener::variables( const int variablesReference,
std::vector<Variable>&& vars ) {
mVariablesHolder->addVariables( variablesReference, std::move( vars ) );

auto scopeIt = mScopeRef.find( variablesReference );
if ( mCurrentScopePos && scopeIt != mScopeRef.end() ) {
ExpandedState::Location location{ mCurrentScopePos->first, mCurrentScopePos->second,
mCurrentFrameId };
mVariablesHolder->restoreExpandedState( location, mClient );
}
}

void DebuggerClientListener::modules( ModulesInfo&& ) {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class DebuggerClientListener : public DebuggerClient::Listener {
std::shared_ptr<ThreadsModel> mThreadsModel;
std::shared_ptr<StackModel> mStackModel;
std::shared_ptr<VariablesHolder> mVariablesHolder;
std::unordered_map<int, Scope> mScopeRef;

StatusDebuggerController* getStatusDebuggerController() const;

Expand Down
85 changes: 85 additions & 0 deletions src/tools/ecode/plugins/debugger/models/variablesmodel.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "variablesmodel.hpp"
#include "../debuggerclient.hpp"
#include <eepp/ui/uiscenenode.hpp>

namespace ecode {
Expand Down Expand Up @@ -240,4 +241,88 @@ ModelVariableNode::NodePtr VariablesHolder::getNodeByReference( int variablesRef
return ( it != nodeMap.end() ) ? it->second : nullptr;
}

VariablePath VariablesHolder::buildVariablePath( ModelVariableNode* node ) const {
VariablePath path;
std::vector<std::string> reversePath;

// Build the path from node to root
while ( node && node != rootNode.get() ) {
reversePath.push_back( node->getName() );
node = node->parent ? node->parent.get() : nullptr;
}

if ( reversePath.size() >= 2 ) {
path.scopeName = reversePath.back(); // The scope name is at the root
path.variableName = reversePath[reversePath.size() - 2]; // The variable name is next

// Add any remaining path components as child path
path.childPath.assign( reversePath.begin(), reversePath.end() - 2 );
}

return path;
}

void VariablesHolder::saveExpandedState( const ModelIndex& index ) {
if ( !currentLocation )
return;

ModelVariableNode* node = static_cast<ModelVariableNode*>( index.internalData() );
if ( !node )
return;

auto nodePath = buildVariablePath( node );
expandedStates[*currentLocation].insert( std::move( nodePath ) );
}

void VariablesHolder::restoreExpandedState( const ExpandedState::Location& location,
DebuggerClient* client ) {
currentLocation = location;

auto it = expandedStates.find( location );
if ( it == expandedStates.end() )
return;

const auto& paths = it->second;

for ( const auto& path : paths ) {
// Find the scope node
auto scopeNode = [this, &path]() -> ModelVariableNode::NodePtr {
for ( const auto& child : rootNode->children ) {
if ( child->getName() == path.scopeName ) {
return child;
}
}
return nullptr;
}();

if ( !scopeNode )
continue;

// Find the variable node
auto currentNode = [&path, scopeNode]() -> ModelVariableNode::NodePtr {
for ( const auto& child : scopeNode->children ) {
if ( child->getName() == path.variableName ) {
return child;
}
}
return nullptr;
}();

if ( !currentNode )
continue;

if ( currentNode->getVariablesReference() > 0 )
client->variables( currentNode->getVariablesReference() );

for ( const auto& childName : path.childPath ) {
auto childOpt = currentNode->getChild( childName );
if ( !childOpt )
break;

currentNode = *childOpt;
if ( currentNode->getVariablesReference() > 0 )
client->variables( currentNode->getVariablesReference() );
}
}
}
} // namespace ecode
68 changes: 68 additions & 0 deletions src/tools/ecode/plugins/debugger/models/variablesmodel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,67 @@ namespace ecode {

using namespace dap;

class DebuggerClient;

struct VariablePath {
std::string scopeName;
std::string variableName;
std::vector<std::string> childPath;

bool operator==( const VariablePath& other ) const {
return scopeName == other.scopeName && variableName == other.variableName &&
childPath == other.childPath;
}
};

} // namespace ecode

namespace std {
template <> struct hash<ecode::VariablePath> {
size_t operator()( const ecode::VariablePath& path ) const {
size_t h = std::hash<std::string>{}( path.scopeName );
h ^= std::hash<std::string>{}( path.variableName ) + 0x9e3779b9 + ( h << 6 ) + ( h >> 2 );
for ( const auto& child : path.childPath ) {
h ^= std::hash<std::string>{}( child ) + 0x9e3779b9 + ( h << 6 ) + ( h >> 2 );
}
return h;
}
};

} // namespace std

namespace ecode {

struct ExpandedState {
struct Location {
std::string filePath;
int lineNumber{};
int frameIndex{};

bool operator==( const Location& other ) const {
return filePath == other.filePath && lineNumber == other.lineNumber &&
frameIndex == other.frameIndex;
}
};

Location location;
std::unordered_set<VariablePath> expandedPaths;
};

} // namespace ecode

namespace std {
template <> struct hash<ecode::ExpandedState::Location> {
size_t operator()( const ecode::ExpandedState::Location& loc ) const {
return hashCombine( std::hash<std::string>{}( loc.filePath ),
std::hash<int>{}( loc.lineNumber ),
std::hash<int>{}( loc.frameIndex ) );
}
};
} // namespace std

namespace ecode {

struct ModelVariableNode : public std::enable_shared_from_this<ModelVariableNode> {
using NodePtr = std::shared_ptr<ModelVariableNode>;

Expand Down Expand Up @@ -89,6 +150,13 @@ struct VariablesHolder {
std::shared_ptr<ModelVariableNode> rootNode;
std::shared_ptr<VariablesModel> model;
std::unordered_map<int, ModelVariableNode::NodePtr> nodeMap;

std::unordered_map<ExpandedState::Location, std::unordered_set<VariablePath>> expandedStates;
std::optional<ExpandedState::Location> currentLocation;

VariablePath buildVariablePath( ModelVariableNode* node ) const;
void saveExpandedState( const ModelIndex& index );
void restoreExpandedState( const ExpandedState::Location& location, DebuggerClient* client );
};

} // namespace ecode

0 comments on commit 4913443

Please sign in to comment.