Improve asynchronous filesystem event processing

- queue and batch filesystem model updates on the main thread
  - process directory-tree updates and worker-affine listeners asynchronously
  - coalesce adjacent modified events for the same path
  - preserve captured file metadata across delayed event delivery
  - add event, path, and thread-affinity filters for listener subscriptions
  - configure optimized per-plugin filesystem subscriptions
  - make listener removal wait for active callbacks safely
  - handle self-removal without deadlocking
  - support allocation-free matching of moved source paths
  - synchronize project directory-tree mutations with active searches
  - centralize diff-view button visibility around find/replace state
  - improve code editor wrap-content and scrollbar sizing
  - add queue, listener, and filesystem-model regression tests
This commit is contained in:
Martín Lucas Golini
2026-08-21 01:32:36 -03:00
parent c13710dddc
commit 864b2a9b3f
25 changed files with 860 additions and 109 deletions
+2
View File
@@ -132,6 +132,8 @@ class EE_API Event {
OnFocusWithinLoss,
OnItemsCountChange,
OnApply,
OnShowFindReplace,
OnHideFindReplace,
NoEvent = eeINDEX_NOT_FOUND
};
+11 -1
View File
@@ -224,6 +224,14 @@ class EE_API FileSystemModel : public Model {
*/
bool handleFileEvent( const FileEvent& event );
/**
* @brief Processes a filesystem event using metadata captured when the event was received.
*
* This avoids querying the filesystem from the main thread and preserves the state observed by
* an asynchronous listener even if a later event changes the path before this event is applied.
*/
bool handleFileEvent( const FileEvent& event, const FileInfo& file );
virtual bool isValid( const ModelIndex& index ) const override;
virtual bool classModelRoleEnabled() { return true; }
@@ -256,7 +264,9 @@ class EE_API FileSystemModel : public Model {
size_t getFileIndex( Node* parent, const FileInfo& file, const Node* excludedNode = nullptr );
bool handleFileEventLocked( const FileEvent& event );
bool handleFileEventLocked( const FileEvent& event, const FileInfo* preparedFile = nullptr );
bool handleFileEvent( const FileEvent& event, const FileInfo* preparedFile );
void setupColumnNames( Translator* translator );
};
+1
View File
@@ -135,6 +135,7 @@ class EE_API UIDiffView : public UIWidget, public WidgetCommandExecuter {
void computeSubLineDiff( DiffLine& oldLine, DiffLine& newLine );
void updateEditorsText();
void updateButtonsText();
void updateButtonsVisibility();
void createImageViewers();
bool loadImageDiffFromPaths( const std::string& oldFilePath, const std::string& newFilePath );
void updateImageDiffView();
+2
View File
@@ -869,6 +869,8 @@ class EE_API UICodeEditor : public UIWidget, public TextDocument::Client {
void setDynamicTheming( bool set );
const Tools::UIDocFindReplace* getFindReplace() const { return mFindReplace; }
protected:
struct LastXOffset {
TextPosition position{ 0, 0 };