Saturday, July 6, 2013

Codea AddOns Auto-Registration

I am currently enjoying one week of vacation and just spent some time building a proof-of-concept to show that Codea AddOns could be plug-and-play.

The idea is to be able to add plugin files to a newly exported Codea XCode project, build, and immediately have access to the AddOns without adding registration code to the AppDelegate.

Something we often have to do in Unity to avoid having to modifying the AppDelegate is to register for notifications like UIApplicationDidFinishLaunchingNotification in the class +load function, so I wanted to see if I could apply this concept to Codea. (see this)

The problem is that UIApplicationDidFinishLaunchingNotification will happen after the version found in AppDelegate.mm, after the Codea project has been loaded, which is too late to register AddOns.

However, I realized that we can manually send named notifications to classes. With this, I had all the puzzle pieces to build a plug-and-play solution.

Here's the simple change which would need to be added to Codea's default AppDelegate.mm file.

1:  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions  
2:  {  
3:    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];  
4:    self.viewController = [[CodeaViewController alloc] init];  
5:      
6:    [[NSNotificationCenter defaultCenter] postNotificationName:@"RegisterAddOns"  
7:                              object:self];  
8:      
9:    NSString* projectPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingPathComponent:@"MyProject.codea"];  
10:      
11:    [self.viewController loadProjectAtPath:projectPath];  
12:      
13:    self.window.rootViewController = self.viewController;  
14:    [self.window makeKeyAndVisible];  
15:      
16:    return YES;  
17:  }  

Once we have this, AddOn code can register for the RegisterAddOns notification and do the AddOn registration at the correct time. Here's an example:

1:  #import "AppDelegate.h"  
2:  #import "CodeaViewController.h"  
3:  #import "CommonAddOn.h"  
4:  #import "lua.h"  
5:    
6:  static CommonAddOn *commonAddOn;  
7:    
8:  @implementation CommonAddOn  
9:    
10:  + (void) load  
11:  {  
12:    [[NSNotificationCenter defaultCenter] addObserver:self  
13:                         selector:@selector(registerAddOn:)  
14:                           name:@"RegisterAddOns"  
15:                          object:nil];  
16:  }  
17:    
18:  + (void) registerAddOn:(NSNotification *)notification  
19:  {  
20:    commonAddOn = [[CommonAddOn alloc] init];  
21:    CodeaViewController *viewController = (CodeaViewController*)[(AppDelegate*)[[UIApplication sharedApplication]delegate] viewController];  
22:    [viewController registerAddon:commonAddOn];  
23:  }  
24:    
25:  - (id)init  
26:  {  
27:    self = [super init];  
28:    

I tested this solution and it works perfectly fine.

Now, let's hope the RegisterAddOns notification is actually added to Codea so that everyone can benefit from plug-and-play AddOns!

You can find the add-ons I wrote using this method on GitHub. I plan on converting other add-ons as well in the near future (GameCenter, etc.)

https://github.com/jfperusse/CodeaAddons

No comments:

Post a Comment