Redid threading for reading file info and metadata. Still a bit buggy.
This commit is contained in:
parent
a0cdf1a03e
commit
4168bb43eb
6 changed files with 90 additions and 55 deletions
|
@ -49,6 +49,8 @@
|
||||||
|
|
||||||
AppleRemote *remote;
|
AppleRemote *remote;
|
||||||
BOOL remoteButtonHeld; /* true as long as the user holds the left,right,plus or minus on the remote control */
|
BOOL remoteButtonHeld; /* true as long as the user holds the left,right,plus or minus on the remote control */
|
||||||
|
|
||||||
|
NSOperationQueue *queue; // Since we are the app delegate, we take care of the op queue
|
||||||
}
|
}
|
||||||
|
|
||||||
- (IBAction)openURL:(id)sender;
|
- (IBAction)openURL:(id)sender;
|
||||||
|
@ -82,5 +84,7 @@ 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
|
||||||
|
|
|
@ -35,11 +35,19 @@
|
||||||
|
|
||||||
remote = [[AppleRemote alloc] init];
|
remote = [[AppleRemote alloc] init];
|
||||||
[remote setDelegate: self];
|
[remote setDelegate: self];
|
||||||
|
|
||||||
|
queue = [[NSOperationQueue alloc]init];
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)dealloc
|
||||||
|
{
|
||||||
|
[queue release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
// Listen to the remote in exclusive mode, only when Cog is the active application
|
// Listen to the remote in exclusive mode, only when Cog is the active application
|
||||||
- (void)applicationDidBecomeActive:(NSNotification *)notification
|
- (void)applicationDidBecomeActive:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
|
@ -462,4 +470,9 @@ increase/decrease as long as the user holds the left/right, plus/minus button */
|
||||||
[self changeFontSize:-1];
|
[self changeFontSize:-1];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSOperationQueue *)sharedOperationQueue
|
||||||
|
{
|
||||||
|
return queue;
|
||||||
|
}
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -50,10 +50,6 @@
|
||||||
+ (NSSet *)keyPathsForValuesAffectingStatus;
|
+ (NSSet *)keyPathsForValuesAffectingStatus;
|
||||||
+ (NSSet *)keyPathsForValuesAffectingStatusMessage;
|
+ (NSSet *)keyPathsForValuesAffectingStatusMessage;
|
||||||
|
|
||||||
- (void)setProperties:(NSDictionary *)properties;
|
|
||||||
- (void)readPropertiesThread;
|
|
||||||
- (void)readMetadataThread;
|
|
||||||
|
|
||||||
@property(readonly) NSString *display;
|
@property(readonly) NSString *display;
|
||||||
@property(retain, readonly) NSNumber *length;
|
@property(retain, readonly) NSNumber *length;
|
||||||
@property(readonly) NSString *path;
|
@property(readonly) NSString *path;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "PlaylistEntry.h"
|
#import "PlaylistEntry.h"
|
||||||
#import "CogAudio/AudioPropertiesReader.h"
|
|
||||||
#import "CogAudio/AudioMetadataReader.h"
|
|
||||||
|
|
||||||
@implementation PlaylistEntry
|
@implementation PlaylistEntry
|
||||||
|
|
||||||
|
@ -76,34 +74,6 @@
|
||||||
return [NSSet setWithObjects:@"current", @"queued", @"queuePosition", @"error", @"errorMessage", @"stopAfter", nil];
|
return [NSSet setWithObjects:@"current", @"queued", @"queuePosition", @"error", @"errorMessage", @"stopAfter", nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setProperties:(NSDictionary *)properties
|
|
||||||
{
|
|
||||||
if (properties == nil)
|
|
||||||
{
|
|
||||||
self.error = YES;
|
|
||||||
self.errorMessage = @"Unable to retrieve properties.";
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self setValuesForKeysWithDictionary:properties];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)readPropertiesThread
|
|
||||||
{
|
|
||||||
NSDictionary *properties = [AudioPropertiesReader propertiesForURL:self.URL];
|
|
||||||
|
|
||||||
[self performSelectorOnMainThread:@selector(setProperties:) withObject:properties waitUntilDone:YES];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)readMetadataThread
|
|
||||||
{
|
|
||||||
NSDictionary *metadata = [AudioMetadataReader metadataForURL:self.URL];
|
|
||||||
|
|
||||||
[self performSelectorOnMainThread:@selector(setValuesForKeysWithDictionary:) withObject:metadata waitUntilDone:YES];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)description
|
- (NSString *)description
|
||||||
{
|
{
|
||||||
return [NSString stringWithFormat:@"PlaylistEntry %i:(%@)", self.index, self.URL];
|
return [NSString stringWithFormat:@"PlaylistEntry %i:(%@)", self.index, self.URL];
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
@class PlaylistController;
|
@class PlaylistController;
|
||||||
|
@class PlaylistEntry;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
kPlaylistM3u,
|
kPlaylistM3u,
|
||||||
|
@ -30,6 +31,9 @@ typedef enum {
|
||||||
- (BOOL)saveM3u:(NSString *)filename;
|
- (BOOL)saveM3u:(NSString *)filename;
|
||||||
- (BOOL)savePls:(NSString *)filename;
|
- (BOOL)savePls:(NSString *)filename;
|
||||||
|
|
||||||
|
//read info for a playlist entry
|
||||||
|
- (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe;
|
||||||
|
|
||||||
- (NSArray *)acceptableFileTypes;
|
- (NSArray *)acceptableFileTypes;
|
||||||
- (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving
|
- (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving
|
||||||
- (NSArray *)acceptableContainerTypes;
|
- (NSArray *)acceptableContainerTypes;
|
||||||
|
|
|
@ -9,11 +9,14 @@
|
||||||
#import "PlaylistLoader.h"
|
#import "PlaylistLoader.h"
|
||||||
#import "PlaylistController.h"
|
#import "PlaylistController.h"
|
||||||
#import "PlaylistEntry.h"
|
#import "PlaylistEntry.h"
|
||||||
|
#import "AppController.h"
|
||||||
|
|
||||||
#import "NSFileHandle+CreateFile.h"
|
#import "NSFileHandle+CreateFile.h"
|
||||||
|
|
||||||
#import "CogAudio/AudioPlayer.h"
|
#import "CogAudio/AudioPlayer.h"
|
||||||
#import "CogAudio/AudioContainer.h"
|
#import "CogAudio/AudioContainer.h"
|
||||||
|
#import "CogAudio/AudioPropertiesReader.h"
|
||||||
|
#import "CogAudio/AudioMetadataReader.h"
|
||||||
|
|
||||||
@implementation PlaylistLoader
|
@implementation PlaylistLoader
|
||||||
|
|
||||||
|
@ -265,32 +268,77 @@
|
||||||
//Select the first entry in the group that was just added
|
//Select the first entry in the group that was just added
|
||||||
[playlistController setSelectionIndex:index];
|
[playlistController setSelectionIndex:index];
|
||||||
|
|
||||||
//Other thread for reading things...
|
NSOperationQueue *queue;
|
||||||
[self performSelectorInBackground:@selector(readEntriesInfoThread:) withObject:entries];
|
queue = [[[NSApplication sharedApplication] delegate] sharedOperationQueue];
|
||||||
|
|
||||||
|
NSInvocationOperation *oldReadEntryInfoOperation = Nil;
|
||||||
|
for (PlaylistEntry *pe in entries)
|
||||||
|
{
|
||||||
|
NSInvocationOperation *readEntryInfoOperation;
|
||||||
|
readEntryInfoOperation = [[[NSInvocationOperation alloc]
|
||||||
|
initWithTarget:self
|
||||||
|
selector:@selector(readEntryInfo:)
|
||||||
|
object:pe] autorelease];
|
||||||
|
if (oldReadEntryInfoOperation)
|
||||||
|
{
|
||||||
|
[readEntryInfoOperation addDependency:oldReadEntryInfoOperation];
|
||||||
|
[oldReadEntryInfoOperation release];
|
||||||
|
}
|
||||||
|
[readEntryInfoOperation addObserver:self
|
||||||
|
forKeyPath:@"isFinished"
|
||||||
|
options:NSKeyValueObservingOptionNew
|
||||||
|
context:NULL];
|
||||||
|
[queue addOperation:readEntryInfoOperation];
|
||||||
|
oldReadEntryInfoOperation = [readEntryInfoOperation retain];
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)readEntriesInfoThread:(NSArray *)entries
|
- (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
// Just setting this to 30 for now...
|
||||||
|
NSMutableDictionary *entryInfo = [NSMutableDictionary dictionaryWithCapacity:30];
|
||||||
|
NSDictionary *entryProperties;
|
||||||
|
entryProperties = [AudioPropertiesReader propertiesForURL:pe.URL];
|
||||||
|
if (entryProperties == nil)
|
||||||
|
return nil;
|
||||||
|
|
||||||
PlaylistEntry *pe;
|
[entryInfo addEntriesFromDictionary:entryProperties];
|
||||||
for (pe in entries)
|
[entryInfo addEntriesFromDictionary:[AudioMetadataReader metadataForURL:pe.URL]];
|
||||||
{
|
return entryInfo;
|
||||||
[pe readPropertiesThread];
|
}
|
||||||
|
|
||||||
[pe readMetadataThread];
|
- (void)observeValueForKeyPath:(NSString *)keyPath
|
||||||
|
ofObject:(id)object
|
||||||
|
change:(NSDictionary *)change
|
||||||
|
context:(void *)context
|
||||||
|
{
|
||||||
|
// We finished reading the info for a playlist entry
|
||||||
|
if ([keyPath isEqualToString:@"isFinished"] && [object isFinished])
|
||||||
|
{
|
||||||
|
// get the results
|
||||||
|
NSDictionary *entryInfo = [object result];
|
||||||
|
// get the playlist entry that the thread was inspecting
|
||||||
|
PlaylistEntry *pe;
|
||||||
|
[[object invocation]getArgument:&pe atIndex:2];
|
||||||
|
|
||||||
//Hack so the display gets updated
|
if (entryInfo == nil)
|
||||||
if (pe == [playlistController currentEntry])
|
{
|
||||||
[playlistController performSelectorOnMainThread:@selector(setCurrentEntry:) withObject:[playlistController currentEntry] waitUntilDone:YES];
|
pe.error = YES;
|
||||||
}
|
pe.errorMessage = @"Unable to retrieve properties.";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
[pe setValuesForKeysWithDictionary:entryInfo];
|
||||||
|
[playlistController updateTotalTime];
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hack so the display gets updated
|
||||||
[playlistController performSelectorOnMainThread:@selector(updateTotalTime) withObject:nil waitUntilDone:NO];
|
if (pe == [playlistController currentEntry])
|
||||||
|
[playlistController setCurrentEntry:[playlistController currentEntry]];
|
||||||
[pool release];
|
// stop observing
|
||||||
|
[object removeObserver:self forKeyPath:keyPath];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort
|
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort
|
||||||
|
|
Loading…
Reference in a new issue