mirror of
https://github.com/SpartanJ/eepp.git
synced 2026-10-03 03:31:04 +03:00
Fix FileSystemModel crash on stale filesystem-model indexes
- dispatch filesystem events on the main thread in FileSystemListener, preserving model, tree, document, and callback ordering - add address + generation node identity to close the allocator-reuse hole - return null/empty results for stale indexes instead of root data - assert the main-thread contract and token-guard queued listener actions - add attached-view and stale-selection crash regression tests Fixes crash reported in discussion SpartanJ/ecode#952
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
#include <eepp/core/containers.hpp>
|
||||
#include <eepp/system/fileinfo.hpp>
|
||||
#include <eepp/system/threadpool.hpp>
|
||||
#include <eepp/system/translator.hpp>
|
||||
@@ -82,7 +83,7 @@ class EE_API FileSystemModel : public Model {
|
||||
Node( const std::string& rootPath, FileSystemModel& model,
|
||||
const std::shared_ptr<ThreadPool>& threadPool = {} );
|
||||
|
||||
Node( FileInfo&& info, Node* parent );
|
||||
Node( FileInfo&& info, Node* parent, const FileSystemModel& model );
|
||||
|
||||
const std::string& getName() const { return mName; }
|
||||
|
||||
@@ -137,6 +138,8 @@ class EE_API FileSystemModel : public Model {
|
||||
String mDisplayName;
|
||||
std::string mMimeType;
|
||||
Node* mParent{ nullptr };
|
||||
const FileSystemModel* mModel{ nullptr };
|
||||
Uint64 mId{ 0 };
|
||||
FileInfo mInfo;
|
||||
std::vector<Node*> mChildren;
|
||||
bool mHasTraversed{ false };
|
||||
@@ -181,6 +184,14 @@ class EE_API FileSystemModel : public Model {
|
||||
void update();
|
||||
|
||||
const Node& node( const ModelIndex& index ) const;
|
||||
|
||||
/**
|
||||
* @brief Returns the node for a valid index, or nullptr for a stale index
|
||||
* (node deleted by a background refresh). An invalid index resolves to the
|
||||
* root.
|
||||
*/
|
||||
const Node* nodePtr( const ModelIndex& index ) const;
|
||||
|
||||
virtual size_t treeColumn() const { return Column::Name; }
|
||||
virtual size_t rowCount( const ModelIndex& = ModelIndex() ) const;
|
||||
virtual size_t columnCount( const ModelIndex& = ModelIndex() ) const;
|
||||
@@ -203,8 +214,18 @@ class EE_API FileSystemModel : public Model {
|
||||
|
||||
void setPreviouslySelectedIndex( const ModelIndex& previouslySelectedIndex );
|
||||
|
||||
/**
|
||||
* @brief Processes a filesystem event (add/delete/move/modified).
|
||||
*
|
||||
* Must be called from the main thread when views are attached: the method
|
||||
* mutates view selections and metadata. ecode's FileSystemListener
|
||||
* dispatches watcher events to the main thread before calling this; direct
|
||||
* callers are responsible for the same requirement.
|
||||
*/
|
||||
bool handleFileEvent( const FileEvent& event );
|
||||
|
||||
virtual bool isValid( const ModelIndex& index ) const override;
|
||||
|
||||
virtual bool classModelRoleEnabled() { return true; }
|
||||
|
||||
~FileSystemModel();
|
||||
@@ -222,7 +243,12 @@ class EE_API FileSystemModel : public Model {
|
||||
|
||||
ModelIndex mPreviouslySelectedIndex{};
|
||||
|
||||
Node& nodeRef( const ModelIndex& index ) const;
|
||||
Node* nodeRef( const ModelIndex& index ) const;
|
||||
|
||||
bool isNodeAlive( const Node* node, Uint64 id ) const;
|
||||
|
||||
mutable UnorderedSet<const Node*> mAliveNodes;
|
||||
mutable Uint64 mNextNodeId{ 1 };
|
||||
|
||||
FileSystemModel( const std::string& rootPath, const Mode& mode,
|
||||
const DisplayConfig& displayConfig, Translator* translator,
|
||||
|
||||
@@ -100,7 +100,7 @@ class EE_API Model {
|
||||
|
||||
virtual bool isEditable( const ModelIndex& ) const { return false; }
|
||||
|
||||
bool isValid( const ModelIndex& index ) const {
|
||||
virtual bool isValid( const ModelIndex& index ) const {
|
||||
auto parentIndex = this->parentIndex( index );
|
||||
return index.row() >= 0 && index.row() < (Int64)rowCount( parentIndex ) &&
|
||||
index.column() >= 0 && index.column() < (Int64)columnCount( parentIndex );
|
||||
|
||||
Reference in New Issue
Block a user