cog/Audio/PluginController.m

207 lines
4.4 KiB
Objective-C

#import "PluginController.h"
#import "Plugin.h"
@implementation PluginController
//Start of singleton-related stuff.
static PluginController *sharedPluginController = nil;
+ (PluginController*)sharedPluginController
{
@synchronized(self) {
if (sharedPluginController == nil) {
[[self alloc] init]; // assignment not done here
}
}
return sharedPluginController;
}
+ (id)allocWithZone:(NSZone *)zone
{
@synchronized(self) {
if (sharedPluginController == nil) {
sharedPluginController = [super allocWithZone:zone];
return sharedPluginController; // assignment and return on first allocation
}
}
return nil; //on subsequent allocation attempts return nil
}
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
- (id)retain
{
return self;
}
- (unsigned)retainCount
{
return UINT_MAX; //denotes an object that cannot be released
}
- (void)release
{
//do nothing
}
- (id)autorelease
{
return self;
}
//End of singleton-related stuff
- (id)init {
self = [super init];
if (self) {
codecPlugins = [[NSMutableArray alloc] init];
decoders = [[NSMutableDictionary alloc] init];
metadataReaders = [[NSMutableDictionary alloc] init];
propertiesReaders = [[NSMutableDictionary alloc] init];
}
return self;
}
- (void)setup
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self loadPlugins];
[self setupPlugins];
[self printPluginInfo];
[pool release];
}
- (void)loadPluginsAtPath:(NSString *)path
{
NSArray *dirContents = [[NSFileManager defaultManager] directoryContentsAtPath:path];
NSEnumerator *dirEnum = [dirContents objectEnumerator];
NSString *pname;
NSLog(@"Loading plugins at %@, candidates: %@", path, dirContents);
while (pname = [dirEnum nextObject])
{
NSString *ppath;
ppath = [NSString pathWithComponents:[NSArray arrayWithObjects:path,pname,nil]];
if ([[pname pathExtension] isEqualToString:@"bundle"])
{
NSBundle *b = [NSBundle bundleWithPath:ppath];
if (b)
{
NSLog(@"Loaded bundle: %@", b);
id plugin = [[[b principalClass] alloc] init];
NSLog(@"Candidate: %@", plugin);
if ([plugin respondsToSelector:@selector(pluginType)])
{
NSLog(@"Responds to selector");
switch([plugin pluginType])
{
case kCogPluginCodec: //Only type currently
NSLog(@"Its a codec");
[codecPlugins addObject:plugin];
break;
default:
NSLog(@"Unknown plugin type");
break;
}
}
}
}
}
}
- (void)loadPlugins
{
[self loadPluginsAtPath:[[NSBundle mainBundle] builtInPlugInsPath]];
[self loadPluginsAtPath:[@"~/Library/Application Support/Cog/Plugins" stringByExpandingTildeInPath]];
}
- (void)setupInputPlugins
{
NSEnumerator *pluginsEnum = [codecPlugins objectEnumerator];
id plugin;
while (plugin = [pluginsEnum nextObject])
{
Class decoder = [plugin decoder];
Class metadataReader = [plugin metadataReader];
Class propertiesReader = [plugin propertiesReader];
if (decoder) {
NSEnumerator *fileTypesEnum = [[decoder fileTypes] objectEnumerator];
id fileType;
NSString *classString = NSStringFromClass(decoder);
while (fileType = [fileTypesEnum nextObject])
{
[decoders setObject:classString forKey:fileType];
}
}
if (metadataReader) {
NSEnumerator *fileTypesEnum = [[metadataReader fileTypes] objectEnumerator];
id fileType;
NSString *classString = NSStringFromClass(metadataReader);
while (fileType = [fileTypesEnum nextObject])
{
[metadataReaders setObject:classString forKey:fileType];
}
}
if (propertiesReader) {
NSEnumerator *fileTypesEnum = [[propertiesReader fileTypes] objectEnumerator];
id fileType;
NSString *classString = NSStringFromClass(propertiesReader);
while (fileType = [fileTypesEnum nextObject])
{
[propertiesReaders setObject:classString forKey:fileType];
}
}
}
}
- (void)setupPlugins {
[self setupInputPlugins];
}
- (void)printPluginInfo
{
NSLog(@"Codecs: %@\n\n", codecPlugins);
}
- (NSDictionary *)decoders
{
return decoders;
}
- (NSDictionary *)metadataReaders
{
return metadataReaders;
}
- (NSDictionary *)propertiesReaders
{
return propertiesReaders;
}
@end
//This is called when the framework is loaded.
void __attribute__ ((constructor)) InitializePlugins(void) {
static BOOL wasInitialized = NO;
if (!wasInitialized) {
// safety in case we get called twice.
[[PluginController sharedPluginController] setup];
wasInitialized = YES;
}
}