Flex 2 WebService & Cairngorm 2 Example

*** Update: 8.14.2007: The code in this article is out of date. Please refer to the new entry instead. ***

ws_icon.jpgThis example utilizes Amazon’s search webservice in the Cairngorm 2 application framework. You can go to Amazon.com and register for a free API key. Once you do, you just plug into this example’s constant file, and she’ll work for you too if you when you compile. This example application allows you to search for books on Amazon.com by keywords.

The events are debatable in their place in the package structure. They extend CairngormEvent, thus implying they fire commands, but you could reuse events. Also, I am not very good at E4X so please do not use that as an example of E4X usage.

Here’s basically how she works:

  1. App boots up, shows first state
  2. user types in some keywords, clicks the Search button
  3. this fires the doSearch event handler
  4. the doSearch handler creates a CairngormEvent, and dispatches it
  5. the Controller has mapped that type of event to a Command, and thus it runs the command, passing it the event
  6. the Command looks at the event type in the execute function and decides what to run, in this case, searchBooks, passing the event’s data to the function
  7. search books creates the Business Delegate, and calls its method
  8. the Delegate gets the WebService from the ServiceLocator, fires off the WebService, and waits for a response
  9. if the response is successful, it parses the E4X XML via a Factory to a list of Book ValueObjects
  10. finally, it calls the responder’s onResult function
  11. Since the Command is the Responder, he gets the data, and sets it to the ModelLocator and updates the applications state
  12. The View’s are bound to the state variable and book list in the ModelLocator, so they immediately have their bindings fire
  13. This causes the main app to change state, and show the results DataGrid
  14. The results DataGrid is bound to the books list in the ModelLocator, and shows the results.

* Note: I haven’t got my serial for Flex Builder 2 yet, so the App & View Source will time out after a day. The source, however, is good forever.

Flex 2 WebService & Cairngorm 2 Example – App | View Source | Source ZIP

BTW, I fixed my Atom feeds, thanks to those who let me know they were busted. If I don’t know it’s broke, I can’t fix it.

Flash & ARP Widget: DDO Server Status

Preface

Beautiful weekend here in Atlanta, Georgia, USA. Sunny, no clouds, and up to I believe 80 degrees (26 Celsius) this weekend. Naturally, I spent most of it indoors. Part of Friday evening and Sunday I spent creating this application just to see if I could do it. It pings the gaming servers for Dungeon & Dragons Online every minute, a massively multiplayer online roleplaying game. It solves 3 extremely niche problems:

  • You need to have the DDO game installed on your computer to get server status updates. This is a web application (or a executable widget); no installation necessary.
  • You need to login before you can see them. Using this app, you just visit whereever this app is hosted or double-click the executable on your desktop.
  • You need to have 51 megs to spare. This app takes 11 (less in a browser).

Why You Should Care

Like I said; extremely niche. That wasn’t the point, however. The goal was to set a challenge for myself, and learn in the process. A nice side-effect is some code I feel others can learn from.

Key takeaways:

  1. This is a pefect example of how to over-architect an application. This is a widget, not even an application, so the need for an Application Framework such as ARP was definately not needed and major overkill.
  2. Same code, 2 different runtime environments: Desktop and Web.
  3. Using a business delegate to handle all the “crap” involved with getting the business rules working.
  4. Using a business delegate to handle the security context. (Not sure if this was a good idea yet or not).
  5. How to get the new version of mProjector to handle Flash Player 8 filters plus transparency.

Digital Thorns in My Side

There were 2 things that really bothered me during and after development. The first, which I already mentioned, was allowing the business delegate to handle the security context. Basically, Flash Player running as a projector is not bound by the Flash Player security sandbox. When the Flash Player is not running in an executable, it is. The way I know is by checking for the existence of mProjector API’s. They are baked in when the mProjector exe file is made; stuck on global as static level objects with methods I reckon. If they aren’t there, you aren’t running in an mProjector created exe file, and thus are probably running as a SWF file, usually on the web in a web browser.

