Tuesday, May 3, 2011

Custom Events in Actionscript

Actionscript 3 events are wonderful. The syntax is simple and easy to implement. But there may come a time when the default events just will not do. Say, for example, after a user clicks a button to log into an application you want the application to check if the connection to the server was established before the program closes the log-in screen and opens the main application. This can be solved by using a custom USER_CONNECTED event for instance.

First off let my give you a little info about AS 3events. This is a sample event handeler for a button called btnSend:

btnSend.addEventListener(MouseEvent.MOUSE_DOWN, onSendClick);

MouseEvent.MOUSE_DOWN is a common event. MouseEvent is the class that holds all of actionscript's mouse events. In reality MOUSE_DOWN is just a constant string value. When we trace the MOUSE_DOWN variable we get the string: "mouseDown".

Now I'm going to show how to make your own events to handle more specific actions. The following is code from a client-side server app I'm working on. Assume there is a User class. The idea is the same as the first example; we want the log in screen to go away only AFTER the user fires a USER_CONNECTED event. For good practice we are going to make a class to hold our custom events. The only purpose of the class will be to hold constant strings that we will use as custom event names. Lets call it UserEvent.as:

package
{
   public class UserEvent
   {
     public static const USER_CONNECTED:String = "userConnected";
   }
}

That's it for that class. Now lets use it. Here is code before we add the event handeler:

private function login():void 
{
   if(loginSuccess())
   {               
      initGui();
   } 
}

Now we have this:

private function login():void
{
   if(loginSuccess())
   {               
     user.addEventListener(UserEvent.USER_CONNECTED,initGui);
   }
}

I should mention loginSuccess() is a boolean function that returns true when the user has entered a valid name.
As you can see the user is assigned the custom event and initGui is the handling function. This says rather than logging in right away, wait for the user to fire the USER_CONNECTED event. I must also mention that initGui() is a function that takes 0 arguments. When you use it as an event handler, it will be sent an Event object and this will lead to run-time errors because it doesn't expect to receive anything. So, to clarify, the definition for initGui must be :

 public function initGui(e:Event):void

Now we will add the code that fires that event. In the user class there is a socket with a Event Listener listening for a Event.CONNECT event. We need to place the code in the handler function for that event, because it's the event that fires when the user successfully connects. Here is what that code looks like now:

private function socketConnect(e:Event):void 
{
    //Code here runs when the socket makes a connection
}

Now we add a line to the end:

private function socketConnect(e:Event):void 
{
    //Code here runs when the socket makes a connection
    dispatchEvent(new Event(UserEvent.USER_CONNECTED)); 
}

DispatchEvent does exactly what you would expect it to; it dispatches an event. To use dispatchEvent you must import AS3's EventDispatcher in the flash.events package. IE, put this with you're other imports(before the class definition):

import flash.events.EventDispatcher;

The dispatchEvent function takes an Event object as a parameter, so we create one inside the call. The Event constructor takes a string to create the event, so we send it our custom event string from our UserEvent class.

I hope this will be a help to someone looking for help with custom actions in actionscript 3. I'm sorry for leaving out most of the code for my application, but it was to keep this post to the point. If you want moar code let me know! Happy coding all.