First, a little backstory on how I got to this error in the first place (bear with me). I recently start a project using Robotlegs 2.0.0. Since this version was just released, a lot of the extensions are still being ported over. In my case, I had need of the RelaxedEventMap extension, which I had used heavily with RL1. Thankfully, CReynders was kind enough to port the existing RL1 source over to an RL2 extension; however, porting the extension also required a few minor tweaks to the RL framework source. What this meant to me is that if I wanted to use the RelaxedEventMap extension, I would need to download the latest Robotlegs source from GitHub which contained the previously mentioned tweaks (i.e. I could no longer use the latest compiled version of the RL2 SWC). I didn’t assume this would be a big deal, that is, until I tried to compile my application using Flash Pro. The compile-time went from about 2 seconds using the compiled RL2 SWC, to upwards of 30 seconds when including the RL2 framework source. All this led me down the path of compiling the RL2 SWC myself for the first time (see, I told you’d I’d get to the point eventually!).
While implementing the Robotlegs framework into my first application, I came across a rather common issue: How do I properly manage my views? To give you the basic run-down, my application has a number of different views (menus and various other screens) that need to be shown on the display at different times throughout the application lifecycle. What I wanted was a way to store all of my views, and be able to map events to show a specific view at a given time (ex: a user clicks the logout button in some component, I want the login menu to be shown). Add to this situation the fact dependency injection (while wonderful) has one pretty major flaw: If the object that needs to listen for a particular event is created after the event is dispatched, you end up with a race condition, and the object usually loses (and as such could be shown in an invalid state). For the example of the login menu, let’s say that the use clicks the logout button, the event is fired to trigger a logout command, which then tells the application to display the login menu. This is all well and good unless there is some event that the login menu needs to listen for that gets fired before it is created (ex: The logout Command fires an event to tell the app that the user has logged out and this event contains a message “The users has been logged out successfully” that the login menu is supposed to display). If you’re still managing to follow my confusing-ass example, give yourself a high five!
THE SOLUTION: Continue Reading
One of the common practices suggested by the Robotlegs team (and one I have personally grown to love) is the user of Interfaces for your services and data models. What this allows you to do is type-cast all of your injections and other references to these classes using the name of the Interface, then, when mapping these classes, you map the Interace to the either the concrete class or a seperate “mock” class that can be used for testing. This gives you the ability to quickly swap between mock data and live data by simply changing the injection mappings in your context file (or startup command or wherever you handle your mappings).
I ran into some issues today trying to get my first Robotlegs based application to run. I was using Flash Professional as my publishing tool and Flash Builder 4 as my code editor, and for some reason whenever I tried to publish the compiler would bark about a null object reference whenever I tried to access one of my views. After a bit of digging I stumbled across a blog post stating that you have to check the “Export swc” option in the Flash Professional publish settings when building a Robotolegs project using flash. After updating my publish settings everything worked perfectly. This has something to do with the compiler stripping out the [Inject] metadata when publishing the .swf.