While I agree that the business delegate is the correct place to handle coverting the XML received from the server into a usable ActionScript class value object, I don’t necessarely agree it is the best place to handle security context. I DO agree that it certainly the easiest. Since he’s already making asyncronous calls to the server for specific data, why not just put it there? :: shrugs :: For me, the jury is out on that one.

The second was how I’ve allowed Commands to call a callback function. To me, you’re code that is calling a command usually wants:

  • something to happen
  • to know when it’s done
  • to get the data from the operation if any

Getting something to happen is easy; that’s what Commands do. Chunks of code usually responsible for getting or modifiying data, whether that be from local classes, firing other Views to do things, or making server calls via a business delegate (if applicable).

To know when it’s done is accomplished by my CommandRegistry; you can specify a callback function that the Command calls when it’s completed. This is called whenever the Command feels like it. This could be immediately, or after the business delegate has returned a result or fault… or never if you so choose; it is optional after all.

That last part, however, has got me stumped; mainly because I haven’t really thought through how to solve it. How does your result function “know” what it is getting back? It doesn’t, and that sucks. ResultEvent has a property called “result”. This property is not cast on purpose; this allows anythng to be passed into a ResultEvent. That way, if you talk to PHP, Java, Perl, Ruby, ColdFusion, or who the heck ever, you can throw that result into a ResultEvent, and you’re business delegate will get it and know where to look for it. But it’s the business delegate’s job, if your Command decides to use one, to massage and/or convert that into something usable and pass it back to the Command to handle. The Command can then easily pass this back to the result function.

The problem is, how does the instance invoking the Command know what the Command returns? Cairngorm users would argue, “A Command doesn’t ‘return’ anything; merely sets data on the ModelLocator, and bindings fire, and everyone’s informed and happy.” Uh…ok… so do we now declare that all Commands return true or false in their result functions? That certainly brings some order and understanding here, but greatly limits the functionality that result handlers provide. Remember this is Flash, we don’t have bindings like Flex does. There are some binding classes, sure, but they aren’t implemented as thoroughly nor as transparently as they are in Flex. Thus, it’s typically easier to get a result function and handle View updates manually. To me, this is justified since Flash projects aren’t as large in scope so this is more realistic a scenario anyway. Besides, making other datatypes act like Array’s do via DataProvider where changing an array via the DataProvider API methods dispatches a modelChanged event isn’t that diffucult to do.

So yeah, you could do boolean return values, but that is limiting. How about Event objects like ActionScript 3 does? Flex Builder 2 will actually give you compile error if the event type your event handler defines is the incorrect type. So, if you register for a MouseEvent, but define this in your event handler function:

function onPressed ( event : KeyEvent )

Flex Builder 2 will throw a compiler error.

However, you don’t register for Command events, you fire them off, and register a callback. I’m finding it hard to find some strongly typed way of “knowing” what a Command returns in it’s result function.

Anyway, I really had fun over-doing this widget and having it work in 2 runtime contexts (desktop vs. web) and 2 security contexts (desktop vs. web). It uses my modified version of ARP. Hopefully you can learn something from the code!

Instructions To Use

*** Warning: Currently, the web app utlizes a PHP proxy script on my server to get around Flash Player’s security sandbox. My suggestion is to host the PHP script on your own server, assuming you deem it secure enough, or some other proxy, and point your ddo_server_status_config.xml config file to have the proxy point to your server. I have no problem with you using mine (if you do nothing or don’t know what I’m talking about, it does by default), but if mine goes down (meaning they ban my server’s IP or my host bitches about bandwidth), then you’ll be forced to use your own, someone elses, or the exe instead. ***

To utilize the exe, just double-click the “DDOServerStatus.exe”.

If you wish to host the DDO Server Status app on your own site, simply do the following:

  1. upload the “DDOServerStatus.swf” to your site
  2. upload the “ddo_server_status_config.xml” next to the SWF
  3. put this HTML code in your webpage, ensuring the 2 paths to the SWF are correct:
<embed src="DDOServerStatus.swf" quality="high" bgcolor="#ffffff" width="136" height="330" name="DDOServerStatus" align="middle" allowScriptAccess="sameDomain" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer"></embed>

