Redid threading for reading file info and metadata. Still a bit buggy.

CQTexperiment
matthewleon 2008-03-01 18:29:14 +00:00
parent a0cdf1a03e
commit 4168bb43eb
6 changed files with 90 additions and 55 deletions

View File

@ -49,6 +49,8 @@
AppleRemote *remote;
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;
@ -82,5 +84,7 @@ OSStatus handleHotKey(EventHandlerCallRef nextHandler,EventRef theEvent,void *us
- (IBAction)decreaseFontSize:(id)sender;
- (void)changeFontSize:(float)size;
// return the operation queue
- (NSOperationQueue *)sharedOperationQueue;
@end

View File

@ -35,11 +35,19 @@
remote = [[AppleRemote alloc] init];
[remote setDelegate: self];
queue = [[NSOperationQueue alloc]init];
}
return self;
}
- (void)dealloc
{
[queue release];
[super dealloc];
}
// Listen to the remote in exclusive mode, only when Cog is the active application
- (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];
}
- (NSOperationQueue *)sharedOperationQueue
{
return queue;
}
@end

View File

@ -50,10 +50,6 @@
+ (NSSet *)keyPathsForValuesAffectingStatus;
+ (NSSet *)keyPathsForValuesAffectingStatusMessage;
- (void)setProperties:(NSDictionary *)properties;
- (void)readPropertiesThread;
- (void)readMetadataThread;
@property(readonly) NSString *display;
@property(retain, readonly) NSNumber *length;
@property(readonly) NSString *path;

View File

@ -7,8 +7,6 @@
//
#import "PlaylistEntry.h"
#import "CogAudio/AudioPropertiesReader.h"
#import "CogAudio/AudioMetadataReader.h"
@implementation PlaylistEntry
@ -76,34 +74,6 @@
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
{
return [NSString stringWithFormat:@"PlaylistEntry %i:(%@)", self.index, self.URL];

View File

@ -9,6 +9,7 @@
#import <Cocoa/Cocoa.h>
@class PlaylistController;
@class PlaylistEntry;
typedef enum {
kPlaylistM3u,
@ -30,6 +31,9 @@ typedef enum {
- (BOOL)saveM3u:(NSString *)filename;
- (BOOL)savePls:(NSString *)filename;
//read info for a playlist entry
- (NSDictionary *)readEntryInfo:(PlaylistEntry *)pe;
- (NSArray *)acceptableFileTypes;
- (NSArray *)acceptablePlaylistTypes; //Only m3u and pls saving
- (NSArray *)acceptableContainerTypes;

View File

@ -9,11 +9,14 @@
#import "PlaylistLoader.h"
#import "PlaylistController.h"
#import "PlaylistEntry.h"
#import "AppController.h"
#import "NSFileHandle+CreateFile.h"
#import "CogAudio/AudioPlayer.h"
#import "CogAudio/AudioContainer.h"
#import "CogAudio/AudioPropertiesReader.h"
#import "CogAudio/AudioMetadataReader.h"
@implementation PlaylistLoader
@ -265,32 +268,77 @@
//Select the first entry in the group that was just added
[playlistController setSelectionIndex:index];
//Other thread for reading things...
[self performSelectorInBackground:@selector(readEntriesInfoThread:) withObject:entries];
NSOperationQueue *queue;
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;
}
- (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;
[entryInfo addEntriesFromDictionary:entryProperties];
[entryInfo addEntriesFromDictionary:[AudioMetadataReader metadataForURL:pe.URL]];
return entryInfo;
}
PlaylistEntry *pe;
for (pe in entries)
{
[pe readPropertiesThread];
[pe readMetadataThread];
//Hack so the display gets updated
if (pe == [playlistController currentEntry])
[playlistController performSelectorOnMainThread:@selector(setCurrentEntry:) withObject:[playlistController currentEntry] waitUntilDone:YES];
}
[playlistController performSelectorOnMainThread:@selector(updateTotalTime) withObject:nil waitUntilDone:NO];
[pool release];
- (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];
if (entryInfo == nil)
{
pe.error = YES;
pe.errorMessage = @"Unable to retrieve properties.";
}
else
{
[pe setValuesForKeysWithDictionary:entryInfo];
[playlistController updateTotalTime];
}
//Hack so the display gets updated
if (pe == [playlistController currentEntry])
[playlistController setCurrentEntry:[playlistController currentEntry]];
// stop observing
[object removeObserver:self forKeyPath:keyPath];
}
}
- (void)addURLs:(NSArray *)urls sort:(BOOL)sort