DaVinci, Development, Flash

Building an AS3 component framework: Suspend and Resume

The purpose of the suspend() function is to freeze and store the current state of the component. It’s partner function resume() starts any frozen processes back up and returns the component to the state it was in. Both functions help to manage state and memory and are related to the destroy() function I proposed in my last post.

The Problem
Removing a DisplayObject from the display list does not cause it to stop running. This presents a unique problem for Flash developers who are used to using the timeline to control the state of their application.

Let’s say you have a Flash microsite that contains three or four pages. In a typical AS1 or AS2 project each page would live inside its own MovieClip. An instance of each page would then be placed (with a corrosponding label) on the main timeline. The gotoAndPlay() command is then used to navigate between pages.

Timeline states in AS2

A typical state timeline in AS2

This pattern works fine in AS1 and AS2 because the AVM1 compiler destroys any MovieClip that is no longer on the stage. Consider then how this pattern would work in AVM2:

The first thing the user will see is the ‘home’ page movie. If lets say they navigate to the companies page; the timeline will shift to show the ‘companies’ page movie and the ‘home’ page is removed from the display list. But, as we’ve already established, removing a DisplayObject from the display list does not cause it to stop running.

Moving from page to page will instantiate and remove (but not destroy) all the other page movies. If the state of each page is not properly managed then a number of problems present themselves:

  • If all the pages in your site are running concurrently then you’re likely to have a problem with performance.
  • If one or more of your pages contain elements that are heavy on the processor (e.g. large videos, layered effects or real time 3D) then these will continue to be processed even though the page is not visible.
  • If any of your pages play audio or video that contains an audio track, then you will continue to hear it play even though you can no longer see the page.

The Solution
The simple answer is to avoid using the timeline to manage state in AS3. In the new world order you would have a PageManager class that creates and destroys pages as required. The thing is, Flash developers (as opposed to back-end or even Flex developers) are very ‘visual people’. They like to see the objects they are managing and the timeline is a familiar way of doing that.

If every component already has suspend() and resume() functionality built in then we can automate some of the state management process by listening for stage addition and removal events. When an REMOVED_FROM_STAGE event is detected we call suspend() and when an ADDED_TO_STAGE event is detected we call resume(). Early versions of the player did not support these events so if you need to target an early version of the player then you may wish to use Senocular’s code for detecting stage events.

Update: Both functions are public. This allows a component to be suspended and resumed as required. For this reason I have added a read-only property isSuspended to indicate whether the component is suspended or not.

The Benefits
Being able to suspend and resume your components will improve the overall performance of your application. Correctly implemented it should avoid the problem of components continuing to run after being removed from the display list.

The Code

DaVinci, Development, Flash

Building an AS3 component framework: Garbage Management

Garbage Collection is a housekeeping function performed by the Flash Player. It cleans up and removes any objects or data from memory that are no longer being used by the Flash movie. ‘Garbage Management’ is my way of helping the Flash Player garbage collector do its job.

The Problem
As you may already know AS3 code is processed by its own just-in-time compiler AVM2 (Actionscript Virtual Machine 2). Destroying anything in AVM2 is notoriously difficult. Unlike in previous versions of the language (processed by AVM1) deleting an object does not necessarily remove it from memory. The AVM2 garbage collector will not remove any object that is still being referenced by anything else. This means you need to remove any outside references and de-register all event listeners to a class when it is no longer required.

For a good overview of the problems and some recommended management strategies take a look at Grant Skinner’s articles on garbage collection and resource management in Flash Player 9. If after this you want to get more technical then check out Garbage Collection and Memory Leaks by Adobe engineer Alex Hurai for a full low level explanation of how the garbage collector works.

The Solution
Garbage management is a ‘best practice’ rather than a specific implementation. You just have to get into the way of clearing up after yourself. Early versions of Flash Player 9 did not allow garbage collection to be directly invoked from code but since the release of update 3 you can force it by calling flash.system.System.gc(). I haven’t tested this myself yet but according to the boffins at CraftyMind you’ll need to call this twice due to the ‘mark and sweep’ nature of the Garbage Collector.

One good practice to get into is to always provide a destroy() function alongside your constructor. In this function you should remove all listeners and null any references to outside objects in your class. Note that due to ECMA262 compliance you can only delete dynamic properties. Cleaning up a class or Display object before removal becomes much easier when all you have to do is call a single standard (polymorphic) function before removing it from the stage.

Another good habit to get into is to use weak references on your Dictionary objects and listeners. It takes a little bit more code to write but it’s a good safety net should you forget to call destroy() before removing the class. Again Grant Skinner explains it best in his post AS3: Weakly Referenced Listeners.

