From 5aef110bda06aaedd9d4ef5239fcbe146ccb242b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Fri, 10 Mar 2023 02:37:01 -0300 Subject: [PATCH] Ups, staged the wrong files: Improved ThreadPool. ecode: Make consistent the find/search highlighting with the actual results (Closes SpartanJ/ecode#73). Fixed $NPROC in LSP client commands. --- bin/assets/plugins/lspclient.json | 2 +- include/eepp/system/threadpool.hpp | 20 +++- include/eepp/ui/doc/textdocument.hpp | 24 +++++ include/eepp/ui/tools/uidocfindreplace.hpp | 23 +--- include/eepp/ui/uicodeeditor.hpp | 14 ++- include/eepp/ui/uiscenenode.hpp | 8 ++ src/eepp/system/resourceloader.cpp | 2 +- src/eepp/system/threadpool.cpp | 50 ++++++++- src/eepp/ui/doc/textdocument.cpp | 34 +++--- src/eepp/ui/tools/uidocfindreplace.cpp | 14 +-- src/eepp/ui/uicodeeditor.cpp | 102 +++++++++++++++--- src/eepp/ui/uiscenenode.cpp | 12 +++ src/tools/ecode/docsearchcontroller.cpp | 10 +- src/tools/ecode/docsearchcontroller.hpp | 4 + src/tools/ecode/ecode.cpp | 29 +++-- .../autocomplete/autocompleteplugin.cpp | 15 ++- .../plugins/formatter/formatterplugin.cpp | 2 +- .../ecode/plugins/linter/linterplugin.cpp | 4 +- .../ecode/plugins/lsp/lspclientplugin.cpp | 4 +- .../plugins/lsp/lspclientservermanager.cpp | 2 +- src/tools/ecode/projectdirectorytree.cpp | 6 +- src/tools/ecode/projectsearch.cpp | 2 +- 22 files changed, 277 insertions(+), 106 deletions(-) diff --git a/bin/assets/plugins/lspclient.json b/bin/assets/plugins/lspclient.json index 95771857c..219376e45 100644 --- a/bin/assets/plugins/lspclient.json +++ b/bin/assets/plugins/lspclient.json @@ -53,7 +53,7 @@ "language": "c", "name": "clangd", "url": "https://clang.llvm.org/extra/clangd/", - "command": "clangd -log=error --background-index --header-insertion=never --limit-results=0 --limit-references=0 --clang-tidy=0 --use-dirty-headers --completion-style=bundled -j=$NPROC", + "command": "clangd -log=error --background-index --header-insertion=never --limit-results=0 --limit-references=0 --clang-tidy=0 --use-dirty-headers --completion-style=bundled -j $NPROC", "file_patterns": ["%.c$", "%.h$", "%.C$", "%.H$", "%.objc$"] }, { diff --git a/include/eepp/system/threadpool.hpp b/include/eepp/system/threadpool.hpp index 803318e3e..88c219058 100644 --- a/include/eepp/system/threadpool.hpp +++ b/include/eepp/system/threadpool.hpp @@ -1,6 +1,7 @@ #ifndef EE_SYSTEM_THREADPOOL_HPP #define EE_SYSTEM_THREADPOOL_HPP +#include #include #include #include @@ -27,8 +28,10 @@ class EE_API ThreadPool : NonCopyable { virtual ~ThreadPool(); - void run( - const std::function& func, const std::function& doneCallback = []() {} ); + Uint64 run( + const std::function& func, + const std::function& doneCallback = []( const Uint64& ) {}, + const Uint64& tag = 0 ); Uint32 numThreads() const; @@ -36,16 +39,27 @@ class EE_API ThreadPool : NonCopyable { void setTerminateOnClose( bool terminateOnClose ); + bool existsIdInQueue( const Uint64& id ); + + bool existsTagInQueue( const Uint64& tag ); + + bool removeId( const Uint64& id ); + + bool removeWithTag( const Uint64& tag ); + private: struct Work { + Uint64 id{ 0 }; const std::function func; - const std::function callback; + const std::function callback; + Uint64 tag{ 0 }; }; void threadFunc(); std::vector> mThreads; std::deque> mWork; + std::atomic mLastWorkId; bool mShuttingDown = false; bool mTerminateOnClose = false; mutable std::mutex mMutex; diff --git a/include/eepp/ui/doc/textdocument.hpp b/include/eepp/ui/doc/textdocument.hpp index ce5577222..6d8e6ae50 100644 --- a/include/eepp/ui/doc/textdocument.hpp +++ b/include/eepp/ui/doc/textdocument.hpp @@ -653,6 +653,30 @@ class EE_API TextDocument { TextRange restrictRange = TextRange() ); }; +struct TextSearchParams { + String text; + TextRange range = TextRange(); + bool caseSensitive{ false }; + bool wholeWord{ false }; + bool escapeSequences{ false }; + TextDocument::FindReplaceType type{ TextDocument::FindReplaceType::Normal }; + + bool operator==( const TextSearchParams& other ) { + return text == other.text && range == other.range && caseSensitive == other.caseSensitive && + wholeWord == other.wholeWord && escapeSequences == other.escapeSequences && + type == other.type; + } + + bool operator!=( const TextSearchParams& other ) { return !( *this == other ); } + + bool isEmpty() { return text.empty(); } + + void reset() { + range = TextRange(); + text = ""; + } +}; + }}} // namespace EE::UI::Doc #endif diff --git a/include/eepp/ui/tools/uidocfindreplace.hpp b/include/eepp/ui/tools/uidocfindreplace.hpp index 3b3aed9f2..2bc7d961c 100644 --- a/include/eepp/ui/tools/uidocfindreplace.hpp +++ b/include/eepp/ui/tools/uidocfindreplace.hpp @@ -40,19 +40,6 @@ class EE_API UIDocFindReplace : public UILinearLayout, public WidgetCommandExecu virtual void hide(); protected: - struct SearchState { - String text; - TextRange range = TextRange(); - bool caseSensitive{ false }; - bool wholeWord{ false }; - bool escapeSequences{ false }; - TextDocument::FindReplaceType type{ TextDocument::FindReplaceType::Normal }; - void reset() { - range = TextRange(); - text = ""; - } - }; - bool mReady{ false }; UITextInput* mFindInput{ nullptr }; UITextInput* mReplaceInput{ nullptr }; @@ -70,16 +57,16 @@ class EE_API UIDocFindReplace : public UILinearLayout, public WidgetCommandExecu UIWidget* parent, const std::shared_ptr& doc, std::unordered_map keybindings = getDefaultKeybindings() ); - SearchState mSearchState; + TextSearchParams mSearchState; String mLastSearch; - bool findAndReplace( SearchState& search, const String& replace ); + bool findAndReplace( TextSearchParams& search, const String& replace ); - bool findPrevText( SearchState& search ); + bool findPrevText( TextSearchParams& search ); - bool findNextText( SearchState& search ); + bool findNextText( TextSearchParams& search ); - int replaceAll( SearchState& search, const String& replace ); + int replaceAll( TextSearchParams& search, const String& replace ); virtual Uint32 onKeyDown( const KeyEvent& event ); }; diff --git a/include/eepp/ui/uicodeeditor.hpp b/include/eepp/ui/uicodeeditor.hpp index 1104e5951..58a63c10e 100644 --- a/include/eepp/ui/uicodeeditor.hpp +++ b/include/eepp/ui/uicodeeditor.hpp @@ -426,9 +426,9 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { void setShowWhitespaces( const bool& showWhitespaces ); - const String& getHighlightWord() const; + const TextSearchParams& getHighlightWord() const; - void setHighlightWord( const String& highlightWord ); + void setHighlightWord( const TextSearchParams& highlightWord ); const TextRange& getHighlightTextRange() const; @@ -628,6 +628,7 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { bool mAutoCloseXMLTags{ false }; bool mFindReplaceEnabled{ true }; bool mShowIndentationGuides{ false }; + std::atomic mHighlightWordProcessing{ false }; TextRange mLinkPosition; String mLink; Uint32 mTabWidth; @@ -666,7 +667,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { Float mLongestLineWidth{ 0 }; Time mFindLongestLineWidthUpdateFrequency; Clock mLongestLineWidthLastUpdate; - String mHighlightWord; + TextSearchParams mHighlightWord; + TextRanges mHighlightWordCache; TextRange mHighlightTextRange; Color mPreviewColor; TextRange mPreviewColorRange; @@ -859,6 +861,12 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client { bool createContextMenu(); bool stopMinimapDragging( const Vector2f& mousePos ); + + void drawWordRanges( const TextRanges& ranges, const std::pair& lineRange, + const Vector2f& startScroll, const Float& lineHeight, + bool ignoreSelectionMatch ); + + void updateHighlightWordCache(); }; }} // namespace EE::UI diff --git a/include/eepp/ui/uiscenenode.hpp b/include/eepp/ui/uiscenenode.hpp index 83acf776e..2a8d1adbc 100644 --- a/include/eepp/ui/uiscenenode.hpp +++ b/include/eepp/ui/uiscenenode.hpp @@ -2,6 +2,7 @@ #define EE_UISCENENODE_HPP #include +#include #include #include #include @@ -158,6 +159,12 @@ class EE_API UISceneNode : public SceneNode { void reloadStyle( bool disableAnimations = false, bool forceReApplyProperties = false ); + bool hasThreadPool() const; + + std::shared_ptr getThreadPool(); + + void setThreadPool( const std::shared_ptr& threadPool ); + protected: friend class EE::UI::UIWindow; friend class EE::UI::UIWidget; @@ -184,6 +191,7 @@ class EE_API UISceneNode : public SceneNode { Uint32 mMaxInvalidationDepth{ 2 }; Node* mCurParent{ nullptr }; Uint32 mCurOnSizeChangeListener{ 0 }; + std::shared_ptr mThreadPool; virtual void resizeNode( EE::Window::Window* win ); diff --git a/src/eepp/system/resourceloader.cpp b/src/eepp/system/resourceloader.cpp index 5db271a46..9da67b1dc 100644 --- a/src/eepp/system/resourceloader.cpp +++ b/src/eepp/system/resourceloader.cpp @@ -109,7 +109,7 @@ void ResourceLoader::taskRunner() { auto pool = ThreadPool::createUnique( eemin( mThreads, (Uint32)mTasks.size() ) ); for ( auto& task : mTasks ) { - pool->run( task, [&] { mTotalLoaded++; } ); + pool->run( task, [&]( const auto& ) { mTotalLoaded++; } ); } } diff --git a/src/eepp/system/threadpool.cpp b/src/eepp/system/threadpool.cpp index 0f2cb47fc..cb96ab624 100644 --- a/src/eepp/system/threadpool.cpp +++ b/src/eepp/system/threadpool.cpp @@ -60,7 +60,7 @@ void ThreadPool::threadFunc() { work->func(); if ( work->callback != nullptr ) { - work->callback(); + work->callback( work->id ); } } } @@ -73,18 +73,58 @@ void ThreadPool::setTerminateOnClose( bool terminateOnClose ) { mTerminateOnClose = terminateOnClose; } -void ThreadPool::run( const std::function& func, - const std::function& doneCallback ) { +bool ThreadPool::existsIdInQueue( const Uint64& id ) { + std::unique_lock lock( mMutex ); + return std::any_of( mWork.begin(), mWork.end(), + [id]( const std::unique_ptr& work ) { return work->id == id; } ); +} + +bool ThreadPool::existsTagInQueue( const Uint64& tag ) { + std::unique_lock lock( mMutex ); + return std::any_of( mWork.begin(), mWork.end(), + [tag]( const std::unique_ptr& work ) { return work->tag == tag; } ); +} + +bool ThreadPool::removeId( const Uint64& id ) { + std::unique_lock lock( mMutex ); + for ( auto it = mWork.begin(); it != mWork.end(); ++it ) { + if ( it->get()->id == id ) { + mWork.erase( it ); + return true; + } + } + return false; +} + +bool ThreadPool::removeWithTag( const Uint64& tag ) { + std::vector ids; + { + std::unique_lock lock( mMutex ); + for ( const auto& work : mWork ) + if ( work->tag == tag ) + ids.emplace_back( work->id ); + } + for ( const auto& id : ids ) + removeId( id ); + return !ids.empty(); +} + +Uint64 ThreadPool::run( const std::function& func, + const std::function& doneCallback, + const Uint64& tag ) { + Uint64 id = ++mLastWorkId; { std::unique_lock lock( mMutex ); if ( mShuttingDown ) - return; + return id; - mWork.emplace_back( new Work{ func, doneCallback } ); + mWork.emplace_back( new Work{ id, func, doneCallback, tag } ); } mWorkAvailable.notify_one(); + + return id; } Uint32 ThreadPool::numThreads() const { diff --git a/src/eepp/ui/doc/textdocument.cpp b/src/eepp/ui/doc/textdocument.cpp index 4446e6cec..231cf0e99 100644 --- a/src/eepp/ui/doc/textdocument.cpp +++ b/src/eepp/ui/doc/textdocument.cpp @@ -391,21 +391,19 @@ bool TextDocument::loadAsyncFromFile( const std::string& path, std::shared_ptrrun( - [this, path, onLoaded] { - auto loaded = loadFromFile( path ); - if ( loaded != LoadStatus::Interrupted && onLoaded ) { - onLoaded( this, loaded == LoadStatus::Loaded ); - } - { - Lock l( mLoadingFilePathMutex ); - mLoadingFilePath.clear(); - mLoadingFileURI = URI(); - } - mLoadingAsync = false; - notifyDocumentLoaded(); - }, - [] {} ); + pool->run( [this, path, onLoaded] { + auto loaded = loadFromFile( path ); + if ( loaded != LoadStatus::Interrupted && onLoaded ) { + onLoaded( this, loaded == LoadStatus::Loaded ); + } + { + Lock l( mLoadingFilePathMutex ); + mLoadingFilePath.clear(); + mLoadingFileURI = URI(); + } + mLoadingAsync = false; + notifyDocumentLoaded(); + } ); return true; } @@ -2032,7 +2030,7 @@ TextRange TextDocument::findText( String text, TextPosition from, const bool& ca return TextRange(); } - if ( !caseSensitive ) + if ( !caseSensitive && type != FindReplaceType::LuaPattern ) text.toLower(); for ( Int64 i = from.line(); i <= to.line(); i++ ) { @@ -2081,7 +2079,7 @@ TextRange TextDocument::findTextLast( String text, TextPosition from, const bool return TextRange(); } - if ( !caseSensitive ) + if ( !caseSensitive && type != FindReplaceType::LuaPattern ) text.toLower(); for ( Int64 i = from.line(); i >= to.line(); i-- ) { @@ -2279,6 +2277,8 @@ TextRanges TextDocument::findAll( const String& text, const bool& caseSensitive, do { found = find( text, from, caseSensitive, wholeWord, type, restrictRange ); if ( found.isValid() ) { + if ( !all.empty() && all.back() == found ) + break; from = found.end(); all.push_back( found ); } diff --git a/src/eepp/ui/tools/uidocfindreplace.cpp b/src/eepp/ui/tools/uidocfindreplace.cpp index 5d7eca275..ff6d26c72 100644 --- a/src/eepp/ui/tools/uidocfindreplace.cpp +++ b/src/eepp/ui/tools/uidocfindreplace.cpp @@ -203,7 +203,7 @@ UIDocFindReplace::UIDocFindReplace( UIWidget* parent, const std::shared_ptraddEventListener( Event::OnTextChanged, [&, editor]( const Event* ) { mSearchState.text = mFindInput->getText(); if ( editor ) - editor->setHighlightWord( mSearchState.text ); + editor->setHighlightWord( mSearchState ); if ( !mSearchState.text.empty() ) { mDoc->setSelection( { 0, 0 } ); if ( !findNextText( mSearchState ) ) { @@ -374,7 +374,7 @@ void UIDocFindReplace::show( bool expanded ) { if ( editor ) { editor->setHighlightTextRange( mSearchState.range ); - editor->setHighlightWord( mSearchState.text ); + editor->setHighlightWord( mSearchState ); mDoc->setActiveClient( editor ); } } @@ -391,14 +391,14 @@ void UIDocFindReplace::hide() { mSearchState.range = TextRange(); mSearchState.text = ""; if ( editor ) { - editor->setHighlightWord( "" ); + editor->setHighlightWord( { "" } ); editor->setHighlightTextRange( TextRange() ); } getParent()->setFocus(); } -bool UIDocFindReplace::findPrevText( SearchState& search ) { +bool UIDocFindReplace::findPrevText( TextSearchParams& search ) { if ( search.text.empty() ) search.text = mLastSearch; @@ -433,7 +433,7 @@ bool UIDocFindReplace::findPrevText( SearchState& search ) { return false; } -bool UIDocFindReplace::findNextText( SearchState& search ) { +bool UIDocFindReplace::findNextText( TextSearchParams& search ) { if ( search.text.empty() ) search.text = mLastSearch; @@ -469,7 +469,7 @@ bool UIDocFindReplace::findNextText( SearchState& search ) { return false; } -int UIDocFindReplace::replaceAll( SearchState& search, const String& replace ) { +int UIDocFindReplace::replaceAll( TextSearchParams& search, const String& replace ) { if ( search.text.empty() ) search.text = mLastSearch; if ( search.text.empty() ) @@ -495,7 +495,7 @@ Uint32 UIDocFindReplace::onKeyDown( const KeyEvent& event ) { return WidgetCommandExecuter::onKeyDown( event ); } -bool UIDocFindReplace::findAndReplace( SearchState& search, const String& replace ) { +bool UIDocFindReplace::findAndReplace( TextSearchParams& search, const String& replace ) { if ( search.text.empty() ) search.text = mLastSearch; if ( search.text.empty() ) diff --git a/src/eepp/ui/uicodeeditor.cpp b/src/eepp/ui/uicodeeditor.cpp index b72ba6c10..6698597d5 100644 --- a/src/eepp/ui/uicodeeditor.cpp +++ b/src/eepp/ui/uicodeeditor.cpp @@ -173,6 +173,10 @@ UICodeEditor::~UICodeEditor() { for ( auto& plugin : mPlugins ) plugin->onUnregister( this ); + // TODO: Use a condition variable to wait the thread pool to finish + while ( mHighlightWordProcessing ) + Sys::sleep( Milliseconds( 1 ) ); + if ( mDoc.use_count() == 1 ) { DocEvent event( this, mDoc.get(), Event::OnDocumentClosed ); sendEvent( &event ); @@ -285,9 +289,8 @@ void UICodeEditor::draw() { } } - if ( !mHighlightWord.empty() ) { - drawWordMatch( mHighlightWord, lineRange, startScroll, lineHeight ); - } + if ( !mHighlightWord.isEmpty() ) + drawWordRanges( mHighlightWordCache, lineRange, startScroll, lineHeight, true ); if ( mShowIndentationGuides ) { drawIndentationGuides( lineRange, startScroll, lineHeight ); @@ -1562,6 +1565,9 @@ void UICodeEditor::onDocumentLineChanged( const Int64& lineNumber ) { mDoc->getHighlighter()->invalidate( lineNumber ); if ( mFont && !mFont->isMonospace() ) updateLineCache( lineNumber ); + + if ( !mHighlightWord.isEmpty() ) + updateHighlightWordCache(); } void UICodeEditor::onDocumentUndoRedo( const TextDocument::UndoRedo& ) { @@ -2470,13 +2476,33 @@ void UICodeEditor::setShowWhitespaces( const bool& showWhitespaces ) { } } -const String& UICodeEditor::getHighlightWord() const { +const TextSearchParams& UICodeEditor::getHighlightWord() const { return mHighlightWord; } -void UICodeEditor::setHighlightWord( const String& highlightWord ) { +void UICodeEditor::updateHighlightWordCache() { + if ( getUISceneNode()->hasThreadPool() ) { + Uint64 tag = reinterpret_cast( this ); + getUISceneNode()->getThreadPool()->removeWithTag( tag ); + getUISceneNode()->getThreadPool()->run( + [this]() { + mHighlightWordProcessing = true; + mHighlightWordCache = mDoc->findAll( + mHighlightWord.text, mHighlightWord.caseSensitive, mHighlightWord.wholeWord, + mHighlightWord.type, mHighlightWord.range ); + }, + [this]( const auto& ) { mHighlightWordProcessing = false; }, tag ); + } else { + mHighlightWordCache = + mDoc->findAll( mHighlightWord.text, mHighlightWord.caseSensitive, + mHighlightWord.wholeWord, mHighlightWord.type, mHighlightWord.range ); + } +} + +void UICodeEditor::setHighlightWord( const TextSearchParams& highlightWord ) { if ( mHighlightWord != highlightWord ) { mHighlightWord = highlightWord; + updateHighlightWordCache(); invalidateDraw(); } } @@ -2572,6 +2598,43 @@ void UICodeEditor::drawSelectionMatch( const std::pair& lineRange, } } +void UICodeEditor::drawWordRanges( const TextRanges& ranges, const std::pair& lineRange, + const Vector2f& startScroll, const Float& lineHeight, + bool ignoreSelectionMatch ) { + if ( ranges.empty() ) + return; + Primitives primitives; + primitives.setForceDraw( false ); + primitives.setColor( Color( mSelectionMatchColor ).blendAlpha( mAlpha ) ); + TextRange selection = mDoc->getSelection( true ); + + for ( const auto& range : ranges ) { + if ( !( range.start().line() >= lineRange.first && + range.end().line() <= lineRange.second ) ) + continue; + + if ( ignoreSelectionMatch && selection.inSameLine() && + selection.start().line() == range.start().line() && + selection.start().column() == range.start().column() ) { + continue; + } + + if ( !range.inSameLine() ) + continue; + + Rectf selRect; + Int64 startCol = range.start().column(); + Int64 endCol = range.end().column(); + selRect.Top = startScroll.y + range.start().line() * lineHeight; + selRect.Bottom = selRect.Top + lineHeight; + selRect.Left = startScroll.x + getXOffsetCol( { range.start().line(), startCol } ); + selRect.Right = startScroll.x + getXOffsetCol( { range.start().line(), endCol } ); + primitives.drawRectangle( selRect ); + } + + primitives.setForceDraw( true ); +} + void UICodeEditor::drawWordMatch( const String& text, const std::pair& lineRange, const Vector2f& startScroll, const Float& lineHeight, bool ignoreSelectionMatch ) { @@ -3267,6 +3330,23 @@ void UICodeEditor::drawMinimap( const Vector2f& start, primitives.drawRectangle( selRect ); }; + auto drawWordRanges = [&]( const TextRanges& ranges ) { + primitives.setColor( Color( mMinimapHighlightColor ).blendAlpha( mAlpha ) ); + + for ( const auto& range : ranges ) { + if ( !( range.start().line() >= minimapStartLine && range.end().line() <= endidx ) || + !range.inSameLine() ) + continue; + + Rectf selRect; + selRect.Top = rect.Top + ( range.start().line() - minimapStartLine ) * lineSpacing; + selRect.Bottom = selRect.Top + charHeight; + selRect.Left = minimapStart + getXOffsetCol( range.start() ) * widthScale; + selRect.Right = minimapStart + getXOffsetCol( range.end() ) * widthScale; + primitives.drawRectangle( selRect ); + } + }; + String selectionString; if ( mDoc->hasSelection() && @@ -3285,16 +3365,16 @@ void UICodeEditor::drawMinimap( const Vector2f& start, } } + if ( !mHighlightWord.isEmpty() ) + drawWordRanges( mHighlightWordCache ); + if ( mMinimapConfig.syntaxHighlight ) { for ( int index = minimapStartLine; index <= endidx; index++ ) { batchSyntaxType = "normal"; batchStart = rect.Left + gutterWidth; batchWidth = 0; - if ( !mHighlightWord.empty() ) - drawWordMatch( mHighlightWord, index ); - - if ( !selectionString.empty() ) + if ( mHighlightWord.isEmpty() && !selectionString.empty() ) drawWordMatch( selectionString, index ); for ( auto* plugin : mPlugins ) @@ -3363,9 +3443,7 @@ void UICodeEditor::drawMinimap( const Vector2f& start, batchStart = rect.Left + gutterWidth; batchWidth = 0; - if ( !mHighlightWord.empty() ) - drawWordMatch( mHighlightWord, index ); - if ( !selectionString.empty() ) + if ( mHighlightWord.isEmpty() && !selectionString.empty() ) drawWordMatch( selectionString, index ); const String& text( mDoc->line( index ).getText() ); diff --git a/src/eepp/ui/uiscenenode.cpp b/src/eepp/ui/uiscenenode.cpp index 2d073493d..f105dc68d 100644 --- a/src/eepp/ui/uiscenenode.cpp +++ b/src/eepp/ui/uiscenenode.cpp @@ -402,6 +402,18 @@ void UISceneNode::reloadStyle( bool disableAnimations, bool forceReApplyProperti } } +bool UISceneNode::hasThreadPool() const { + return mThreadPool != nullptr; +} + +std::shared_ptr UISceneNode::getThreadPool() { + return mThreadPool; +} + +void UISceneNode::setThreadPool( const std::shared_ptr& threadPool ) { + mThreadPool = threadPool; +} + UIWidget* UISceneNode::loadLayoutFromFile( const std::string& layoutPath, Node* parent, const Uint32& marker ) { if ( FileSystem::fileExists( layoutPath ) ) { diff --git a/src/tools/ecode/docsearchcontroller.cpp b/src/tools/ecode/docsearchcontroller.cpp index 1eabb19d5..7b4442ada 100644 --- a/src/tools/ecode/docsearchcontroller.cpp +++ b/src/tools/ecode/docsearchcontroller.cpp @@ -80,7 +80,7 @@ void DocSearchController::initSearchBar( mFindInput->addEventListener( Event::OnTextChanged, [&]( const Event* ) { if ( mSearchState.editor && mEditorSplitter->editorExists( mSearchState.editor ) ) { mSearchState.text = mFindInput->getText(); - mSearchState.editor->setHighlightWord( mSearchState.text ); + mSearchState.editor->setHighlightWord( mSearchState.toTextSearchParams() ); if ( !mSearchState.text.empty() ) { mSearchState.editor->getDocument().setSelection( { 0, 0 } ); if ( !findNextText( mSearchState ) ) { @@ -108,7 +108,7 @@ void DocSearchController::initSearchBar( mEditorSplitter->getCurWidget()->setFocus(); if ( mSearchState.editor ) { if ( mEditorSplitter->editorExists( mSearchState.editor ) ) { - mSearchState.editor->setHighlightWord( "" ); + mSearchState.editor->setHighlightWord( { "" } ); mSearchState.editor->setHighlightTextRange( TextRange() ); } } @@ -187,7 +187,7 @@ void DocSearchController::showFindView() { } mSearchState.text = mFindInput->getText(); editor->setHighlightTextRange( mSearchState.range ); - editor->setHighlightWord( mSearchState.text ); + editor->setHighlightWord( mSearchState.toTextSearchParams() ); editor->getDocument().setActiveClient( editor ); } @@ -350,8 +350,8 @@ void DocSearchController::hideSearchBar() { void DocSearchController::onCodeEditorFocusChange( UICodeEditor* editor ) { if ( mSearchState.editor && mSearchState.editor != editor ) { - String word = mSearchState.editor->getHighlightWord(); - mSearchState.editor->setHighlightWord( "" ); + auto word = mSearchState.editor->getHighlightWord(); + mSearchState.editor->setHighlightWord( { "" } ); mSearchState.editor->setHighlightTextRange( TextRange() ); mSearchState.text = ""; mSearchState.range = TextRange(); diff --git a/src/tools/ecode/docsearchcontroller.hpp b/src/tools/ecode/docsearchcontroller.hpp index 1b97e8b4c..bca610104 100644 --- a/src/tools/ecode/docsearchcontroller.hpp +++ b/src/tools/ecode/docsearchcontroller.hpp @@ -19,6 +19,10 @@ struct SearchState { range = TextRange(); text = ""; } + + TextSearchParams toTextSearchParams() { + return { text, range, caseSensitive, wholeWord, escapeSequences, type }; + } }; class App; diff --git a/src/tools/ecode/ecode.cpp b/src/tools/ecode/ecode.cpp index 8b7d3e0b4..26cf751e3 100644 --- a/src/tools/ecode/ecode.cpp +++ b/src/tools/ecode/ecode.cpp @@ -1832,24 +1832,22 @@ void App::loadFileFromPath( mImageLayout->setEnabled( true )->setVisible( true ); loaderView->setVisible( true ); #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) - mThreadPool->run( - [&, imageView, loaderView, path]() { + mThreadPool->run( [&, imageView, loaderView, path]() { #endif - Texture* image = TextureFactory::instance()->getTexture( - TextureFactory::instance()->loadFromFile( path ) ); - if ( mImageLayout->isVisible() ) { - imageView->runOnMainThread( [imageView, loaderView, image]() { - imageView->setDrawable( image, true ); - loaderView->setVisible( false ); - } ); - } else { - TextureFactory::instance()->remove( image ); - imageView->setDrawable( nullptr ); + Texture* image = TextureFactory::instance()->getTexture( + TextureFactory::instance()->loadFromFile( path ) ); + if ( mImageLayout->isVisible() ) { + imageView->runOnMainThread( [imageView, loaderView, image]() { + imageView->setDrawable( image, true ); loaderView->setVisible( false ); - } + } ); + } else { + TextureFactory::instance()->remove( image ); + imageView->setDrawable( nullptr ); + loaderView->setVisible( false ); + } #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) - }, - []() {} ); + } ); #endif } } else { @@ -2841,6 +2839,7 @@ void App::init( const LogLevel& logLevel, std::string file, const Float& pidelDe eemax( mWindow->getScale(), mConfig.windowState.pixelDensity ) ); mUISceneNode = UISceneNode::New(); + mUISceneNode->setThreadPool( mThreadPool ); mUIColorScheme = mConfig.ui.colorScheme; if ( !colorScheme.empty() ) { mUIColorScheme = diff --git a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp index bf60d74d3..86dc016b6 100644 --- a/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp +++ b/src/tools/ecode/plugins/autocomplete/autocompleteplugin.cpp @@ -142,12 +142,10 @@ void AutoCompletePlugin::onRegister( UICodeEditor* editor ) { std::string oldLang = event->getOldLang(); std::string newLang = event->getNewLang(); #if AUTO_COMPLETE_THREADED - mPool->run( - [&, oldLang, newLang] { - updateLangCache( oldLang ); - updateLangCache( newLang ); - }, - [] {} ); + mPool->run( [&, oldLang, newLang] { + updateLangCache( oldLang ); + updateLangCache( newLang ); + } ); #else updateLangCache( oldLang ); updateLangCache( newLang ); @@ -589,7 +587,7 @@ void AutoCompletePlugin::update( UICodeEditor* ) { continue; } #if AUTO_COMPLETE_THREADED - mPool->run( [&, doc] { updateDocCache( doc ); }, [] {} ); + mPool->run( [&, doc] { updateDocCache( doc ); } ); #else updateDocCache( doc ); #endif @@ -980,8 +978,7 @@ void AutoCompletePlugin::updateSuggestions( const std::string& symbol, UICodeEdi { #if AUTO_COMPLETE_THREADED mPool->run( - [this, symbol, symbols, editor] { runUpdateSuggestions( symbol, symbols, editor ); }, - [] {} ); + [this, symbol, symbols, editor] { runUpdateSuggestions( symbol, symbols, editor ); } ); #else runUpdateSuggestions( symbol, symbols, editor ); #endif diff --git a/src/tools/ecode/plugins/formatter/formatterplugin.cpp b/src/tools/ecode/plugins/formatter/formatterplugin.cpp index 5eecb3f1a..641348bad 100644 --- a/src/tools/ecode/plugins/formatter/formatterplugin.cpp +++ b/src/tools/ecode/plugins/formatter/formatterplugin.cpp @@ -37,7 +37,7 @@ FormatterPlugin::FormatterPlugin( PluginManager* pluginManager, bool sync ) : load( pluginManager ); } else { #if FORMATTER_THREADED - mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} ); + mPool->run( [&, pluginManager] { load( pluginManager ); } ); #else load( pluginManager ); #endif diff --git a/src/tools/ecode/plugins/linter/linterplugin.cpp b/src/tools/ecode/plugins/linter/linterplugin.cpp index cc21572f1..fc42a7f7e 100644 --- a/src/tools/ecode/plugins/linter/linterplugin.cpp +++ b/src/tools/ecode/plugins/linter/linterplugin.cpp @@ -36,7 +36,7 @@ LinterPlugin::LinterPlugin( PluginManager* pluginManager, bool sync ) : load( pluginManager ); } else { #if LINTER_THREADED - mPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} ); + mPool->run( [&, pluginManager] { load( pluginManager ); } ); #else load( pluginManager ); #endif @@ -440,7 +440,7 @@ void LinterPlugin::update( UICodeEditor* editor ) { if ( it != mDirtyDoc.end() && it->second->getElapsedTime() >= mDelayTime ) { mDirtyDoc.erase( doc.get() ); #if LINTER_THREADED - mPool->run( [&, doc] { lintDoc( doc ); }, [] {} ); + mPool->run( [&, doc] { lintDoc( doc ); } ); #else lintDoc( doc ); #endif diff --git a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp index bacdf3b4a..548005605 100644 --- a/src/tools/ecode/plugins/lsp/lspclientplugin.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientplugin.cpp @@ -121,7 +121,7 @@ LSPClientPlugin::LSPClientPlugin( PluginManager* pluginManager, bool sync ) : if ( sync ) { load( pluginManager ); } else { - mThreadPool->run( [&, pluginManager] { load( pluginManager ); }, [] {} ); + mThreadPool->run( [&, pluginManager] { load( pluginManager ); } ); } } @@ -174,7 +174,7 @@ static LSPURIAndServer getServerURIFromTextDocumentURI( LSPClientServerManager& return { uri, manager.getOneLSPClientServer( uri ) }; } -static void sanitizeCommand( std::string cmd ) { +static void sanitizeCommand( std::string& cmd ) { String::replaceAll( cmd, "$NPROC", String::toString( Sys::getCPUCount() ) ); } diff --git a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp index 1563e06ce..2534611c0 100644 --- a/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp +++ b/src/tools/ecode/plugins/lsp/lspclientservermanager.cpp @@ -187,7 +187,7 @@ void LSPClientServerManager::applyWorkspaceEdit( } void LSPClientServerManager::run( const std::shared_ptr& doc ) { - mThreadPool->run( [&, doc]() { tryRunServer( doc ); }, []() {} ); + mThreadPool->run( [&, doc]() { tryRunServer( doc ); } ); } size_t LSPClientServerManager::clientCount() const { diff --git a/src/tools/ecode/projectdirectorytree.cpp b/src/tools/ecode/projectdirectorytree.cpp index aa396d73d..0bf87e8d9 100644 --- a/src/tools/ecode/projectdirectorytree.cpp +++ b/src/tools/ecode/projectdirectorytree.cpp @@ -86,7 +86,7 @@ void ProjectDirectoryTree::scan( const ProjectDirectoryTree::ScanCompleteEvent& #endif #if EE_PLATFORM != EE_PLATFORM_EMSCRIPTEN || defined( __EMSCRIPTEN_PTHREADS__ ) }, - [scanComplete, this] { + [scanComplete, this] ( const auto& ) { if ( scanComplete ) scanComplete( *this ); } ); @@ -155,12 +155,12 @@ std::shared_ptr ProjectDirectoryTree::matchTree( const std::strin void ProjectDirectoryTree::asyncFuzzyMatchTree( const std::string& match, const size_t& max, ProjectDirectoryTree::MatchResultCb res ) const { - mPool->run( [&, match, max, res]() { res( fuzzyMatchTree( match, max ) ); }, []() {} ); + mPool->run( [&, match, max, res]() { res( fuzzyMatchTree( match, max ) ); } ); } void ProjectDirectoryTree::asyncMatchTree( const std::string& match, const size_t& max, ProjectDirectoryTree::MatchResultCb res ) const { - mPool->run( [&, match, max, res]() { res( matchTree( match, max ) ); }, []() {} ); + mPool->run( [&, match, max, res]() { res( matchTree( match, max ) ); } ); } std::shared_ptr diff --git a/src/tools/ecode/projectsearch.cpp b/src/tools/ecode/projectsearch.cpp index a3518967d..b60cf2ea9 100644 --- a/src/tools/ecode/projectsearch.cpp +++ b/src/tools/ecode/projectsearch.cpp @@ -169,7 +169,7 @@ void ProjectSearch::find( const std::vector files, std::string stri findData->res.push_back( { file, fileRes } ); } }, - [result, findData] { + [result, findData]( const auto& ) { int count; { Lock l( findData->countMutex );