See you online!

Dungeons & Dragons Online: Server Status – Download It | Source

DrawingPad for Flex 2

A simple drawing pad for Flex 2, beta 2. Someone had asked on the Flexcoders list if there was a drawing component in Flex 2. This has been done countless times in Flash, so I wanted to use this as a reason to learn about some of the chagnes to UIComponent. There aren’t as many as I thought; easy to get up to speed if you’ve ever built a component in Flash MX 2004, Flash 8, or Flex 1.5.

There are a ton of things I could add to this, but I wanted to keep it simple for others to easily dive into the code. It took 4 hours to do, and while it uses next to no MXML, I am reminded how enjoyable it is to code ActionScript in Flex Builder 2.

Requires Flash Player 8.5 beta.

DrawingPad – App | Source | ZIP

Creative Commons License

This work is licensed under a Creative Commons Attribution 2.5 License.

Flex 2 States: Expanding Pod – ActionScript vs. MXML

One of the new features of Flex 2 is states. It allows you to declaratively define the state of a component. Flash Developers used to do this by using different frames for MovieClips in Flash. Since the timeline paradigm doesn’t exist in Flex, you had to use copious amounts of Effect ActionScript and/or ViewStacks to have a component have multiple states. Programmers would do the same thing in Flash too, using Tween engines like Animation Package and Laco Tween, abandoning the timeline entirely. Still, it was clear that Flash Developers had the edge.

The biggest issue here is that MXML offers a way to significantly increase code portability, reduce the amount of code written, and cleanly separate concerns. Once you started to fallback into pure ActionScript, you started to lose those benefits that MXML offered. You didn’t really have a choice before Flex 2.

For example, the typical ActionScript class has an import statement up top identifying the View control you wish to use. It then has some sort of init function to create the control and assign it default properties and add events. In another area is additional code to size the control based on it’s parent form resizing. Finally, there may be changes to it such as loading a new image into an image control as the result of a button click. This is 4 different places in code each operating on the same control. MXML helps centralize this into 1 tag.

For example, here is a common ActionScript 3 UIComponent class (psuedo code).

package
{
        import mx.controls.Button;
        import mx.containers.Canvas;
        import flash.events.MouseEvent;
        
        public class MyForm extends Canvas
        {
                
                protected var my_pb:Button;
                
                public function MyForm()
                {
                }
                
                override protected function createChildren():void
                {
                        super.createChildren();
                        my_pb = new Button();
                        addChild ( my_pb );
                        my_pb.addEventListener ( MouseEvent.CLICK, onClick );
                }
                
                override protected function updateDisplayList( unscaledWidth:Number,
                                                                                      unscaledHeight:Number):void
                {
                        super.updateDisplayList(unscaledWidth, unscaledHeight);
                        my_pb.width = width;
                }
                
                protected function onClick ( event : MouseEvent ) :void
                {
                        // do something
                }
        }
}

The thing that I think most ActionScript programmers have gotten their eyes trained to do is all “things used” are up top, defined in the imports. All things created GUI wise are somewhere near the top. All things initialized are usually in the same place as where they are being created. Finally, event handlers to respond to such things are near the bottom, mired with the rest of them.

