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.
parent
e2d590c167
commit
d6a0b0670e
|
@ -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
|
||||
|
|
|
@ -469,8 +469,4 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
|
|||
|
||||
}
|
||||
|
||||
- (NSOperationQueue *)sharedOperationQueue
|
||||
{
|
||||
return queue;
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import <Growl/GrowlApplicationBridge.h>
|
||||
|
||||
@class PlaybackController;
|
||||
@class PlaylistLoader;
|
||||
@class AudioScrobbler;
|
||||
@interface PlaybackEventController : NSObject <GrowlApplicationBridgeDelegate> {
|
||||
NSOperationQueue *queue;
|
||||
|
||||
AudioScrobbler *scrobbler;
|
||||
IBOutlet PlaybackController *playbackController;
|
||||
IBOutlet PlaylistLoader *playlistLoader;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<object class="NSMutableArray" key="IBDocument.EditedObjectIDs">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
<integer value="21"/>
|
||||
<integer value="2234"/>
|
||||
<integer value="29"/>
|
||||
<integer value="2234"/>
|
||||
</object>
|
||||
<object class="NSArray" key="IBDocument.PluginDependencies">
|
||||
<bool key="EncodedWithXMLCoder">YES</bool>
|
||||
|
@ -6882,6 +6882,14 @@ OQA</bytes>
|
|||
</object>
|
||||
<int key="connectionID">2406</int>
|
||||
</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 class="IBMutableOrderedSet" key="objectRecords">
|
||||
<object class="NSArray" key="orderedObjects">
|
||||
|
@ -10475,7 +10483,7 @@ OQA</bytes>
|
|||
</object>
|
||||
</object>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">2406</int>
|
||||
<int key="maxID">2407</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<object class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
|
@ -10890,8 +10898,8 @@ OQA</bytes>
|
|||
<string key="className">PlaybackEventController</string>
|
||||
<string key="superclassName">NSObject</string>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">playbackController</string>
|
||||
<string key="NS.object.0">PlaybackController</string>
|
||||
<string key="NS.key.0">playlistLoader</string>
|
||||
<string key="NS.object.0">PlaylistLoader</string>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
|
|
|
@ -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]];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue