Archive for December, 2007

State Machine Transitions

In my initial posting on state machines I necessarily skipped over a lot of detail that I’d like to start filling in. Let’s start by going back to this comment:

  // switch to stateNorthSouthGreen

In this state machine implementation, the current state is represented by a function, and that function is stored in the m_state member variable. Switching states is therefore almost as simple as just updating this variable. Let’s wrap it in a function with a helpful name:

function transition( newState:Function ):void {
// it's not quite this simple...
m_state = newState;

Recall that the dispatch() function simply forwards all events to the current state function. The new state function will receive all subsequently dispatched events. Continuing with our traffic light example, that means that CarEvents, for example, will continue to be dispatched, but now to our new state function.

It’s often useful to be able to do some additional work when entering or exiting a state. For example, a traffic light might might want to start a timer when entering a state which turns on the walk signal. This behavior can be added directly to the state functions by dispatching a couple of new events. Let’s define them first:

class StateMachineEvent extends Event {
public static const ENTER:String = "enter";
public static const EXIT:String = "exit";

Then we refine our implementation of transition():

function transition( newState:Function ):void {
m_state( new StateEvent( StateMachineEvent.EXIT ));
m_state = newState;
m_state( new StateEvent( StateMachineEvent.ENTER ));

(In other state machine models, individual states are sometimes modeled as classes. If you think of states that way, the enter and exit events are like the constructor and destructor, respectively.)

Finally, we add some code to our state function to handle these new events. I like to use the following skeleton for state functions:

function stateFunction( event:Event ):void {
switch( event.type ) {
case StateMachineEvent.ENTER:
// start Timers, etc.
case ...:
// handle various other events
case StateMachineEvent.EXIT:
// stop Timers, clean up , etc.
// Unexpected event! Maybe throw?

Beta 3 and the Browser API

Adobe AIR 1.0 Beta 3 is now available. Among other new and interesting features is the ability to detect and launch AIR-based applications from within the browser–as promised.

Note that this is not an API for controlling the browser, despite its name. Rather, think of it as an AIR API that’s projected into the browser. Just goes to show you how much naming depends on your perspective.

Details are in the documentation, but here’s a couple of things to keep in mind:

  • Applications are invisible to this API by default. If you want to make your application visible from the browser–and therefore to any website–you have to opt in via a declaration in your application descriptor.
  • If you opt in, you are responsible for making sure your application can’t be exploited by web sites using this feature. Don’t use it lightly. The BrowserInvokeEvent you receive when invoked via this feature has properties to identify who invoked you so you can restrict responses to trusted sites.

Installing applications from the browser has been rolled into this same API and the new Beta 3 sample badge has been updated accordingly. Note that the older badges will not work with Beta 3.