Playback events for last.fm and growl are now done in the background via an operation queue. Removed hack to load metadata for autoplay. Now metadata is reloaded for each file you play.

CQTexperiment
vspader 2009-03-05 20:37:44 -08:00
parent e2d590c167
commit d6a0b0670e
8 changed files with 77 additions and 54 deletions

View File

@ -83,7 +83,4 @@ OSStatus handleHotKey(EventHandlerCallRef nextHandler,EventRef theEvent,void *us
- (IBAction)decreaseFontSize:(id)sender; - (IBAction)decreaseFontSize:(id)sender;
- (void)changeFontSize:(float)size; - (void)changeFontSize:(float)size;
// return the operation queue
- (NSOperationQueue *)sharedOperationQueue;
@end @end

View File

@ -469,8 +469,4 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
} }
- (NSOperationQueue *)sharedOperationQueue
{
return queue;
}
@end @end

View File

@ -9,13 +9,13 @@
#import <Cocoa/Cocoa.h> #import <Cocoa/Cocoa.h>
#import <Growl/GrowlApplicationBridge.h> #import <Growl/GrowlApplicationBridge.h>
@class PlaybackController; @class PlaylistLoader;
@class AudioScrobbler; @class AudioScrobbler;
@interface PlaybackEventController : NSObject <GrowlApplicationBridgeDelegate> { @interface PlaybackEventController : NSObject <GrowlApplicationBridgeDelegate> {
NSOperationQueue *queue; NSOperationQueue *queue;
AudioScrobbler *scrobbler; AudioScrobbler *scrobbler;
IBOutlet PlaybackController *playbackController; IBOutlet PlaylistLoader *playlistLoader;
} }
@end @end

View File

