diff --git a/Application/AppController.h b/Application/AppController.h index 3c0152e4a..e92e04d36 100644 --- a/Application/AppController.h +++ b/Application/AppController.h @@ -83,7 +83,4 @@ OSStatus handleHotKey(EventHandlerCallRef nextHandler,EventRef theEvent,void *us - (IBAction)decreaseFontSize:(id)sender; - (void)changeFontSize:(float)size; -// return the operation queue -- (NSOperationQueue *)sharedOperationQueue; - @end diff --git a/Application/AppController.m b/Application/AppController.m index c50926c2a..352140f14 100644 --- a/Application/AppController.m +++ b/Application/AppController.m @@ -469,8 +469,4 @@ increase/decrease as long as the user holds the left/right, plus/minus button */ } -- (NSOperationQueue *)sharedOperationQueue -{ - return queue; -} @end diff --git a/Application/PlaybackEventController.h b/Application/PlaybackEventController.h index 2d94ade4a..e39302c45 100644 --- a/Application/PlaybackEventController.h +++ b/Application/PlaybackEventController.h @@ -9,13 +9,13 @@ #import #import -@class PlaybackController; +@class PlaylistLoader; @class AudioScrobbler; @interface PlaybackEventController : NSObject { NSOperationQueue *queue; AudioScrobbler *scrobbler; - IBOutlet PlaybackController *playbackController; + IBOutlet PlaylistLoader *playlistLoader; } @end diff --git a/Application/PlaybackEventController.m b/Application/PlaybackEventController.m index 513c47a0b..5d41e564c 100644 --- a/Application/PlaybackEventController.m +++ b/Application/PlaybackEventController.m @@ -8,9 +8,10 @@ #import "PlaybackEventController.h" -#import "PlaylistEntry.h" #import "AudioScrobbler.h" #import "PlaybackController.h" +#import "PlaylistLoader.h" +#import "PlaylistEntry.h" @implementation PlaybackEventController @@ -32,6 +33,8 @@ [self initDefaults]; queue = [[NSOperationQueue alloc] init]; + [queue setMaxConcurrentOperationCount:1]; + scrobbler = [[AudioScrobbler alloc] init]; [GrowlApplicationBridge setGrowlDelegate:self]; } @@ -46,21 +49,14 @@ [super dealloc]; } -- (void)awakeFromNib +- (void)performPlaybackDidBeginActions:(PlaylistEntry *)pe { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidBegin:) name:CogPlaybackDidBeginNotficiation object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidPause:) name:CogPlaybackDidPauseNotficiation object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidResume:) name:CogPlaybackDidResumeNotficiation object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidStop:) name:CogPlaybackDidStopNotficiation object:nil]; -} - -- (void)playbackDidBegin:(NSNotification *)notification -{ - PlaylistEntry *pe = [notification object]; + [pe performSelectorOnMainThread:@selector(setValuesForKeysWithDictionary:) withObject:[playlistLoader readEntryInfo:pe] waitUntilDone:YES]; + if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { [scrobbler start:pe]; } - + // Note: We don't want to send a growl notification on resume. [GrowlApplicationBridge notifyWithTitle:[pe title] description:[pe artist] @@ -71,27 +67,64 @@ clickContext:nil]; } -- (void)playbackDidPause:(NSNotification *)notification +- (void)performPlaybackDidPauseActions { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { [scrobbler pause]; } } -- (void)playbackDidResume:(NSNotification *)notification +- (void)performPlaybackDidResumeActions { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { [scrobbler resume]; } } -- (void)playbackDidStop:(NSNotification *)notification +- (void)performPlaybackDidStopActions { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { [scrobbler stop]; } } + +- (void)awakeFromNib +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidBegin:) name:CogPlaybackDidBeginNotficiation object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidPause:) name:CogPlaybackDidPauseNotficiation object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidResume:) name:CogPlaybackDidResumeNotficiation object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidStop:) name:CogPlaybackDidStopNotficiation object:nil]; +} + +- (void)playbackDidBegin:(NSNotification *)notification +{ + NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(performPlaybackDidBeginActions:) object:[notification object]]; + [queue addOperation:op]; + [op release]; +} + +- (void)playbackDidPause:(NSNotification *)notification +{ + NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(performPlaybackDidPauseActions) object:nil]; + [queue addOperation:op]; + [op release]; +} + +- (void)playbackDidResume:(NSNotification *)notification +{ + NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(performPlaybackDidResumeActions) object:nil]; + [queue addOperation:op]; + [op release]; +} + +- (void)playbackDidStop:(NSNotification *)notification +{ + NSOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(performPlaybackDidStopActions) object:nil]; + [queue addOperation:op]; + [op release]; +} + - (NSDictionary *) registrationDictionaryForGrowl { NSArray *notifications = [NSArray arrayWithObjects:@"Stream Changed", nil]; diff --git a/English.lproj/MainMenu.xib b/English.lproj/MainMenu.xib index fcda5036e..b616ea4c6 100644 --- a/English.lproj/MainMenu.xib +++ b/English.lproj/MainMenu.xib @@ -9,8 +9,8 @@ YES - + YES @@ -6882,6 +6882,14 @@ OQA 2406 + + + playlistLoader + + + + 2407 + @@ -10475,7 +10483,7 @@ OQA - 2406 + 2407 @@ -10890,8 +10898,8 @@ OQA PlaybackEventController NSObject - playbackController - PlaybackController + playlistLoader + PlaylistLoader IBProjectSource diff --git a/Playlist/PlaylistController.m b/Playlist/PlaylistController.m index 2a272f546..7fc9f3162 100644 --- a/Playlist/PlaylistController.m +++ b/Playlist/PlaylistController.m @@ -843,10 +843,6 @@ //Auto start playback if (shouldPlay && [[entriesController entries] count] > 0) { - // HACK ALERT! - [[urls objectAtIndex:0] setValuesForKeysWithDictionary:[playlistLoader readEntryInfo:[urls objectAtIndex:0]]]; - // END HACK - [playbackController playEntry: [urls objectAtIndex:0]]; } } diff --git a/Playlist/PlaylistLoader.h b/Playlist/PlaylistLoader.h index 2dd1fd67d..67c15d277 100755 --- a/Playlist/PlaylistLoader.h +++ b/Playlist/PlaylistLoader.h @@ -20,22 +20,22 @@ typedef enum { @interface PlaylistLoader : NSObject { IBOutlet PlaylistController *playlistController; + + NSOperationQueue *queue; } -- (void)initDefaults; - -//load arrays of urls... +// Load arrays of urls... - (NSArray*)addURLs:(NSArray *)urls sort:(BOOL)sort; - (NSArray*)addURL:(NSURL *)url; - (NSArray*)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort; -//save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined. +// Save playlist, auto-determines type based on extension. Uses m3u if it cannot be determined. - (BOOL)save:(NSString *)filename; - (BOOL)save:(NSString *)filename asType:(PlaylistType)type; - (BOOL)saveM3u:(NSString *)filename; - (BOOL)savePls:(NSString *)filename; -//read info for a playlist entry +// Read info for a playlist entry - (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe; - (void)loadInfoForEntries:(NSArray *)entries; @@ -44,7 +44,7 @@ typedef enum { - (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving - (NSArray *)acceptableContainerTypes; -// Event inlets (passed to playlist controler): +// Events (passed to playlist controler): - (void)willInsertURLs:(NSArray*)urls origin:(URLOrigin)origin; - (void)didInsertURLs:(NSArray*)entries origin:(URLOrigin)origin; diff --git a/Playlist/PlaylistLoader.m b/Playlist/PlaylistLoader.m index 2e697392a..cdce75a9c 100755 --- a/Playlist/PlaylistLoader.m +++ b/Playlist/PlaylistLoader.m @@ -26,18 +26,20 @@ self = [super init]; if (self) { - [self initDefaults]; + queue = [[NSOperationQueue alloc] init]; + [queue setMaxConcurrentOperationCount:1]; } return self; } -- (void)initDefaults +- (void)dealloc { - + [queue release]; + + [super dealloc]; } - - (BOOL)save:(NSString *)filename { NSString *ext = [filename pathExtension]; @@ -292,10 +294,6 @@ - (void)loadInfoForEntries:(NSArray *)entries { - NSOperationQueue *queue; - queue = [[[NSApplication sharedApplication] delegate] sharedOperationQueue]; - - NSInvocationOperation *oldReadEntryInfoOperation = nil; for (PlaylistEntry *pe in entries) { NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init]; @@ -305,22 +303,17 @@ initWithTarget:self selector:@selector(readEntryInfo:) object:pe]; - if (oldReadEntryInfoOperation) - { - [readEntryInfoOperation addDependency:oldReadEntryInfoOperation]; - [oldReadEntryInfoOperation release]; - } + [readEntryInfoOperation addObserver:self forKeyPath:@"isFinished" options:NSKeyValueObservingOptionNew context:NULL]; [queue addOperation:readEntryInfoOperation]; - oldReadEntryInfoOperation = [readEntryInfoOperation retain]; + [readEntryInfoOperation release]; [pool release]; } - [oldReadEntryInfoOperation release]; [queue waitUntilAllOperationsAreFinished]; @@ -346,7 +339,7 @@ NSDictionary *entryInfo = [operation result]; PlaylistEntry *pe; // get the playlist entry that the thread was inspecting - [[operation invocation]getArgument:&pe atIndex:2]; + [[operation invocation] getArgument:&pe atIndex:2]; if (entryInfo == nil) { pe.error = YES;