MXML enters the picture, and throws a few for a loop. For example, the above, only done in MXML instead:

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.macromedia.com/2005/mxml">
<mx:Script> <![CDATA[
protected function onClick ( event : MouseEvent ) :void { // do something }
]]> </mx:Script>
<mx:Button id="my_pb" width="100%" click="onClick(event)" />
</mx:Canvas>

Significantly more compact. Additionally, it’s a lot easier to rip out the Button, and replace it with, say, a DateField all in 1 line of code. The only thing I DID keep was my event listener. However, again, the imports are gone… so who’s used? The creation is implied by putting the tag, so suddenly, you don’t have that comfort zone of seeing things clearly created. Finally, there is no sizing code; it’s relative to what container the control is in and what his x, y, width and height properties, if any, say.

Again, though, it’s really hard to have an appreciation for how much more centralized this model is if you haven’t written it by hand in AS for a long time. Changing the type, id (like an instance name), position, size, and event handlers are all done in the same place. This is a big change.

However, one thing you’ll notice is it is implied that the button is, forever after “there” and in the same state. Yes, you can apply effects to it, but it never disappears, and unless you bind, say, it’s label property to something, for the most part it never changes. …and that, my friends is what a lot of HTML interfaces do. Rarely if ever changes. They are a lot of times stateless, there for the explicit purpose of gathering data.

…but this is running atop the Flash Platform, and ultimately the Flash Player. We have room to move, grow, and the ability to change the GUI while keep the data intact and easily attainable. AJAX has helped significantly improve this for HTML without negatively affecting the rest of the HTML page, or app. It can be applied, even gregariously, and still be self-contained to improve certain portions of an app.

Flex 1.5 and AJAX still both suffer from the need of copious amounts of scripting to handle more than your average GUI change such as toggling DIV visibility or ViewStacks in Flex. To make a certain control / component have multiple states usually involves making it up of other smaller controls… or a lot of code whose intent is immediately apparent.

Enter states in Flex 2. Now you can significantly reduce the amount of code required to have a GUI control have many states, the intent of the MXML is clear, and centralized enough that it is orthogonally designed. States in MXML are declarative, meaning you write tags that clearly name their state, and what they are based on if any. You have the option of defining transitions, which are like effects, that allow you to more eloquently and clearly change from one state to the other. Taking advantage of the centralized nature of MXML, you can also change the GUI without affecting the states or transitions. You can change the states without affecting your core GUI. You can change your transitions without negatively affecting your GUI or states. Pimp.

This gives you a lot of flexibility, and lessens the need for in house Flash talent to get those challenging state changes… or hours of Herculean coding.

There are 4 basic ways to states in Flex allow you to change the component. You can add additional components, remove existing ones, change property values, change styles, and change event handlers. This is included with all the existing abilities to bind controls’ properties to data as well as having control of their creationPolicy. You even get events of when a state has started to change, when it’s done, and while it’s changing. You can use this to make sub-states for complex changes to allow one state change being completed to start the GUI automatically to change to another state. For example, if you minimize a window, you can have your GUI automatically change to the “hidden” state for example.

Transitions are cool because writing effects to handle the above usually involved registering for completion events, and ignoring the potential race conditions of a Fade maybe finishing after a Resize. While Effects do have the Sequence and Parallel classes to help this, you still have to setup functions to respond in the correct order after a specific state change.

Transitions are built for the sole purpose of melding state changes and effects easily and flexibly. You can create them explicitly to happen when one specific state changes to another, or when any state changes at all.

The example I did was re-creating the old Macromedia Central ExpandingPod. I originally did this last December to see how the new Flash 8 effects worked in Flex. You’ll notice there was really no point of me using MXML at all since the entire component is created via code. I redid it this weekend, ExpandingPod2, to utilize states. I originally thought that compared to say, ViewStacks, that it’d actually make MXML verbose and worse than the ActionScript, but in practice, I was wrong. It feels really good to have these things clearly separated; my state change from my transitions. In the ActionScript example they are all intertwined, and not very flexible, nor is it very clear where you can play to tweak things. The MXML version ended up being less code overall, too, which is nice.

This example also showcases Scale9 usage in Flex 2. The background pod image is 1 bitmap that does not scale the borders nor the corners. That way, I can have 1 bitmap instead of 1 sliced up into 9 pieces. Waldo Smeets has a better image example here.

All this example shows state wise is the change property state change tag. I did not add any other controls, nor remove them, nor change styles, nor change any event handlers. I think I’ll save the more complex sample for a later week; the most cliché control that every Flex developer tweaks… the Panel. Since everyone views them as windows, I’ll try to build an example that uses a more advanced example of adding and remove children.

In conclusion, the thing to look at here is the amount of ActionScript used in ExpandingPod.mxml, and compare to the way states are declaratively used in ExpandingPod2.mxml. Same control, different way to get the same result using the new “states” feature in Flex 2. If you click on View, you can also right click and View Source.

ExpandingPod (Requires Flash Player 8.5 beta)
View | Source