diff --git a/projects/linux/ee.files b/projects/linux/ee.files index b40983524..2563dac2e 100644 --- a/projects/linux/ee.files +++ b/projects/linux/ee.files @@ -1590,6 +1590,8 @@ ../../src/tools/ecode/plugins/debugger/debuggerplugin.hpp ../../src/tools/ecode/plugins/debugger/models/breakpointsmodel.cpp ../../src/tools/ecode/plugins/debugger/models/breakpointsmodel.hpp +../../src/tools/ecode/plugins/debugger/models/processesmodel.cpp +../../src/tools/ecode/plugins/debugger/models/processesmodel.hpp ../../src/tools/ecode/plugins/debugger/models/stackmodel.cpp ../../src/tools/ecode/plugins/debugger/models/stackmodel.hpp ../../src/tools/ecode/plugins/debugger/models/threadsmodel.cpp diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp index a88220a4d..d05e5aa63 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.cpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.cpp @@ -1094,6 +1094,9 @@ DebuggerPlugin::needsToResolveInputs( nlohmann::json& json ) { auto it = mDapInputs.find( id ); if ( it != mDapInputs.end() ) inputs[it->first] = it->second; + } else if ( String::contains( val, "${pid}" ) ) { + DapConfigurationInput dci{ "pid", "Process ID", "pid", "", {} }; + inputs["pid"] = dci; } } }; @@ -1531,6 +1534,29 @@ void DebuggerPlugin::prepareAndRun( DapTool debugger, DapConfig config, } ); } +UIWidget* DebuggerPlugin::processIdPicker() { + static constexpr auto PROCESS_PICKER_LAYOUT = R"html( + + + + + + + + + + + + + + + + )html"; + UIWidget* widget = getUISceneNode()->loadLayoutFromString( PROCESS_PICKER_LAYOUT ); + + return widget; +} + std::optional DebuggerPlugin::debuggerBinaryExists( const std::string& debugger, std::optional optRunConfig ) { diff --git a/src/tools/ecode/plugins/debugger/debuggerplugin.hpp b/src/tools/ecode/plugins/debugger/debuggerplugin.hpp index 389a10647..ca48a38db 100644 --- a/src/tools/ecode/plugins/debugger/debuggerplugin.hpp +++ b/src/tools/ecode/plugins/debugger/debuggerplugin.hpp @@ -236,6 +236,8 @@ class DebuggerPlugin : public PluginBase { void prepareAndRun( DapTool debugger, DapConfig config, std::unordered_map solvedInputs ); + + UIWidget* processIdPicker(); }; } // namespace ecode diff --git a/src/tools/ecode/plugins/debugger/models/processesmodel.cpp b/src/tools/ecode/plugins/debugger/models/processesmodel.cpp new file mode 100644 index 000000000..ed174a799 --- /dev/null +++ b/src/tools/ecode/plugins/debugger/models/processesmodel.cpp @@ -0,0 +1,36 @@ +#include "processesmodel.hpp" +#include + +namespace ecode { + +ProcessesModel::ProcessesModel( std::vector>&& processes, + UISceneNode* sceneNode ) : + mProcesses( std::move( processes ) ), mSceneNode( sceneNode ) {} + +size_t ProcessesModel::rowCount( const ModelIndex& ) const { + return mProcesses.size(); +} + +size_t ProcessesModel::columnCount( const ModelIndex& ) const { + return 2; +} + +std::string ProcessesModel::columnName( const size_t& colIdx ) const { + return colIdx == 0 ? mSceneNode->i18n( "process_id", "Process ID" ) + : mSceneNode->i18n( "command_line", "Command Line" ); +} + +Variant ProcessesModel::data( const ModelIndex& modelIndex, ModelRole role ) const { + switch ( modelIndex.column() ) { + case Columns::Name: + return Variant( mProcesses[modelIndex.row()].second ); + case Columns::ID: + default: + return role == ModelRole::Display + ? Variant( String::toString( mProcesses[modelIndex.row()].first ) ) + : Variant( mProcesses[modelIndex.row()].first ); + } + return {}; +} + +} // namespace ecode diff --git a/src/tools/ecode/plugins/debugger/models/processesmodel.hpp b/src/tools/ecode/plugins/debugger/models/processesmodel.hpp new file mode 100644 index 000000000..aaf9d68fe --- /dev/null +++ b/src/tools/ecode/plugins/debugger/models/processesmodel.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include + +using namespace EE; +using namespace EE::UI; +using namespace EE::UI::Models; + +namespace EE::UI { +class UISceneNode; +} + +namespace ecode { + +class ProcessesModel : public Model { + public: + enum Columns { ID, Name }; + + ProcessesModel( std::vector>&& processes, + UISceneNode* sceneNode ); + + virtual size_t rowCount( const ModelIndex& ) const; + + virtual size_t columnCount( const ModelIndex& ) const; + + virtual std::string columnName( const size_t& colIdx ) const; + + virtual Variant data( const ModelIndex& modelIndex, ModelRole role ) const; + + protected: + std::vector> mProcesses; + UISceneNode* mSceneNode{ nullptr }; +}; + +} // namespace ecode diff --git a/src/tools/ecode/projectdirectorytree.cpp b/src/tools/ecode/projectdirectorytree.cpp index 2afb70b2d..389f516cd 100644 --- a/src/tools/ecode/projectdirectorytree.cpp +++ b/src/tools/ecode/projectdirectorytree.cpp @@ -46,7 +46,10 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& Lock l( mFilesMutex ); mRunning = true; mIgnoreHidden = ignoreHidden; - mDirectories.push_back( mPath ); + { + Lock ld( mDirectoriesMutex ); + mDirectories.push_back( mPath ); + } if ( !mAllowedMatcher && FileSystem::fileExists( mPath + PRJ_ALLOWED_PATH ) ) mAllowedMatcher = @@ -293,20 +296,26 @@ size_t ProjectDirectoryTree::getFilesCount() const { return mFiles.size(); } -const std::vector& ProjectDirectoryTree::getFiles() const { +std::vector ProjectDirectoryTree::getFiles() const { Lock l( mFilesMutex ); return mFiles; } -const std::vector& ProjectDirectoryTree::getDirectories() const { +std::vector ProjectDirectoryTree::getDirectories() const { + Lock l( mDirectoriesMutex ); return mDirectories; } bool ProjectDirectoryTree::isFileInTree( const std::string& filePath ) const { + Lock l( mFilesMutex ); return std::find( mFiles.begin(), mFiles.end(), filePath ) != mFiles.end(); } bool ProjectDirectoryTree::isDirInTree( const std::string& dirTree ) const { + if ( mRunning ) { + return String::startsWith( dirTree, mPath ); + } + Lock l( mDirectoriesMutex ); std::string dir( FileSystem::fileRemoveFileName( dirTree ) ); FileSystem::dirAddSlashAtEnd( dir ); return std::find( mDirectories.begin(), mDirectories.end(), dir ) != mDirectories.end(); @@ -340,11 +349,15 @@ void ProjectDirectoryTree::getDirectoryFiles( FileSystem::dirAddSlashAtEnd( fullpath ); if ( currentDirs.find( fullpath ) == currentDirs.end() ) continue; - if ( std::find( mDirectories.begin(), mDirectories.end(), fullpath ) != - mDirectories.end() ) - continue; - mDirectories.push_back( fullpath ); + { + Lock ld( mDirectoriesMutex ); + if ( std::find( mDirectories.begin(), mDirectories.end(), fullpath ) != + mDirectories.end() ) + continue; + mDirectories.push_back( fullpath ); + } } else { + Lock ld( mDirectoriesMutex ); mDirectories.push_back( fullpath ); } IgnoreMatcherManager dirMatcher( fullpath ); @@ -463,6 +476,8 @@ void ProjectDirectoryTree::moveFile( const FileInfo& file, const std::string& ol FileSystem::dirAddSlashAtEnd( oldDir ); std::vector files; std::vector names; + files.reserve( mFiles.size() ); + names.reserve( mFiles.size() ); for ( size_t i = 0; i < mFiles.size(); i++ ) { if ( !String::startsWith( mFiles[i], oldDir ) ) { files.emplace_back( mFiles[i] ); @@ -473,12 +488,15 @@ void ProjectDirectoryTree::moveFile( const FileInfo& file, const std::string& ol names.emplace_back( FileSystem::fileNameFromPath( newDir ) ); } } - mFiles = files; - mNames = names; - auto wasDirIt = std::find( mDirectories.begin(), mDirectories.end(), oldDir ); - if ( wasDirIt != mDirectories.end() ) - mDirectories.erase( wasDirIt ); - mDirectories.emplace_back( std::move( dir ) ); + mFiles = std::move( files ); + mNames = std::move( names ); + { + Lock ld( mDirectoriesMutex ); + auto wasDirIt = std::find( mDirectories.begin(), mDirectories.end(), oldDir ); + if ( wasDirIt != mDirectories.end() ) + mDirectories.erase( wasDirIt ); + mDirectories.emplace_back( std::move( dir ) ); + } } else { std::string dir( file.getDirectoryPath() ); FileSystem::dirAddSlashAtEnd( dir ); @@ -500,25 +518,40 @@ void ProjectDirectoryTree::moveFile( const FileInfo& file, const std::string& ol } void ProjectDirectoryTree::removeFile( const FileInfo& file ) { - Lock l( mFilesMutex ); std::string removedDir( file.getFilepath() ); FileSystem::dirAddSlashAtEnd( removedDir ); - auto wasDirIt = std::find( mDirectories.begin(), mDirectories.end(), removedDir ); - if ( wasDirIt != mDirectories.end() ) { + + bool wasDir = false; + { + Lock ld( mDirectoriesMutex ); + auto wasDirIt = std::find( mDirectories.begin(), mDirectories.end(), removedDir ); + wasDir = wasDirIt != mDirectories.end(); + } + + if ( wasDir ) { std::vector files; std::vector names; + files.reserve( mFiles.size() ); + names.reserve( mNames.size() ); for ( size_t i = 0; i < mFiles.size(); i++ ) { if ( !String::startsWith( mFiles[i], removedDir ) ) { files.emplace_back( mFiles[i] ); names.emplace_back( mNames[i] ); } } - mFiles = files; - mNames = names; - mDirectories.erase( wasDirIt ); + + { + Lock l( mFilesMutex ); + mFiles = std::move( files ); + mNames = std::move( names ); + } + + Lock ld2( mDirectoriesMutex ); + mDirectories.erase( std::find( mDirectories.begin(), mDirectories.end(), removedDir ) ); } else { size_t index = findFileIndex( file.getFilepath() ); if ( index != std::string::npos ) { + Lock l( mFilesMutex ); mFiles.erase( mFiles.begin() + index ); mNames.erase( mNames.begin() + index ); } diff --git a/src/tools/ecode/projectdirectorytree.hpp b/src/tools/ecode/projectdirectorytree.hpp index aa4b1c540..36faea163 100644 --- a/src/tools/ecode/projectdirectorytree.hpp +++ b/src/tools/ecode/projectdirectorytree.hpp @@ -151,9 +151,9 @@ class ProjectDirectoryTree { size_t getFilesCount() const; - const std::vector& getFiles() const; + std::vector getFiles() const; - const std::vector& getDirectories() const; + std::vector getDirectories() const; bool isFileInTree( const std::string& filePath ) const; @@ -165,6 +165,8 @@ class ProjectDirectoryTree { void resetPluginManager(); + bool isRunning() const { return mRunning; } + protected: std::string mPath; std::shared_ptr mPool; @@ -178,6 +180,7 @@ class ProjectDirectoryTree { bool mIgnoreHidden; bool mClosing; mutable Mutex mFilesMutex; + mutable Mutex mDirectoriesMutex; mutable Mutex mMatchingMutex; Mutex mDoneMutex; IgnoreMatcherManager mIgnoreMatcher;