The Benefits
A proactive approach to garbage management will help prevent memory leaks and improve the overall performance and saleability of your application.

The Code

DaVinci, Development, Flash

Building an AS3 component framework: Events and Inheritance

Building a component architecture in AS3 is much easier than it was in AS2. The structure and features of the language help us to write better code. At the conceptual level we have polymorphism in the shape of a consistent API and loose coupling thanks to the native event architecture.

Events in AS3
To be fair there was a mix-in event architecture for AS2 but it required the use of a rather inelegant Delegate (that’s hard to say) class or a 3rd party alternative such as Grant Skinners GDispatcher class. Thankfully those days are behind us.

Understanding how events work is now crucial to building anything in AS3. Events are not only an integral part of the language, they are far more versatile than they were in AS2. I was going to write an overview of all the new event functionality but to be perfectly honest you can’t beat the official Adobe article on the subject: ‘Introduction to event handling in ActionScript 3.0‘. The key points you’ll want to understand are the three event phases and how event propagation works.

The dynamic duo
It makes sense to me to separate the component graphics from their functionality as I want to be able to design and skin them using the drawing and animation tools inside Flash. Functional code will live inside an AS3 class and the component graphics will live inside a Flash FLA file. Each component therefore will consist of a MovieClip containing its graphics which is bound (using the Linkage properties in the library) to an AS3 class containing its functionality. This workflow is really no different from AS2 although the linkage properties in AS3 can be a little more prescriptive.

Inheritance: choosing a base class
I’ve mentioned this in earlier posts but my other fundamental design decision is to create a base component class for all my components. This will keep all the common “system wiring” in one place. I’m going to call this class AbstractComponent.as.

If this class extends an existing class then it will inherit all of the properties and methods of its parent. An interesting consequence of the integrated event architecture is that inheritance is now preferred over composition when creating components. Again I wont dwell on the details but if you’re interested then you should read Colin Moock’s post about Composition vs inheritance for Sprite and MovieClip.

I want to take full advantage of the animation features of the Flash IDE so I’m going to be extending MovieClip rather than the Sprite class. The full inheritance chain looks like this: AbstractComponent > MovieClip > Sprite > DisplayObjectContainer > InteractiveObject > DisplayObject > EventDispatcher > Object and the class looks like this:

DaVinci, Development, Flash

Building an AS3 component framework: Planning

This isn’t going to be a dictatorial lecture about how you must build your components. Think of it more as a fly-on-the-wall documentary. I need to build some unusual components and I thought it might make interesting reading to document the process and the design decisions along the way. I hope you find it useful.

A UI Component framework is a collection of interface elements that all share some common features. Although there is no single right or wrong way to implement a feature, some techniques are more efficient than others and each route will have its own constraints and challenges.

Size matters: functionality vs filesize
The biggest differentiator between frameworks is usually weight; and by weight I mean filesize. Heavier frameworks like the Flex component set have a lot of powerful shared functionality, but the tradeoff for this is a larger base filesize. Lighter frameworks such as MinimalComps have much less functionality but are consequently simpler and lighter. The chart below shows the relative feature sets of both frameworks.

Feature set comparison: CS3 vs MinimalComps

As a rough guide I’m aiming to build something lighter than the CS3 Components but heavier than the MinimalComps and I expect to use a combination of AS3 for the functionality and Flash for the design assets. I certainly don’t intend to build yet another set of standard components. I’m only going to build what I need when I need it. This is the main attraction of rolling your own – you can add all the functionality you need and no more than you need. If you want to extend any of these then be my guest, but the focus of this series will be on the concepts, the process and the decisions.

The first thing I want to do is decide on my common feature list. This functionality can then be baked into the base class that every component extends. My wish list looks something like this:

  • Garbage Management
  • Component Invalidation
  • Deferred Rendering
  • Child Management

All of these features are examples of what I call ‘system wiring’. They are common management features that form the functionality backbone of all the components in the set. There are plenty of historical precedents for building these features so it’s worth doing a little research before diving in. This could be as simple as referring to a Patterns book to digging into the source code of someone who’s been there before. We’re looking for elegant solutions.

I’d recommend taking a look under the hood of both the CS3 components and the Bit101 MinimalComps to see how they work. If this is your first time then I’d start with Keith Peters MinimalComps. They are really stripped down and good way to get acquainted with the main concepts. You can get started by reading Inside the Bit-101 MinimalComps. The CS3 components are more complex but very well commented.