Category: Flex

  • Cairngorm Command Flaws and What You Can Do About Them

    From Day 1 I hated how Cairngorm Commands / Delegates didn’t give a status to what they were doing. Since Flex‘ primary purpose is a Rich GUI, and there isn’t a built in way to get status on Commands. For example, the flash.net.FileReference object will give you a progress event. This gives you the ability to show the actual progress of the upload in a progress bar. While most Commands are simple request / responses, sometimes you’ll call many of these in a row, with different ones at different times in the case of editing wizards.

    Even more important, however, is the flow of this logic. Some Commands contain logic that can be re-used elsewhere. For example, a GetPerson Command that get’s a specific person from a database by ID. There can be many other scenarios where you need to get a specific person from the database where you wish to store a local reference to it (for an EditPerson form for example), or you are just querying the data for some other operation. This still poses a problem for other Commands, however. They can’t re-use the Command in the Cairngorm way, but rather the Delegate way. Meaning, a Delegate usually takes in an mx.rpc.Responder. Therefore, you can call a method on a Delegate, and get a useful response in a result handler when it’s done, and an error response in a fault handler. You can’t do that with Commands. Commands are run only by the Controller, and have no callback support built in.

    While a Delegate, assuming one exists for the specific Command in the first place, is a viable way of re-using functionality, the application logic usually happens in the Commands, not the Delegates. The Delegates are responsible for merely getting the data, and parsing for use by the application. The Commands are the ones who do useful stuff with it like stick on the ModelLocator, or update your data model as appropriate. That valuable, and specific application logic is what I’m talking about here. Written in an encapsulated form, it is ripe for re-use. Yet, you can’t.

    Therefore, the only official way of sequencing Commands is using the SequenceCommand which basically locks you into a specific order, puts too much knowledge into a Command, and risks making them state-full. Meaning, by default you are locked to a specific order; the order in which you coded the Commands to call each other. The potential exists for a Command to “know” it was called by something else, thus forming a potential dependency. Dependencies bad. Third, if you know this, you may be tempted to put some conditional logic in there to help adjust for this and say “If I was called by the GetPerson Command, then I need to do this… otherwise, I’ll just do this.” Commands are use cases, and shouldn’t be determining the “way” they run the use case. If I ask you to SaveTheData, just save it. The Event that gets passed into the execute function tells the Command all it needs to know. While some would argue that the alternative Cairngorm where you have Many Events for every 1 Command as opposed to the default which is 1 to 1 allows this scenario to work well. While very true, it doesn’t scale well. Meaning, while having 1 LoginCommand capable of doing the work for a LoginEvent, ForgotPasswordEvent and ChangePassword event is very possible just by adding a switch statement for the event’s type in the execute function, your classes get very big, and less flexible. Yes, you do end up with more classes, but that’s what folders are for. Furthermore, there is nothing wrong with a bunch of classes that have less than 100 lines in them. Compare this with a few classes that have a thousand each. This is why a lot of people like Ruby on Rails; does a lot with few lines of code.

    Remember, we’re running client code here, not server-side. Our scalability needs are for code maintenance not performance. So, in this case, less code is better regardless of the performance implications.

    Even worse, you run into scenarios with the above where you have the urge to make your Commands state-full, meaning, they “remember” their state. That further makes your Commands less re-usable. Now to use a Command, you as the invoker have to know how the Command will use the Event class you choose, who it may call next, and what state it may already have. As if programming wasn’t hard enough. You shouldn’t have to know all of that stuff. Just dispatch an event, and have faith your use case will get resolved.

    How to solve these issues? If you were using Joe’s Controller, you could just add an event listener, make your call, and get an event when it was done for the asynchronous operations. For the synchronous ones, you could just return a result. Taken a step further, you could also return a token instead. For example, if the Controller were just an instance, the event model would work well. As soon as you handled the the event, the Controller instance would go out of scope, and the Garbage Collector in Flash Player would clean it up. However, Controllers are Singletons, so that won’t work. This means the user of the Controller is now responsible to “remember” to do a removeEventListener to ensure it doesn’t get events later it doesn’t care about. Kind of like the space shuttle docking with the space station. When it’s done, it first un-docks. That’s lame, though. It makes it a pain to deal with.

    The third option is to do what HTTPService and friends do using the token pattern. Since HTTPServices can either be used as 1 time instances or act like a Singleton (only 1 instance instantiated 1 time in the Services.mxml), it needs to support both ways of working. As such, all calls create their own instances of the call and return it. In this case, they’ll make a call, and associate a token with it. They’ll return this token to the caller. When the call comes back from the server, the HTTPService knows which token it is for, and so does the one who called it since he has a unique token for it. You can treat these tokens as instances. The only minor downside to this is when you are using these classes like HTTPService as instances, it takes a few more lines of code just to make a call. This is because it is assumed you’ll usually be using only 1 instance, but the class creators don’t want to lock you into an implementation, so give you the option to do both. Bottom line, the Token pattern is really for the developer to be able to tell the difference between multiple calls to the same service by comparing the token you get when making the call to the token you receive from the result handler’s event.

    …in Cairngorm’s case, he doesn’t have that option. You dispatch an event and that’s the last you hear of the call. Years ago, the suggestion was to simply set a ModelLocator variable as a state variable, and change it’s value when the Command was done. The first problem with this is that it only works if you only ever call the Command once. Since Commands are created as stateless instances, you could have a scenario where many are running. One variable cannot work for keeping state of all Commands. Secondly, this doesn’t scale because you then have state variables. View’s in Flex 2 have a great way of representing their own state and don’t need to offload that baggage to the Model. While the View can react to a change in the Model such as databinding, for GUI development, you need more than just a global variable. You need callback support.

    I developed some extensions to Cairngorm to support this as have others. Grant Davies and I originally did this for back in the Flash days, but with a different approach. We removed the need for Events, and just gave Controller the ability to launch Commands via method calls. We’d pass in parameters with the first 3 being scope, result callback function, and fault callback function. This allows any View, anywhere, to launch a use case AND have a result callback when the Command is done. Cairngorm & default ARP can only do the first part, not the latter.

    This changes the game, though for a lot of people’s perceptions. This means that the View in some cases is acting like a Controller. This is hard for a lot of traditional, non-Flex / Flash devs to understand. Traditionally non-GUI code handles this. However, a lot of people just assume that in Cairngorm’s case this means the Commands which leads to some of the problems mentioned above. This lead to the use of ViewLocator, a Singleton class that can access any View that has registered itself via a String. This allowed Commands the “formal” ability to access a View’s methods whenever it felt the need. The only justification I’ve have for this disgusting class was in a discussion over IM with Spike Milligan. It is in the case of a base Delegate detecting an expiring of a user’s login. You need some way to make the whoever your main view is to spawn a Login View in a PopUpManager. Another way is to have your main view add an event listener to the CairngormEventDispatcher for a “PromptLoginEvent”.

    A lot of Views in Flex case aren’t really View’s at all. SystemManager for example merely manages how the application is setup to actually show Views. Application.mxml is the main View, but typically he only has 2 children, the CSS style sheet you are linking in and Darron Schall‘s “MainView”… aka, your app.

    three_flex_views.png

    Even more granular, now that event bubbling is built into the Flash Player, we can encourage the “higher views have higher concerns” paradigm. Meaning, the higher the View is in the DisplayList, the more important it is. For example, Application.mxml is pretty damn important. Without him, you have no Flex app. MainView is the 2nd most important; he instantiates Cairngorm and starts your main application up. Without him, you just see the loading bar and resulting blue gradient. In an EditPersonWizard, he manages child views which in turn manage specific Person properties. An important key here to the whole thing is that they listen to their parent. If the parent, the EditPersonWizard, says next step, they disappear. The parent manages the children in the wizard, sets their data, and keeps a track of their changes. When the choreography is done, you’ve “Edited your person using the Edit Person Wizard successfully. Have a nice day!”. In effect, the EditPersonWizard is a controller. The same can be said for MainView. The same can be said for Application. They don’t just instantiate Views; they control them.

    One thing you should strive for is to NOT put Cairngorm specific event dispatching in your View’s. You should treat them as encapsulated components that you can reuse. Rule of thumb: If you can put a Cairngorm event to be dispatched in a parent instead of the current View, do it. With Flex 2, it is now easier to do this by either dispatching an even up to the parent, or just bubbling it up even higher than that. You should define the events in the MXML metadata, since a parent should know which events its children will dispatch, even if it won’t actually use them. This is very valid, btw; I don’t use a Button’s mouseDown or render event, but I commonly use its click event. Either way, all 3 are strongly-typed. You should make your Views strongly typed as well, even with the events.

    In effect, this allows your child views to dispatch events up the DisplayList and those higher up the chain who need to know get what the need to know. For example, a Button inside Step3 inside of EditPersonWizard doesn’t need to be reporting that the user clicked him to MainView.mxml. Step3 knows how to manage his subordinates and take the appropriate action. He’ll inform his parent, EditPersonWizard, of any changes that are important.

    What if Step3 needs to get a person from the database, however? Could you not just put a Cairngorm event dispatch right there in Step3? Of course! If you are in a hurry, go for it. Deadlines are deadlines. Should you? No. You couldn’t re-use this View elsewhere without dragging all of your Cairngorm code with it to work. Instead, you could build in a setter for the EditPersonWizard that was specifically put in place some MainView could then set it. But how does MainView.mxml know when to get the person? Does it need it immediately, or is it optional? In this case, we’ll Delegate the responsibility to Step3. Support is built into EditPersonWizard, but nothing is implied or demanded. Step3, when needed, can bubble the event up. EditPersonWizard can then do absolutely nothing as the event passes by. MainView can then catch this event (it’s defined in the EditPersonWizard’s metadata tag remember, so we have strong-typing in MXML here), and do the normal Cairngorm getting of data routine. Even without callback support, the data is set on the ModelLocator via the Command, and since it’ll probably be bound in MainView like , it’ll then propagate that data down to Step3. You’re effectively delegating authority just like real management does.

    You can see if you build View’s this way 4 things happen, 2 of which are good. First, you’re views are re-usable since they don’t have Cairngorm dependencies. So, you can re-use in the same application even with different data. Second, you don’t have to bind a lot of View’s to ModelLocator. Instead, they are given their data to them by their parents, again making your View’s more flexible. Third, you write more code in your View’s to support data in children. While this is more code, it’s good code in my view. Still, more code isn’t necessarily good, but better more code for the sake of encapsulation. Fourth, your higher level views spend a LOT of time getting data for people. If this is MainView.mxml for example, who has very little Views to handle, this is a great thing. For one thing, ALL Cairngorm use cases are dispatch from (hopefully, not always the case) 1 spot. Just like Commands are great in that you know for a fact they are usually the ONLY ones who set data on ModelLocator, you can be sure that the only one handling main application control logic is in MainView.

    The downside is this can be a lot of code, even for smaller apps. This is why a lot of programmers feel they need to put this stuff in Commands since at first glance, they appear related. They aren’t, though. The View’s are dictating what data they need since they are best suited at this. Things like lazy loading happen at the View’s discretion for example vs. the Controller. Further, the Views are the ones passing data up, whether packaged in an event object, or exposed view public getters. The parents of those Views as well as MainView may have context about that data that Commands may not know. In effect, you shielded the Commands from all of that View logic… thus reducing their code size. That’s a good thing! Views should be managing Views. Views can act like Controllers for other Views. That’s just the nature of GUI development whether composition or inheritance.

    The fatal flaw in this scenario is that MainView is crippled in this scenario in getting back to the View’s with their needed data or progress events. If you ask for time off from your manager, but their boss never responds to emails, you’ll never know if you can take those days off you need. This is the main problem I had with ARP, and the same problem I have with Cairngorm. With Cairngorm, I modified CairngormEvents to store callback functions. “Call this when you’re done”. This callback is then called from the Command “when it’s done”. This could be immediatley or after a Delegate returns from the server… whatever, whenever. Bottom line, a View can get a response when a use case is done. In this case, MainView can then pass the data down to EditPersonWizard, who will then pass it to Step3. If the Command just set it on ModelLocator, MainView doesn’t have to do anything in this case. But, if you were saving your changes, for example, and EditPersonWizard was disabled while the save happens, MainView can enable the form again once the save has successfully completed.

    In effect, this makes MainView a very effective View controller. For scalability purposes, you make a few MainViews who manage their section of the app.

    One of these days I’ll explain the technicalities behind using Callbacks; strongly typed responses that Delegates return to Commands, who in turn can return to Views. Views can use them just like they use ValueObjects, and get only the info that a Command allows it to have. ResultEvent is too generic, not strongly-typed, and View’s have no clue what they are supposed to do with it. Furthermore, it’s a code dependency risk too. That’s another blog entry…

  • Loading Flex Applications Into Flex Applications Gotcha: App Resizing

    I should be asleep, but this is such an awesome bug. Have the need to load one Flex app into another Flex app at work. Modules force us to refactor our 2 separate code bases, which we don’t have time nor budget to do right now and a component suffers from the same problem. Using a unique ApplicationDomain, I can load an app Mike built into an app I built without worrying about class collisions.

    Nick, a co-worker and brilliant PHP developer not even out of college, found a bug where if you went to a state that showed Mike’s app, then left that state which removes Mike’s app from the display list (that’s how states work), and then resized the browser, you got an exception. The stack trace is just 1 line, basically stating that mx.managers.SystemManager is having a problem with a null object in the Stage_resizeHandler function.

    The short description of the problem is that the “stage” property of DisplayObjects is null when a DisplayObject is not in the DisplayList. It’s set after it’s added. The SystemManager is designed to assume that the stage is never null in this case. The stage does become null, though, because since this application is only shown in one state, and then not shown in another means that it’s removed from the DisplayList. Therefore, the listener to the Stage object is still there, and the resize handler gets triggered when you resize your browser. Since the whole entire app, SystemManager included, is in fact a DisplayObject, it fails since its stage object is now null.

    It’s a justified design decision because the use case of loading Flex apps into other Flex apps is just weird to begin with, and thus an edge use case that doesn’t really get much testing. The “right” thing to do would be to build an encapsulated component or Module, thus rendering this use case invalid, and thus not a problem.

    The solution for now isn’t pretty because SystemManager’s resize handler, and the rest of the code it uses to setup the stage listeners is private, thus nothing I can really do save modifying the code directly, and recompiling the SWC. Not really a solution.

    Instead, we just removed the external app from the state, and add it to the main app. We then just use a SetProperty action for the state tag to toggle the visibility. Since being invisible and being out of the DisplayList are 2 different things, with the former still retaining a non-null reference to the Stage via the stage property, it works. To say that another way, when you set the visibility of a DisplayObject to false, like a MovieClip, it still retains it’s reference to the stage.

    Interestingly, I reckon removedFromStage was added in a new Flash Player 9 build (don’t know which one) because the 2.01 docs show it for flash.display.DisplayObject whereas the 2.0 docs do not. If SystemManager were to respond to this event, I think things would work just fine. Either that, or just code things to assume stage may be null.

    …again, in all fairness, this is a problem Flash Developers have run into for years, so didn’t really think it’d go away in Flex (although, I hoped it would). To quote one of the Flash greats with regards on how to code your Flash apps, which could apply in this case to your Flex apps:

    Be prepared to be loadMovie’d!

  • Flex Chronicles #25: E4X Gotchas

    Couple of E4X gotchas that have bitten me in past few weeks.

    Namespaces

    The first is namespaces. There is a good article on them in the Flex docs, but it may not be apparent why at first your parsing code is failing. In effect, it may not be failing, but simply looking for the wrong nodes. To give you the quick version of namespaces, check the following XML.

    <Button label="foo" />
    <Button label="bar" />

    Two XML nodes that represent Button’s in Flex. What if, however, you had a component called Button? How would you write it so Flex knew one was yours and the others was Adobe’s? Namespaces.

    <mx:Button />
    <jxl:Button />

    Notice the prefixes. The mx one will map somewhere, usually on the root node which defines the namespace. The same goes for yours.

    xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:jxl="com.jxl.controls.*"

    Now, those values are really just unique string representations. The URL for example is not actually checked. The package path for jxl however is checked by Flex Builder. The point is, using namespaces allows the same XML nodes to be used in an a block of XML and be identified as different. Therefore, the default E4X way of accessing XML nodes won’t work as expected. For example, the quick way to get at “book” in the following:

    var myXML:XML =
       <books xmlns="http://www.moogoo.com/">
           <book name="cheese">sup</book>
       </books>;

    Is not:

    trace(myXML.book); //

    But:

    var ns1:Namespace = new Namespace("http://www.moogoo.com/");
    default xml namespace = ns1;
    trace(myXML.book); // sup

    Namespaces are used in ActionScript 3 to identify specific methods. For example, public, private, protected, and mx_internal are namespaces. E4X has a similar way of using namespaces in AS3 because XML is basically a first class citizen in AS3. So, you have to define the namespace ABOVE your E4X specific code.

    If your XML doesn’t have namespaces, don’t worry about this jazz.

    By Ref vs. By Val

    The second gotcha is really hard for me to reproduce, so I’m not even sure this is accurately the problem but I DO know this is a working solution. I have a series of HTTPService POST’s to a series of PHP services. To work with the API, you send XML and get XML back. Simple stuff.

    To call it, I just build the XML by hand per call, and databind my values into it. Here’s a sample factory method:

    public static function getSampleRequest(userToken:String="",
                                                    appName:String="",
                                                    someParam:String=""):XML
    {
           var request:XML =
                      <Request>
                           <authentication>
                               <user_token>{userToken}</user_token>
                               <app_name>{appName}</app_name>
                           </authentication>
                           <Some_Action>
                               <some_param>{someParam}</some_param>
                           </Some_Action>
                       </Request>;
            
           return request;
     }
    

    I do the reverse when I get XML back, and parse out the values, converting those to Value Objects (strongly-typed AS3 classes that represent data objects; usually matching the database tables).

    One particular request, however, is a file upload. The new upload complete data, the event that is fired after the file upload is successful and shows the returned server data, allows me to upload a file, and get info about that file from our API. This XML, however, wasn’t parsing like the others were. I’d get a DataEvent back, cast the data property to XML, and go from there. However, in this case… something whack was happening not matter what I did (converting to XMLList, snagging first child as XML… nothing).

    I got so mad cause everything else was working, but I’d get weird parsing/casting results, like the XML getting a namespace prefix of “aaa” for all nodes. Weird stuff. I could copy and paste the exact XML into a new file and parse it just fine. Finally, I figured if it wasn’t the XML string, it must of been whatever it was attached to. So, instead of this:

    var myXML:XML = event.data as XML;

    I did this:

    var xmlStr:String = event.data as String;
    var my_xml:XML = new XML(xmlStr);

    Boo-fing-ya, it worked. My only guess is the by reference was injecting something “else” into the XML object whereas a freshly created String (by val) was good and pure. Once shoved into the XML constructor, it was fine and didn’t contain whatever mess the by ref did.

  • Controlling Flash Player 8 SWFs in Flash Player 9 SWFs

    One of the things I’ve been promoting the last year is encouraging people not to mess with loading legacy Flash Player 8 content into Flash Player 9, usually with regards to Flex 2 content loading Flash 8 content.

    ExternalInterface gives you less browser support, the calls are blocking which locks up your visual display depending on speed, and causes security debugging challenges if you don’t know exactly what you are doing. The last is the kicker because you DON’T have to know, you just know it works, and you move on. When under a deadline crunch with a boss yelling at you, it’s really frustrating to not know why a SWF is yelling about security rules. You don’t need another headache. LocalConnection is asynchronous, and has little strong-typing, and has a limit on the size of messages you can send. Furthermore, you have no guarantee every call you make will… make it. There have been abstraction attempts which really end up with about the same amount of code had you not abstracted it.

    Bottom line, it’s a major headache, painful to debug, and gets really funky when you start loading multiple pre-Flash Player 9 SWF’s into the same app. My guess is, it shares the same security & application domain sandbox which you’re code is not allowed access to. Therefore, any static variables I’m guessing are stuck there too (aka, classes on _global). Never really figured out the exact reason, but it’s just blatantly crazy how bad things are and just flat out don’t work as you’d expect.

    …but there is something far worse, and foreboding. Flash Player 9’s DisplayList + Garbage Collection. In Flash 8 and below, we’re pretty spoiled. We do a my_mc.removeMovieClip(), and poof, everything is gone. All sounds stop, everything stops showing, and most RAM goes with it, immediately. Not in Flash Player 9. Since you don’t have access to this AVM1Movie “sandbox”, whatever the heck it is, you can’t stop the stuff either. Case in point, load in a SWF with a video player, and then unload the SWFLoader. You’ll still hear the video, and it’ll STILL be using resources… that is, until Garbage Collection decides to nail it, if ever. In effect, Flex speaks Espanol, and Flash speaks English. You need a translator.

    In the past I’d do what I’ve been doing the last 2 years; reverently exclaim you need to go to management and explain the benefits of AS3, and just rewrite your legacy content. Since I wasn’t the one who had to deal with the ramifications & implementations of those decisions, it was pretty easy for me to do so upon a high horse.

    …then I started working for an Internet TV company. Thousands upon thousands of customers using Flash Player 8. Existing customers, entrenched, with working software. Boat loads of existing Flash Player 8, 7, and 6 content that works for a variety of existing customers and clients. In effect, Flash Player 8 content AND development isn’t going away for at least another year. Bugger…

    I tried eating my own dog food, but you can’t just immediately demand thousands of people upgrade their rigs without incurring significant costs and losses doing so. Then I tried my best to sequester myself away from said Flash Player 8 content. No dice. The amount, and thoroughness of some of the implementations was too great for me to just re-write in AS3. I can only code so fast.

    So, in the end, I’ve settled on a 3 tier setup. A Flex component that uses a SWFLoader via composition with 2 LocalConnections; 1 for talking to the SWF, and for the SWF to talk to it. A Flash Player 8, AS2 SWF that has 2 LocalConnections, 1 for talking to Flex, and another for Flex talking to it. This Flash SWF manages all content it loads, usually written for a specific piece of content. If you have control of the servers you are loading from, you can either have yourMovieClipLoader check the policy file, and boom, you’ve got no problem with loaded Flash content talking to Flash content. Even if it’s not yours, it’s very easy to dig around in someone else’s classes and “make stuff work” since everything is public in Flash Player 8 and below bytecode.

    The important job of the proxy.swf is clean up the mess when you unload stuff. In the case of a Video Player, you have to stop the video, stop all sounds, and unload the player. It’s ok if the Flex component holding the proxy.swf doesn’t die immediately; the proxy.swf has basically done his job well: stopped all multimedia, and lessened the RAM & CPU damage. An ancillary benefit is you can issue commands through this proxy.swf to control your content. I just send string messages in this case and the proxy.swf knows what to do with them.

    If you find yourself in this situation, don’t go down the ExternalInterface route; it’s too painful. Don’t load it using a simple Flex SWFLoader either since you’ll have no control over the content. Yes, it sucks you have to build a seperate SWF as a Mediator Pattern implementation, but if you don’t, you won’t have any control over the SWF you’re loading in. Remeber, test and get it working in Flash first before you start involving Flex in the mix.