From b4e3c05c87bf5c6e7abfe76b3a2fb2910c88eca9 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Wed, 6 Jul 2022 14:28:14 -0700 Subject: [PATCH] [Playlist Loader] Load files in the background Load new playlist entries in the background, asynchronously. Signed-off-by: Christopher Snowhill --- Application/AppController.m | 27 ++++++++++----- FileTree/FileTreeViewController.m | 6 ++-- Playlist/PlaylistController.h | 6 +++- Playlist/PlaylistController.m | 49 +++++++++++++++++++++++---- Playlist/PlaylistLoader.h | 2 ++ Playlist/PlaylistLoader.m | 8 +++++ Playlist/PlaylistView.m | 10 +++--- Spotlight/SpotlightWindowController.m | 7 ++-- 8 files changed, 91 insertions(+), 24 deletions(-) diff --git a/Application/AppController.m b/Application/AppController.m index d35dc37d5..d09326854 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -98,8 +98,10 @@ static AppController *kAppController = nil; [p beginSheetModalForWindow:mainWindow completionHandler:^(NSInteger result) { if(result == NSModalResponseOK) { - [self->playlistLoader willInsertURLs:[p URLs] origin:URLOriginExternal]; - [self->playlistLoader didInsertURLs:[self->playlistLoader addURLs:[p URLs] sort:YES] origin:URLOriginExternal]; + NSDictionary *loadEntryData = @{@"entries": [p URLs], + @"sort": @(YES), + @"origin": @(URLOriginExternal)}; + [self->playlistController performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntryData]; } else { [p close]; } @@ -136,8 +138,10 @@ static AppController *kAppController = nil; - (void)openURLPanelDidEnd:(OpenURLPanel *)panel returnCode:(int)returnCode contextInfo:(void *)contextInfo { if(returnCode == NSModalResponseOK) { - [playlistLoader willInsertURLs:@[[panel url]] origin:URLOriginExternal]; - [playlistLoader didInsertURLs:[playlistLoader addURLs:@[[panel url]] sort:NO] origin:URLOriginExternal]; + NSDictionary *loadEntriesData = @{ @"entries": @[[panel url]], + @"sort": @(NO), + @"origin": @(URLOriginExternal) }; + [playlistController performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntriesData]; } } @@ -479,8 +483,10 @@ static AppController *kAppController = nil; - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { NSArray *urls = @[[NSURL fileURLWithPath:filename]]; - [playlistLoader willInsertURLs:urls origin:URLOriginExternal]; - [playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:NO] origin:URLOriginExternal]; + NSDictionary *loadEntriesData = @{ @"entries": urls, + @"sort": @(NO), + @"origin": @(URLOriginInternal) }; + [playlistController performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntriesData]; return YES; } @@ -491,8 +497,13 @@ static AppController *kAppController = nil; for(NSString *filename in filenames) { [urls addObject:[NSURL fileURLWithPath:filename]]; } - [playlistLoader willInsertURLs:urls origin:URLOriginExternal]; - [playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:YES] origin:URLOriginExternal]; + + NSDictionary *loadEntriesData = @{ @"entries": urls, + @"sort": @(YES), + @"origin": @(URLOriginInternal) }; + + [playlistController performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntriesData]; + [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; } diff --git a/FileTree/FileTreeViewController.m b/FileTree/FileTreeViewController.m index cd582c2b7..3f8e3c62e 100644 --- a/FileTree/FileTreeViewController.m +++ b/FileTree/FileTreeViewController.m @@ -26,8 +26,10 @@ } - (void)doAddToPlaylist:(NSArray *)urls origin:(URLOrigin)origin { - [playlistLoader willInsertURLs:urls origin:origin]; - [playlistLoader didInsertURLs:[playlistLoader addURLs:urls sort:YES] origin:origin]; + NSDictionary *loadEntryData = @{ @"entries": urls, + @"sort": @(YES), + @"origin": @(origin) }; + [playlistLoader performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntryData]; } - (void)clear:(id)sender { diff --git a/Playlist/PlaylistController.h b/Playlist/PlaylistController.h index 068bc4b42..331d6914d 100644 --- a/Playlist/PlaylistController.h +++ b/Playlist/PlaylistController.h @@ -126,6 +126,10 @@ typedef NS_ENUM(NSInteger, URLOrigin) { - (void)willInsertURLs:(NSArray *_Nullable)urls origin:(URLOrigin)origin; - (void)didInsertURLs:(NSArray *_Nullable)urls origin:(URLOrigin)origin; +// Asynchronous event handler +- (void)addURLsInBackground:(NSDictionary *_Nonnull)input; +- (void)insertURLsInBackground:(NSDictionary *_Nonnull)input; + // queue methods - (IBAction)toggleQueued:(id _Nullable)sender; - (IBAction)emptyQueueList:(id _Nullable)sender; @@ -154,7 +158,7 @@ typedef NS_ENUM(NSInteger, URLOrigin) { - (void)insertObjectsUnsynced:(NSArray *_Nullable)objects atArrangedObjectIndexes:(NSIndexSet *_Nullable)indexes; -- (void)tableView:(NSTableView *)view didClickRow:(NSInteger)clickedRow column:(NSInteger)clickedColumn atPoint:(NSPoint)cellPoint; +- (void)tableView:(NSTableView *_Nonnull)view didClickRow:(NSInteger)clickedRow column:(NSInteger)clickedColumn atPoint:(NSPoint)cellPoint; - (BOOL)pathSuggesterEmpty; diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index 332fd4ba3..d986eb9ea 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -770,17 +770,17 @@ static void *playlistControllerContext = &playlistControllerContext; } if([acceptedURLs count]) { - [self willInsertURLs:acceptedURLs origin:URLOriginInternal]; - if(![[self content] count]) { row = 0; } - NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:row sort:YES]; - [self didInsertURLs:entries origin:URLOriginInternal]; - } + NSDictionary *loadEntriesData = @{ @"entries": acceptedURLs, + @"index": @(row), + @"sort": @(YES), + @"origin": @(URLOriginInternal) }; - if([self shuffle] != ShuffleOff) [self resetShuffleList]; + [self performSelectorInBackground:@selector(insertURLsInBackground:) withObject:loadEntriesData]; + } return YES; } @@ -1720,6 +1720,43 @@ static void *playlistControllerContext = &playlistControllerContext; return YES; } +// Asynchronous event inlets: +- (void)addURLsInBackground:(NSDictionary *)input { + NSUInteger row = [[self content] count]; + + NSMutableDictionary *_input = [input mutableCopy]; + [_input setObject:@(row) forKey:@"index"]; + + [self insertURLsInBackground:_input]; +} + +static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_block_t block) { + if(dispatch_queue_get_label(queue) == dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)) { + block(); + } else { + dispatch_sync(queue, block); + } +} + +- (void)insertURLsInBackground:(NSDictionary *)input { + NSArray *entries = [input objectForKey:@"entries"]; + NSUInteger row = [[input objectForKey:@"index"] integerValue]; + BOOL sort = [[input objectForKey:@"sort"] boolValue]; + URLOrigin origin = (URLOrigin)[[input objectForKey:@"origin"] integerValue]; + + dispatch_sync_reentrant(dispatch_get_main_queue(), ^{ + [self willInsertURLs:entries origin:origin]; + }); + NSArray *urlsAccepted = [playlistLoader insertURLs:entries atIndex:row sort:sort]; + dispatch_sync_reentrant(dispatch_get_main_queue(), ^{ + [self didInsertURLs:urlsAccepted origin:origin]; + }); + + dispatch_sync_reentrant(dispatch_get_main_queue(), ^{ + if([self shuffle] != ShuffleOff) [self resetShuffleList]; + }); +} + // Event inlets: - (void)willInsertURLs:(NSArray *)urls origin:(URLOrigin)origin { if(![urls count]) return; diff --git a/Playlist/PlaylistLoader.h b/Playlist/PlaylistLoader.h index 88f6ebbb0..8b59e8b29 100644 --- a/Playlist/PlaylistLoader.h +++ b/Playlist/PlaylistLoader.h @@ -70,5 +70,7 @@ typedef enum { // Events (passed to playlist controler): - (void)willInsertURLs:(NSArray *)urls origin:(URLOrigin)origin; - (void)didInsertURLs:(NSArray *)entries origin:(URLOrigin)origin; +- (void)addURLsInBackground:(NSDictionary *)input; +- (void)insertURLsInBackground:(NSDictionary *)input; @end diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index 4b34ce5eb..677fe35ce 100644 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -994,4 +994,12 @@ NSURL *_Nullable urlForPath(NSString *_Nullable path); [playlistController didInsertURLs:urls origin:origin]; } +- (void)addURLsInBackground:(NSDictionary *)input { + [playlistController addURLsInBackground:input]; +} + +- (void)insertURLsInBackground:(NSDictionary *)input { + [playlistController insertURLsInBackground:input]; +} + @end diff --git a/Playlist/PlaylistView.m b/Playlist/PlaylistView.m index e964a49be..fe6379d5f 100644 --- a/Playlist/PlaylistView.m +++ b/Playlist/PlaylistView.m @@ -358,12 +358,12 @@ if([acceptedURLs count]) { NSUInteger row = [[playlistController content] count]; - [playlistController willInsertURLs:acceptedURLs origin:URLOriginInternal]; + NSDictionary *loadEntriesData = @{ @"entries": acceptedURLs, + @"index": @(row), + @"sort": @(NO), + @"origin": @(URLOriginInternal) }; - NSArray *entries = [playlistLoader insertURLs:acceptedURLs atIndex:(int)row sort:NO]; - [playlistLoader didInsertURLs:entries origin:URLOriginInternal]; - - if([playlistController shuffle] != ShuffleOff) [playlistController resetShuffleList]; + [playlistController performSelectorInBackground:@selector(insertURLsInBackground:) withObject:loadEntriesData]; } } diff --git a/Spotlight/SpotlightWindowController.m b/Spotlight/SpotlightWindowController.m index c717c550f..e8d683f39 100644 --- a/Spotlight/SpotlightWindowController.m +++ b/Spotlight/SpotlightWindowController.m @@ -244,8 +244,11 @@ static NSPredicate *musicOnlyPredicate = nil; if([tracks count] == 0) tracks = playlistController.arrangedObjects; - [playlistLoader willInsertURLs:[tracks valueForKey:@"url"] origin:URLOriginExternal]; - [playlistLoader didInsertURLs:[playlistLoader addURLs:[tracks valueForKey:@"url"] sort:NO] origin:URLOriginExternal]; + NSDictionary *loadEntryData = @{ @"entries": [tracks valueForKey:@"url"], + @"sort": @(NO), + @"origin": @(URLOriginExternal) }; + + [playlistLoader performSelectorInBackground:@selector(addURLsInBackground:) withObject:loadEntryData]; [self.query enableUpdates]; }