Do not have FSEventsManager load directory contents

Originally we had FSEventsManager handle directory loading because it worked as a cache, but it’s better to move this to the client, as not all clients need the directory content, additionally it simplifies the cache invalidation (reload) and also moves the hardcoded list of URL keys to preload into the client, which should know which keys are desired.
This commit is contained in:
Allan Odgaard
2018-10-28 22:36:22 +07:00
parent f5e543dc77
commit 9f6d9d043e
3 changed files with 26 additions and 25 deletions

View File

@@ -1,7 +1,7 @@
@interface FSEventsManager : NSObject
+ (instancetype)sharedInstance;
- (id)addObserverToDirectoryAtURL:(NSURL*)url usingBlock:(void(^)(NSArray<NSURL*>*))handler;
- (id)addObserverToDirectoryAtURL:(NSURL*)url usingBlock:(void(^)())handler;
- (void)removeObserver:(id)someObserver;
- (void)reloadDirectoryAtURL:(NSURL*)url;

View File

@@ -3,21 +3,19 @@
@class FSEventsDirectory;
@interface FSEventsClient : NSObject
@property (nonatomic, readonly) void(^handler)(NSArray<NSURL*>*);
@property (nonatomic, readonly) void(^handler)();
@property (nonatomic) FSEventsDirectory* directory;
- (instancetype)initWithBlock:(void(^)(NSArray<NSURL*>*))handler;
- (instancetype)initWithBlock:(void(^)())handler;
- (void)removeFromDirectory;
@end
@interface FSEventsDirectory : NSObject
@property (nonatomic, readonly) NSURL* URL;
@property (nonatomic, readonly) NSMutableArray<FSEventsClient*>* clients;
@property (nonatomic, readonly) id scmObserver;
@property (nonatomic) NSArray<NSURL*>* urls;
- (instancetype)initWithURL:(NSURL*)url;
- (void)addClient:(FSEventsClient*)observer;
- (void)removeClient:(FSEventsClient*)observer;
- (void)reloadDirectoryAndNotify;
- (void)notifyObservers;
@end
// ============================
@@ -100,17 +98,17 @@ namespace
- (void)reloadDirectoryAtURL:(NSURL*)url
{
[[_directories objectForKey:url] reloadDirectoryAndNotify];
[[_directories objectForKey:url] notifyObservers];
}
- (void)resetObservers
{
_fsEvents.reset(new fs_events_t(_directories.keyEnumerator.allObjects, ^(NSURL* url){
[[_directories objectForKey:url] reloadDirectoryAndNotify];
[[_directories objectForKey:url] notifyObservers];
}));
}
- (id)addObserverToDirectoryAtURL:(NSURL*)url usingBlock:(void(^)(NSArray<NSURL*>*))handler
- (id)addObserverToDirectoryAtURL:(NSURL*)url usingBlock:(void(^)())handler
{
FSEventsDirectory* directory = [_directories objectForKey:url];
if(!directory)
@@ -148,26 +146,16 @@ namespace
return self;
}
- (void)reloadDirectoryAndNotify
- (void)notifyObservers
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray<NSURL*>* urls = [NSFileManager.defaultManager contentsOfDirectoryAtURL:_URL includingPropertiesForKeys:@[ NSURLIsDirectoryKey, NSURLIsPackageKey, NSURLIsSymbolicLinkKey, NSURLIsHiddenKey, NSURLLocalizedNameKey, NSURLEffectiveIconKey ] options:0 error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
self.urls = urls;
for(FSEventsClient* client in _clients)
client.handler(self.urls);
});
});
for(FSEventsClient* client in _clients)
client.handler();
}
- (void)addClient:(FSEventsClient*)observer
{
observer.directory = self;
[_clients addObject:observer];
if(self.urls)
observer.handler(self.urls);
else [self reloadDirectoryAndNotify];
}
- (void)removeClient:(FSEventsClient*)observer
@@ -178,7 +166,7 @@ namespace
@end
@implementation FSEventsClient
- (instancetype)initWithBlock:(void(^)(NSArray<NSURL*>*))handler
- (instancetype)initWithBlock:(void(^)())handler
{
if(self = [super init])
_handler = handler;

View File

@@ -27,13 +27,15 @@
_scmURLs = @[ ];
__weak FileSystemObserver* weakSelf = self;
_fsEventsObserver = [FSEventsManager.sharedInstance addObserverToDirectoryAtURL:url usingBlock:^(NSArray<NSURL*>* urls){
[weakSelf updateFSEventsURLs:urls scmURLs:nil];
_fsEventsObserver = [FSEventsManager.sharedInstance addObserverToDirectoryAtURL:url usingBlock:^{
[weakSelf loadContentsOfDirectoryAtURL:url];
}];
_scmObserver = [SCMManager.sharedInstance addObserverToRepositoryAtURL:url usingBlock:^(std::map<std::string, scm::status::type> const&){
[weakSelf updateFSEventsURLs:nil scmURLs:[SCMManager.sharedInstance urlsWithStatus:scm::status::deleted inDirectoryAtURL:url]];
}];
[self loadContentsOfDirectoryAtURL:url];
}
return self;
}
@@ -44,6 +46,17 @@
[SCMManager.sharedInstance removeObserver:_scmObserver];
}
- (void)loadContentsOfDirectoryAtURL:(NSURL*)url
{
__weak FileSystemObserver* weakSelf = self;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSArray<NSURL*>* urls = [NSFileManager.defaultManager contentsOfDirectoryAtURL:url includingPropertiesForKeys:@[ NSURLIsDirectoryKey, NSURLIsPackageKey, NSURLIsSymbolicLinkKey, NSURLIsHiddenKey, NSURLLocalizedNameKey, NSURLEffectiveIconKey ] options:0 error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
[weakSelf updateFSEventsURLs:urls scmURLs:nil];
});
});
}
- (void)updateFSEventsURLs:(NSArray<NSURL*>*)fsEventsURLs scmURLs:(NSArray<NSURL*>*)scmURLs
{
_fsEventsURLs = fsEventsURLs ?: _fsEventsURLs;