@ -8,9 +8,10 @@
#import "PlaybackEventController.h" #import "PlaybackEventController.h"
#import "PlaylistEntry.h"
#import "AudioScrobbler.h" #import "AudioScrobbler.h"
#import "PlaybackController.h" #import "PlaybackController.h"
#import "PlaylistLoader.h"
#import "PlaylistEntry.h"
@implementation PlaybackEventController @implementation PlaybackEventController
@ -32,6 +33,8 @@
[self initDefaults]; [self initDefaults];
queue = [[NSOperationQueue alloc] init]; queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
scrobbler = [[AudioScrobbler alloc] init]; scrobbler = [[AudioScrobbler alloc] init];
[GrowlApplicationBridge setGrowlDelegate:self]; [GrowlApplicationBridge setGrowlDelegate:self];
} }
@ -46,17 +49,10 @@
[super dealloc]; [super dealloc];
} }
- (void)awakeFromNib - (void)performPlaybackDidBeginActions:(PlaylistEntry *)pe
{ {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackDidBegin:) name:CogPlaybackDidBeginNotficiation object:nil]; [pe performSelectorOnMainThread:@selector(setValuesForKeysWithDictionary:) withObject:[playlistLoader readEntryInfo:pe] waitUntilDone:YES];
[[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];
if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) {
[scrobbler start:pe]; [scrobbler start:pe];
} }
@ -71,27 +67,64 @@
clickContext:nil]; clickContext:nil];
} }
- (void)playbackDidPause:(NSNotification *)notification - (void)performPlaybackDidPauseActions
{ {
if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) {
[scrobbler pause]; [scrobbler pause];
} }
} }
- (void)playbackDidResume:(NSNotification *)notification - (void)performPlaybackDidResumeActions
{ {
if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) {
[scrobbler resume]; [scrobbler resume];
} }
} }
- (void)playbackDidStop:(NSNotification *)notification - (void)performPlaybackDidStopActions
{ {
if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) { if([[NSUserDefaults standardUserDefaults] boolForKey:@"enableAudioScrobbler"]) {
[scrobbler stop]; [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 - (NSDictionary *) registrationDictionaryForGrowl
{ {
NSArray *notifications = [NSArray arrayWithObjects:@"Stream Changed", nil]; NSArray *notifications = [NSArray arrayWithObjects:@"Stream Changed", nil];

View File

@ -9,8 +9,8 @@
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs"> <object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
<integer value="21"/> <integer value="21"/>
<integer value="2234"/>
<integer value="29"/> <integer value="29"/>
<integer value="2234"/>
</object> </object>
<object class="NSArray" key="IBDocument.PluginDependencies"> <object class="NSArray" key="IBDocument.PluginDependencies">
<bool key="EncodedWithXMLCoder">YES</bool> <bool key="EncodedWithXMLCoder">YES</bool>
@ -6882,6 +6882,14 @@ OQA</bytes>
</object> </object>
<int key="connectionID">2406</int> <int key="connectionID">2406</int>
</object> </object>
<object class="IBConnectionRecord">
<object class="IBOutletConnection" key="connection">
<string key="label">playlistLoader</string>
<reference key="source" ref="424025370"/>
<reference key="destination" ref="362908833"/>
</object>
<int key="connectionID">2407</int>
</object>
</object> </object>
<object class="IBMutableOrderedSet" key="objectRecords"> <object class="IBMutableOrderedSet" key="objectRecords">
<object class="NSArray" key="orderedObjects"> <object class="NSArray" key="orderedObjects">
@ -10475,7 +10483,7 @@ OQA</bytes>
</object> </object>
</object> </object>
<nil key="sourceID"/> <nil key="sourceID"/>
<int key="maxID">2406</int> <int key="maxID">2407</int>
</object> </object>
<object class="IBClassDescriber" key="IBDocument.Classes"> <object class="IBClassDescriber" key="IBDocument.Classes">
<object class="NSMutableArray" key="referencedPartialClassDescriptions"> <object class="NSMutableArray" key="referencedPartialClassDescriptions">
@ -10890,8 +10898,8 @@ OQA</bytes>
<string key="className">PlaybackEventController</string> <string key="className">PlaybackEventController</string>
<string key="superclassName">NSObject</string> <string key="superclassName">NSObject</string>
<object class="NSMutableDictionary" key="outlets"> <object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">playbackController</string> <string key="NS.key.0">playlistLoader</string>
<string key="NS.object.0">PlaybackController</string> <string key="NS.object.0">PlaylistLoader</string>
</object> </object>
<object class="IBClassDescriptionSource" key="sourceIdentifier"> <object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string> <string key="majorKey">IBProjectSource</string>

View File

@ -843,10 +843,6 @@
//Auto start playback //Auto start playback
if (shouldPlay && [[entriesController entries] count] > 0) { if (shouldPlay && [[entriesController entries] count] > 0) {
// HACK ALERT!
[[urls objectAtIndex:0] setValuesForKeysWithDictionary:[playlistLoader readEntryInfo:[urls objectAtIndex:0]]];
// END HACK
[playbackController playEntry: [urls objectAtIndex:0]]; [playbackController playEntry: [urls objectAtIndex:0]];
} }
} }

View File

@ -20,22 +20,22 @@ typedef enum {
@interface PlaylistLoader : NSObject { @interface PlaylistLoader : NSObject {
IBOutlet PlaylistController *playlistController; IBOutlet PlaylistController *playlistController;
NSOperationQueue *queue;
} }
- (void)initDefaults; // Load arrays of urls...
//load arrays of urls...
- (NSArray*)addURLs:(NSArray *)urls sort:(BOOL)sort; - (NSArray*)addURLs:(NSArray *)urls sort:(BOOL)sort;
- (NSArray*)addURL:(NSURL *)url; - (NSArray*)addURL:(NSURL *)url;
- (NSArray*)insertURLs:(NSArray *)urls atIndex:(int)index sort:(BOOL)sort; - (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;
- (BOOL)save:(NSString *)filename asType:(PlaylistType)type; - (BOOL)save:(NSString *)filename asType:(PlaylistType)type;
- (BOOL)saveM3u:(NSString *)filename; - (BOOL)saveM3u:(NSString *)filename;
- (BOOL)savePls:(NSString *)filename; - (BOOL)savePls:(NSString *)filename;
//read info for a playlist entry // Read info for a playlist entry
- (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe; - (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe;
- (void)loadInfoForEntries:(NSArray *)entries; - (void)loadInfoForEntries:(NSArray *)entries;
@ -44,7 +44,7 @@ typedef enum {
- (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving - (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving
- (NSArray *)acceptableContainerTypes; - (NSArray *)acceptableContainerTypes;
// Event inlets (passed to playlist controler): // Events (passed to playlist controler):
- (void)willInsertURLs:(NSArray*)urls origin:(URLOrigin)origin; - (void)willInsertURLs:(NSArray*)urls origin:(URLOrigin)origin;
- (void)didInsertURLs:(NSArray*)entries origin:(URLOrigin)origin; - (void)didInsertURLs:(NSArray*)entries origin:(URLOrigin)origin;

View File

@ -26,18 +26,20 @@
self = [super init]; self = [super init];
if (self) if (self)
{ {
[self initDefaults]; queue = [[NSOperationQueue alloc] init];
[queue setMaxConcurrentOperationCount:1];
} }
return self; return self;
} }
- (void)initDefaults - (void)dealloc
{ {
[queue release];
[super dealloc];
} }
- (BOOL)save:(NSString *)filename - (BOOL)save:(NSString *)filename
{ {
NSString *ext = [filename pathExtension]; NSString *ext = [filename pathExtension];
@ -292,10 +294,6 @@
- (void)loadInfoForEntries:(NSArray *)entries - (void)loadInfoForEntries:(NSArray *)entries
{ {
NSOperationQueue *queue;
queue = [[[NSApplication sharedApplication] delegate] sharedOperationQueue];
NSInvocationOperation *oldReadEntryInfoOperation = nil;
for (PlaylistEntry *pe in entries) for (PlaylistEntry *pe in entries)
{ {
NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init]; NSAutoreleasePool *pool =[[NSAutoreleasePool alloc] init];
@ -305,22 +303,17 @@
initWithTarget:self initWithTarget:self
selector:@selector(readEntryInfo:) selector:@selector(readEntryInfo:)
object:pe]; object:pe];
if (oldReadEntryInfoOperation)
{
[readEntryInfoOperation addDependency:oldReadEntryInfoOperation];
[oldReadEntryInfoOperation release];
}
[readEntryInfoOperation addObserver:self [readEntryInfoOperation addObserver:self
forKeyPath:@"isFinished" forKeyPath:@"isFinished"
options:NSKeyValueObservingOptionNew options:NSKeyValueObservingOptionNew
context:NULL]; context:NULL];
[queue addOperation:readEntryInfoOperation]; [queue addOperation:readEntryInfoOperation];
oldReadEntryInfoOperation = [readEntryInfoOperation retain];
[readEntryInfoOperation release]; [readEntryInfoOperation release];
[pool release]; [pool release];
} }
[oldReadEntryInfoOperation release];
[queue waitUntilAllOperationsAreFinished]; [queue waitUntilAllOperationsAreFinished];