Making ActionScript Look Beautiful: Increasing Readability and Loosing Verboseness
After playing around with languages such as Ruby and Groovy, I’ve been yearning to loose a lot of the verboseness of ActionScript. I feel that many languages tend to be overly expressive, and hide the concepts of what your code is actually doing.
Lets take a simple example of a snippet of code that represents, Is tomorrow after today?
function isTomorrowAfterToday():Boolean { var now:Date = new Date(); var today:Date = new Date(now.setHours(0, 0, 0, 0)); var tomorrow:Date = new Date(now.setDate(now.date + 1)); return tomorrow.getTime() > today.getTime(); }
To me this is bloated, confusing and unreadable. Creation logic is obfuscated and not DRY. Variables are created to represent common concepts, and comparison operators are used that don’t represent the real domain. However, this is how I see most code in ActionScript written. It is the path of least resistance to getting your project done. Most languages are like this and give you the lowest levels of the API, without providing any means to working with them easier. Why not give the developers a proper toolkit to make this more sensible?
So lets try cleaning it up:
function isTomorrowAfterToday():Boolean { return Date.tomorrow().isAfter(Date.today()); }
See how much better that is. So what have we done here?
- First, we’ve consolidated the creation logic (
Date.tomorrow()andDate.today()), and they belong to the class they represent. Not only is it readable, but it’s DRY. - Second, we’ve taken the greater than operator and made it into a method,
Date.isAfter(). Is tomorrow greater than today? No! Dates have no concept of greater than or less than. - Third we’ve removed accessors that return the primitive data that the class uses to store state. Why should my code have to know that
Date.getTime()returns the primitive data used to compare dates? To selfishly put it; the only thing my code should care about is to ask the question, Is tomorrow after today?
Let’s take it one step further:
import flash.date.tomorrow; import flash.date.today; function isTomorrowAfterToday():Boolean { return tomorrow().isAfter(today()); }
Getting closer. So what have we done? Well, we’ve taken the concept of creation, and have moved it once again. Creation can be generalized into the package of which the main class it represents. In this case, the Date class can be given it’s own package flash.date.
Taking it another step further:
import flash.comparison.is; import flash.date.tomorrow; import flash.date.today; function isTomorrowAfterToday():Boolean { return is(tomorrow().after(today())); }
Perfect! Again, so what have we done here? We’ve abstracted the concept of equality into it’s own package. We can express other concepts of comparison such as not().
Like so:
import flash.comparison.is; import flash.comparison.not; import flash.date.tomorrow; import flash.date.today; function isTomorrowNotTheSameAsToday():Boolean { return is(tomorrow().not(today())); }
Lets take a whole different concept, such as distance, and model the simple question, Is 10 feet farther than 5 feet?
import flash.comparison.is; import flash.distance.Distance; import flash.imports.use; function is10FeetFartherThan5Feet():Boolean { use(Distance); return is((10).feet().fartharThan((5).feet()); }
You might be asking yourself, “Is this really ActionScript?” The answer is yes, and can be accomplished with the use of ActionScript’s Object.prototype static property. Again what is all of this doing?
- First, we’re telling our function that we’ll be using classes and methods for distances. This acts like an import statement, and adds prototype methods to Flash’s
Numberclass. - Second, we’re creating distances based off of a number. When we call
10.feet()we’re calling a prototype method that we’ve defined onNumberto return aDistanceobject of 10 feet. In English, this reads much nicer. - Third, we’re reusing the concepts that we’ve established earlier.
is()is an equality concept that we defined within theflash.comparisonpackage. We’re using method names used to compare objects of the same type,Distance.fartherThan(). Lastly, we’re comparing the primitive values of an object, by not having to compare the values of both distances explicitly with call likeFeet.value.
Many of the concepts are things you can start using today. Begin by adding reusable and readable comparison methods, such as Person.isOlder() or Person.isYounger(). It’ll increase the reusability of your domain and make it much more rich. Also, add and chain together static builder methods in your classes, i.e. var dan:Person = Person.thatIs().male().age(24).name("dan").
Happy coding, and keep it clean!
Help Dan find a Flex Engineer and get a free paid trip for 2 to Hawaii
Put me in touch with a Flex Engineer that we hire, and we’ll fly you and a friend to Hawaii, put you both up in a hotel, AND fly you back. Huh? Sick of making your friends jealous from all those Hawaii excursions?? Well, you have the option to choose the tech package, which includes a 42″ LCD TV and Macbook Air. Gez, not interested in that either?? Then eBay it, and get cash for tech!
Take a look at our job posting, which has all the details about the position.
A little info about the company. Mixbook (www.mixbook.com) is a profitable, rapidly-growing San Jose, CA, startup that allows people to collaboratively create photo books through a powerful online Flex application. Users can share their creations online for free online – like a YouTube for photo books - or purchase bookstore-quality copies of their work to share in real life (see http://www.mixbook.com/printed-photo-books). Over 2 million people have created over 5 million photo books on Mixbook’s platform – your work will impact a community of millions.
We offer competitive salary and generous equity stakes, along with benefits, a new Mac or PC, dual monitors, and a chance to impact a community of millions. We’re looking for talented and passionate people who take pride in giving customers a phenomenal and enriching online experience.
Please share!
What’s Happening With Cayri?
Just wanted to throw a quick update to anyone interested in the state of affairs with Cayri. A while back my host shutdown the cron script that was parsing the VATSIM and IVAO data files.
Looking deeper into the problem, there appears to be a very inefficient database query which runs on each pilot that is parsed from these files. In addition, I believe the problem was compounded by the increase of users flying on both of these networks.
I will be having some available time over the winter holidays to hopefully fix this issue.
Saving Flex’s Application State to a Database
Bill Sanders has a great post on the Memento design pattern over at his blog. After reading it, I thought I’d chime in and post a technique that takes the memento one step further. This approach allows you to serialize a Memento object into a ByteArray and save it into a database. Then, retrieving the Memento object from the server, dynamically instantiated it, and restoring its previous state.
One major draw back to the Memento, as you’ll see, is that restoring an object’s state can be a very expensive operation. Especially in a Flex environment where restoring a Memento could trigger a large display list invalidation. For that reason, the Memento is not always the ideal pattern for implementing undo/redo functionality. The alternative pattern for implementing this functionality is the Command pattern. With the Command pattern, each command is only concerned about a particular action to get to the current state of the application. With this, you can have an undo() method in each of your commands that undoes whatever action was performed in your execute() method.
Ok, so where could we apply the Memento then? Hmm .. how about a Monopoly game! Since a game of Monopoly can be pretty lengthy, the user might want to be able to save the game on the server, so that he/she can come back later to finish it off. There’s a couple ways to accomplish this functionality:
- Create a multitude of database tables that represent objects in your application. For example, a Player’s table to keep track of the current players, how much money they have, etc. A Properties table to keep track of the game’s properties. A Properties to Players linking table to store which properties each player owns, and so on.
- OR, create one table whose role is to store Mementos for each of the objects in the game. I think this approach sounds easier, and since it’s in the scope of this article, we’re going to focus on this approach.
The Memento Classes

In order for our application to save its state using the Memento pattern, we need to write a couple classes and interfaces that our objects will implement. Note that my Memento classes slightly differ from that described on Wikipedia and Bill Sanders blog. The reason for this was that I wanted to inspect which type of object each Memento originated from. By doing this, you can re-instantiate the Memento dynamically when it comes back from the database. I also wanted any classes that supported restoration to be of a certain type – IRestorable.
Each class that you want to save and restore state to must implement the IRestorable interface. This interface has two simple methods that either creates or accepts a Memento object.
public interface IRestorable { function restore(state:ObjectState):void; function save():ObjectState; }
Next is the Memento class that is called ObjectState. This class is where you store all the data that the class needs to restore its state back to what it was. These objects can also be serialized and saved to the database (more on this later). You’ll notice that I’ve marked this class as dynamic so that you can add anything you want to it. The only defined property it has is className. You set this to the fully qualified class name that generated the Memento. Another important thing to note: you must put the [RemoteClass] metatag in the ObjectState class definition. I’ll show you later how you can use this property to re-instantiate the object based on this class name property.
[RemoteClass(alias="my.custom.package.ObjectState")] public dynamic class ObjectState { public var className:String; }
Pretty simple stuff, huh? Let’s take a look at a simple class that implements both of these classes. This class, called MyCustomComp, implements the IRestorable interface with the two methods described above. The save() method’s job is to take all the data that this component needs to re-instantiate itself and save it to a new ObjectState. In our case, it’s the text strings from the three TextInput controls. The restore() method’s job is to take those three text strings, and reapply them to our TextInput controls. So whatever is done in the restore() method, needs to be saved to the ObjectState in the save() method.
public class MyCustomComp extends UIComponent implements IRestorable { // Sub-components in our component that we want to // restore the data to. public var textInput1:TextInput; public var textInput2:TextInput; public var textInput3:TextInput; public function MyCustomComp() { super(); } override protected function createChildren():void { super.createChildren(); // Create the sub-components. textInput1 = new TextInput(); textInput1.text = "Text 1"; addChild(textInput1); textInput2 = new TextInput(); textInput2.text = "Text 2"; addChild(textInput2); textInput3 = new TextInput(); textInput3.text = "Text 3"; addChild(textInput3); } public function restore(state:ObjectState):void { // Make sure to throw a TypeError if the class name is // incorrect. if (state.className != flash.utils.getQualifiedClassName(this)) throw new TypeError("This ObjectState was not created from the MyCustomComp class"); // Take the text data from the ObjectState and restore // it to our sub-components. textInput1.text = state.text1; textInput2.text = state.text2; textInput3.text = state.text3; // Restore the position of the component. x = state.xPos; y = state.yPos; } public function save():ObjectState { var state:ObjectState = new ObjectState(); state.className = flash.utils.getQualifiedClassName(this); // Since the ObjectState is dynamic, we can set anything // on it. Set the text from each of the sub-components // into our memento object. state.text1 = textInput1.text; state.text2 = textInput2.text; state.text3 = textInput3.text; // Save the X and Y positioning of this component. state.xPos = x; state.yPos = y; return state; } }
Serializing the ObjectState to the Database
When it’s time to send the ObjectState across the wire and save it to the database, we need to do a simple operation first. This operation will save the ObjectState into a ByteArray so that the database can store it.
// The component that we want to save and restore data to. var myRestorableComp:MyCustomComp = new MyCustomComp(); // Save the component's state. var state:ObjectState = myRestorableComp.save(); // Write the state object into a ByteArray. var stateBytes:ByteArray = new ByteArray(); stateBytes.writeObject(state); // Code to send the ByteArray to the server via Flash Remoting. myService:RemoteObject = myRemotingService; myService.saveMemento(stateBytes);
Also, in order to save serialized objects to a database, you need to set the field in which they’re stored as a BLOB. This way, the serialized structure of the object isn’t modified when you save it.
Retrieving the Memento from the Server
After we save the state to the database, a user will more than likely want to retrieve it. Also, you might want to dynamically re-instantiate the component that the Memento’s originated from. You can achieve this by passing the ObjectState’s className property into Flash’s flash.utils.getDefinitionByName() method.
public class MyCompContainer extends Canvas { private var service:RemoteObject; public function MyCompContainer() { super(); service = new RemoteObject(); service.addEventListener(ResultEvent.RESULT, retrievedMementoHandler); ... service.retrieveMemento(someUniqueMementoId); } // The result handler that was added to the remoting object. private function retrievedMementoHandler(event:ResultEvent):void { // We saved the ObjectState into a ByteArray, so we're // going to get it back as a ByteArray. var stateBytes:ByteArray = event.result as ByteArray; stateBytes.position = 0; // Read the Memento from the ByteArray. var compState:ObjectState = stateBytes.readObject() as ObjectState; // We can inspect the type that the ObjectState // originated from. var restorableComp:IRestorable = flash.utils.getDefinitionByName(compState.className); restorableComp.restore(compState); // If this is a UIComponent, let's add it to the stage. // Since we saved the x and y positioning in the // ObjectState, it will position itself to where it was // when it was saved. if (restorableComp is UIComponent) addChild(restorableComp as UIComponent); } }
By using the Memento pattern, we’ve encapsulate the implementation of storing and retrieving an object’s state. We’ve also made it generic enough, that we can serialize the object’s state and store it into a database table. Once in the database table, the state can be retrieved and instantiated later.
Pitfalls of this Approach
Like any design pattern out there, this approach has its draw backs. One consequence of this technique is the difficulty to change the data inside your Mementos. The reason for this is the way that we use serialization. Since the objects are serialized in the database, you can’t easily add additional data to the ObjectStates. However, there are workarounds for this. You can save a version number along with your ObjectState. This version number can be used in conjunction with a separate class that deals with reading each ObjectState’s data. When the class inspects the version number, it can change its parsing logic to deal with different versions of the ObjectState.
Another drawback is the inability to do a database query on the data inside your ObjectStates. Again, since the objects are serialized, there’s no easy way to do this. You can, however, work around this though by storing the query data in either a separate table, or along side the ObjectState when it’s saved.
Hopefully this technique is something you can add to your toolkit. It definitely has its share of drawbacks, but if you’re looking for an easy way to save the state of your application, this is certainly a pretty trivial and elegant way of accomplishing it.
Loading Modules/Runtime CSS into an AIR App
For those planning to load a Flex module into your AIR application from a remote server: take a look at this post before beating your head against the wall with this ambiguous error message Error: Unable to load style(SWF is not a loadable module).
Basically, loaded SWF’s are not allowed to be in the same security domain as your AIR app. Since modules and external styles loaded using StyleManager.loadStyleDeclaration() try to load themselves into the current security domain, an error will be thrown. The only workaround it appears is to bundle those modules with your application when it’s downloaded. Any new modules you want to add to your application at a later time can be downloaded using AIR’s update API via Updater.update().
CollectionEventKind.RESET, WTF Does That Mean?
When handling Flex’s collection change events, most of the change types are pretty self-explanatory. For example, CollectionEventKind.ADD is when an item is added to the collection, or CollectionEventKind.UPDATE is when an item’s property inside the collection changes. However, there’s this ambiguous change type called RESET. The documentation does a wonderful job of describing when this type of collection event is fired: Indicates that the collection has changed so drastically that a reset is required. (ASDoc Link)
Digging through ListCollectionView provides some better insight of when RESET is dispatched. Anytime a collection is passed to ListCollectionView.list, and both the old list and the new list has items in it, it will fire a reset collection change event. Here’s the code Adobe uses for setting a list on ListCollectionView:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public function set list(value:IList):void { if (_list != value) { var oldHasItems:Boolean; var newHasItems:Boolean; if (_list) { _list.removeEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler); oldHasItems = _list.length > 0; } _list = value; if (_list) { // weak listeners to collections and dataproviders _list.addEventListener(CollectionEvent.COLLECTION_CHANGE, listChangeHandler, false, 0, true); newHasItems = _list.length > 0; } if (oldHasItems || newHasItems) reset(); dispatchEvent(new Event("listChanged")); } } |
Lastly, ListCollectionView is a pretty useful class. A lot of new Flex developers go straight to using ArrayCollection, and forget about its father, ListCollectionView. This collection allows you to apply different sorts and filters on a collection without directly modifying the wrapped collection. You can also call addItem() and removeItemAt() on ListCollectionView and have it modify the wrapped collection. Pretty nifty! Here’s an example of it in action:
1 2 3 4 5 6 7 8 9 10 11 | var col:ArrayCollection = new ArrayCollection(); col.addItem('a'); col.addItem('b'); col.addItem('c'); var wrapper:ListCollectionView = new ListCollectionView(col); wrapper.removeItemAt(0); wrapper.removeItemAt(0); wrapper.removeItemAt(0); trace(col.length); // traces: 0 |
When to Use Weak References
Understanding when to use a weak references, versus strong references can be a confusing one. It took me awhile to fully grasp when, and when not to use one over the other. On top of that, there’s very little documentation on the LiveDocs about the subject. Under the documentation for IEventDispatcher.addEventListener(), it states:
useWeakReference:Boolean (default = false) — Determines whether the reference to the listener is strong or weak. A strong reference (the default) prevents your listener from being garbage-collected. A weak reference does not.
And here’s what they have listed for the Dictionary’s constructor:
weakKeys:Boolean (default = false) — Instructs the Dictionary object to use “weak” references on object keys. If the only reference to an object is in the specified Dictionary object, the key is eligible for garbage collection and is removed from the table when the object is collected.
Ok … thanks. So, I did some Googling, and both Ted Patrick and David Coletta have much better information on the subject.
The basic idea behind strong references and addEventListener is this: when you call addEventListener and you pass it the function that you want to be called when the event fires, the event dispatcher is actually grabbing and holding a reference to that class and function it contains. As we all know, an object won’t be garbage collected until every reference to it doesn’t exist anymore. This insures that the event dispatcher always has a reference to the function that needs to be called. However, if you’re not careful, this can be a breeding ground for nasty memory leaks.
So, here’s my short list of do’s and don’ts related to strong vs weak references and event listeners:
- Always use a weak reference when adding an event listener to a class that’s a singleton, or any object that you expect to live throughout the life of your application. Remember, this applies to most of Flex’s manager classes, including the SystemManager, and any event dispatching classes that your singleton’s contain.
- Always use weak references when adding Cairngorm commands. The event dispatcher in Cairngorm is a singleton, and will always keep references to those command classes.
- According to Ted, weak references are 10x slower. (True when referring to member access, but not event listening.)
- It’s safe to use strong references when you’re adding an event listener to itself (i.e. the instance dispatching the event).
- You should use a weak reference when adding an event listener to the Timer class.
- Lastly, always make sure to clean up and remove any event listeners your classes are using when they’re no longer needed. I follow .NET’s approach, and I have an interface called IDisposable. This interface contains a single method called
dispose(), and inside I remove any event listeners that the class might be using. Additionally, you could clean-up any BitmapData objects you might be using, among other things. Most, if not all, of my classes that I write implement this interface, and I just make sure to calldispose()when I know the object is no longer needed.
If there’s anything else to look out for, I’d love to hear them. It’s always good to be proactive when it comes to memory leaks.
Embedding Cayri on Your Website
Lately I’ve been getting emails from people asking me if they can embed Cayri on their virtual airline’s website. So I think it’s about time to post a small tutorial on how to do this. The simplest way to do it is by using an IFRAME tag with HTML. Just stick the following code in any HTML page, and Cayri will show up on your website:
1 | <iframe src="http://www.cayri.org/?network=vatsim" frameborder="0" height="500" width="700"></iframe> |
If you would like to show IVAO traffic instead of VATSIM traffic, you’ll need to replace ?network=vatsim with ?network=ivao in the src attribute.
The State Pattern in Flex 2
I’m currently working on Flex project at Quality Attributes Software that requires the use of a set of tools, similar to Photoshop, to manipulate a drawing canvas. Some examples of tools might be a drag tool, a selection tool, and a zoom tool. I thought to myself, “Ok, simple enough. Throw all the logic into a switch statement inside a generic on click button handler.” So, when a user clicks on a new tool, disable all the functionality from the previous tool, and enable the functionality of the new one. Ugh! This was a complete disaster. What happens when you expose all this logic, is that you run into some very highly coupled code. Meaning that each tool is essentially keeping the state of the other tools. Yuck!
There’s definitely a better way to handle these situations, and that’s by using the state pattern. Essentially, I turned each tool into a state. So when a user clicks on the Selection Tool, the program changes its state to use the functionality of selecting objects on the drawing canvas. I hide all this logic behind an interface, and each tool is represented as a class that implements this interface. If you’d like some code examples of this pattern, William Sanders has a great write up over at Adobe’s Developer Center.
Aircraft Heading Information for IVAO
The heading information for aircraft on the IVAO network has finally been implemented! Thank you for the staff over at IVAO for modifying their server data to supply this information. The difference is truly night and day.