[Playlist Loader] Load files in the background

Load new playlist entries in the background, asynchronously.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
main
Christopher Snowhill 2022-07-06 14:28:14 -07:00
parent c54062f4bf
commit b4e3c05c87
8 changed files with 91 additions and 24 deletions

View File

@ -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];
}

View File

@ -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 {

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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];
}
}

View File

@ -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];
}