// // MPT_PluginController.m // AUCoderDemo // // Created by Andrew Salamon on 9/25/06. // Copyright (c) 2006 Machine Perception Laboratory, // University of California San Diego. All rights reserved. #import "MPT_PluginController.h" #import "MPT_PluginProtocol.h" #import "MPT_PluginProtocolSVM.h" #import "MPT_ResolveAlias.h" #import "MPT_CERT.h" #import "MPT_AutoTileView.h" #import "MPT_AUView.h" #import "MPT_Preferences.h" extern "C" { #include } static MPT_PluginController *controller; @interface MPT_PluginController(PrivateMethods) - (void)initOnePlugin:(id)plugin; @end @implementation MPT_PluginController + (MPT_PluginController *)defaultController { if( !controller ) controller = [[MPT_PluginController alloc] init]; return controller; } - (id)init { if( self = [super init] ) { plugins = [[NSMutableArray alloc] init]; } return self; } - (void)dealloc { [plugins release]; [tileView release]; [cert release]; [super dealloc]; } - (MPT_AutoTileView *)tileView { return tileView; } - (void)setTileView:(MPT_AutoTileView *)value { if( tileView != value ) { [tileView release]; tileView = [value retain]; } } - (MPT_CERT *)cert { return cert; } - (void)setCert:(MPT_CERT *)value { if( cert != value ) { [cert release]; cert = [value retain]; } } - (NSArray *)plugins { return plugins; } - (NSArray *)sortedPlugins { return [[self plugins] sortedArrayUsingDescriptors:[MPT_Preferences pluginTableSortDescriptors]]; } - (NSArray *)pluginsForStep:(NSString *)step { NSMutableArray *steppers = [NSMutableArray array]; NSEnumerator *plugEnum = [plugins objectEnumerator]; id plugin; while( plugin = [plugEnum nextObject] ) { if( [[plugin step] isEqualToString:step] ) [steppers addObject:plugin]; } return steppers; } - (NSArray *)enabledPluginsForStep:(NSString *)step { NSMutableArray *steppers = [NSMutableArray array]; NSEnumerator *plugEnum = [plugins objectEnumerator]; id plugin; while( plugin = [plugEnum nextObject] ) { if( [[plugin step] isEqualToString:step] && [plugin enabled] ) [steppers addObject:plugin]; } return steppers; } - (void)loadPluginFromPath:(NSString *)path { path = [[[path stringByStandardizingPath] stringByResolvingSymlinksInPath] stringByResolvingAliases]; NSBundle *plugin = [NSBundle bundleWithPath:path]; [plugin load]; Class controller = [plugin principalClass]; id pc = [[controller alloc] init]; if( pc ) { [plugins addObject:pc]; } } - (void)loadPluginsInDirectory:(NSString *)path { NSFileManager *fileManager = [NSFileManager defaultManager]; NSArray *plugs = [fileManager directoryContentsAtPath:path]; NSEnumerator *plugEnum = [plugs objectEnumerator]; NSString *plugPath; while( plugPath = [plugEnum nextObject] ) { if( [[plugPath pathExtension] isEqualToString:@"bundle"] || [[plugPath pathExtension] isEqualToString:@"mptmod"] ) { [self loadPluginFromPath:[path stringByAppendingPathComponent:plugPath]]; } } } - (void)loadPlugins { NSArray *paths = NSSearchPathForDirectoriesInDomains( NSApplicationSupportDirectory, NSAllDomainsMask, YES ); NSEnumerator *pathEnum = [paths objectEnumerator]; NSString *path; while( path = [pathEnum nextObject] ) { path = [path stringByAppendingPathComponent:@"MPLab"]; path = [path stringByAppendingPathComponent:@"PlugIns"]; [self loadPluginsInDirectory:path]; } [self loadPluginsInDirectory:[[NSBundle mainBundle] builtInPlugInsPath]]; } - (BOOL)addPluginFromPath:(NSString *)path { return NO; } - (BOOL)removePlugin:(NSString *)pluginID { return NO; } - (BOOL)setEnable:(BOOL)enable forPlugin:(NSString *)pluginID { return NO; } - (void)initPlugins { [self loadPlugins]; id plugin; NSArray *sortedPlugins = [[self plugins] sortedArrayUsingDescriptors:[MPT_Preferences pluginTableSortDescriptors]]; NSEnumerator *pluginEnum = [sortedPlugins objectEnumerator]; while( plugin = [pluginEnum nextObject] ) { [self initOnePlugin:plugin]; } [tileView tileViews]; [cert pluginStateHasChanged:nil]; } - (void)initOnePlugin:(id)plugin { NSEnumerator *labelEnum = [[plugin labels] objectEnumerator]; NSString *label; while( label = [labelEnum nextObject] ) { MPT_AUView *view = [plugin viewForLabel:label]; if( view ) { [tileView addView:view]; } } NSDictionary *prefs = [[NSUserDefaults standardUserDefaults] objectForKey:[plugin pluginID]]; NSNumber *enabledNum = [prefs objectForKey:@"enabled"]; [plugin setEnabled:[enabledNum boolValue]]; [plugin setDelegate:self]; // Make sure the directory is set for these SVM Weights even if the user prevented them from pre-loading. if( [[plugin step] isEqualTo:MPT_PluginStep_SVM] ) { setDirectoryForWeights( [[plugin internalName] UTF8String], [[((id)plugin) weightsDirectory] UTF8String] ); } } /** Plugin delegate method. * Plugins will call back to this method whenever their enabled state changes, so we can take * appropriate actions. In this case hiding or showing the plugin's views. */ - (void)didChangeEnabledStateForPlugin:(id)plugin { BOOL isEnabled = [plugin enabled]; [tileView tileViews]; [cert pluginStateHasChanged:plugin]; NSMutableDictionary *prefs = [[NSUserDefaults standardUserDefaults] objectForKey:[plugin pluginID]]; NSNumber *enabledNum = [NSNumber numberWithBool:isEnabled]; if( prefs ) prefs = [prefs mutableCopy]; else prefs = [[NSMutableDictionary alloc] init]; [prefs setObject:enabledNum forKey:@"enabled"]; [[NSUserDefaults standardUserDefaults] setObject:prefs forKey:[plugin pluginID]]; [prefs release]; } - (void)resetViews { NSEnumerator *pluginEnum = [[self plugins] objectEnumerator]; id plugin; while( plugin = [pluginEnum nextObject] ) { NSEnumerator *labelEnum = [[plugin labels] objectEnumerator]; NSString *label; while( label = [labelEnum nextObject] ) { MPT_AUView *view = [plugin viewForLabel:label]; [view resetDynamicRange]; } } } @end