This blog has moved to a new location!

Monday, October 11, 2010

Understanding the AS3 Event System #1 - The Basics

This post can be found on the new blog at Understanding the AS3 Event System #1 - the Basics
I originally wrote this thread as a response to a Kirupa forum thread:

This is my first draft, so any opinions or thoughts are deeply appreciated, especially if there is anything you still don't fully understand or would like me to clarify further.

Imagine your code as one big office room. That office has about 100 or so cubicles, with each cubicle representing a different object. For instance, if you have 5 Buttons on the stage, it's not one "Button" cubicle, but instead 5 different cubicles, one for each button instance.

The Event String/Event Type
Now, I'm sitting in the "homeButton" cubicle. One day, I get an email from my boss who tells me I have been "clicked". So immediately I stand up, and yell out into the hallway so loudly that everyone can hear "I HAVE BEEN CLICKED!"

Now, the boss may have A LOT more information, such as where I was clicked, how many times, if any of my children were clicked, and a lot more information. However, I won't stand up and yell out to everyone in the building all that information. That is quite wasteful, and if I got several of those emails a day, I would soon get tired of spouting out all that information.

Instead, to save energy, I only tell everyone "I have been clicked". That is me telling everybody the event type, also known as the event string.

Listening for Events
Back up a few hours (before the event string). I have a friend named Nico sitting in the art department (his cubicle is labeled "currentImage" though that's not really that relevant). His boss told him "Whenever Andreas in the homeButton cubicle is clicked I want you to draw an image of a house and send it right to me."

Now, Nico could get up out of his seat every five minutes, walk over to me, and ask "Hey, Andreas. Were you clicked yet?" I say no, so he walks back to his cubicle and sits down. This would happen again and again, and neither of us would get any work done. This is VERY inefficient. Nico could reduce this and only check with me once per hour, but he wants to know immediately when I am clicked. So that is NOT an option either.

Instead, Nico sits in his cubicle continuing his regular work, and in the meantime, listens out in the hallway for my voice. Now, at around noon I yell out "I was keypressed!" He hears my voice, but he really doesn't care about the keypresses. So, he ignores what I say, and continues working. Then another guy in the cubicle (Larry, a really annoying guy) yells out "I was clicked!" Since Larry is not as good looking as Andreas, and The Boss didn't tell Nico to listen to Larry, Nico ignores him completely.

Because, Nico is only listening to Andreas (in the homeButton cubicle) for the "clicked" event. When he hears the event, he needs to start drawing the house (which looks something like this in AS3):

homeButton.addEventListener("clicked", drawHouse);
The Event is dispatched
Now, fast forward back to where we were. Me (Andreas) gets the call from my boss telling me I was clicked. So I stand up and yell out to everyone. "I was clicked!"

Two people were listening for my "clicked", Nico and Bob (the guy from 'contentManagement', a very talkative fellow) Nico rushes up to me excited "Hey Andreas. I heard about the click. That is awesome! Congratulations! But tell me more about the event! Why were you clicked? Where were you clicked? Who clicked you? Why did they click you?"

I could spend the next 5 minutes explaining all the juicy details to Nico, but then I would have to repeat all this information to Bob (which is very inefficient, and Bob is a busy man and doesn't want to wait). So instead, I print out all the information on the "clicked event" and put it into a Folder which I give to Nico. I give the folder to both Nico and Bob so they can use the information in it and look at it as they please. This folder is the Event object (more details on that later)

Immediatly Nico rushes to his art studio in his cubicle and gets to work at "drawHouse()", however, now he has the Folder (the Event) he can use that information while drawing the house, and therefore passes it into the function as a parameter:
function drawHouse(event:Event)
{ /*Draw stuff in here...*/ }
The Event
To make sure that everyone gets the information they need, there are VERY strict protocols to what the Event Folder needs to contain.

The following pages with information are required for standard Event Folders
>the target - the person dispatching the event, which in this case is me, Andreas (or actually the homeButton cubicle).
>event type - the type of event (aka event string), in this case "clicked".
(there are a few more pages in the file, but that's mostly the small legal mumbo-jumbo fine print that no one reads anyway. You will be fine ignoring them for now.)

This is a standard Event file. But hold on, there was A LOT more information which is missing here! If I hand Nico a file with only those two pages of information in it, he will still wonder "Where were you clicked?" among MANY other important questions. Luckily, the company already has a neat system figured out!

The MouseEvent
Now, the company I work for has a second type of file, a "MouseEvent File". This file extends the standard Event File. That means that the MouseEvent file has all the information contained in the plus a lot more information, perfect for when a "clicked" event happened.

It has the standard two fields (target and type) PLUS these additional pages with information:
And a whole lot more!

Note that this MouseEvent file ONLY is allowed to be used when dealing with events that had to do with the mouse, such as "clicked", "hovered" etc. The file should NOT be used for events that had to do with the keyboard, "keypressed" or "keyreleased". Those events should instead use a specialized KeyboardEvent File with it's own special properties.

So I print out all the relevant information and hand both Nico and Bob a "MouseEvent" folder. Using that information, they draw the houses, or display text, or whatever they want to do with the information.

(Extra note: Maybe Bob didn't even need to see the file. Maybe he just needed to know that I was clicked, so when I hand him the file, he may not even open it or look at the details of the click using the information inside. That's fine by me, but I still need to create the file in case there is someone out there who actually needs the information.)

Creating the MouseEvent
Bob and Nico don't want to wait for me to print out and collect all the papers needed in the MouseEvent file. They want the information to be ready the second they step up to my cubicle. So, BEFORE I stand up and tell everyone I was clicked, I create the folder ahead of time for quick and easy access. THEN, I dispatch it to all who are listening.

This is how it looks in ActionScript:
//create the folder with all the information in it
var eventFolder:MouseEvent = new MouseEvent("clicked", bla, bla, localX, localY, bla, bla, bla, bla, more bla);

//Now stand up and tell everyone I was clicked
//The "eventFolder" already says the event type is "clicked",
// so I don't need to repeat myself when dispatching it.
//All I need to do is dispatch the folder and Flash will do all the dirty work
Now Nico and Bob (and whoever else is listening) can react to it and get to see the folder I sent when dispatching:
function drawHouse( andreasEventFolder:MouseEvent )
{ /*Draw stuff in here...*/ }
That is Events 101.

1 comment:

  1. Nice guide, I loved the office metaphor. Great way to explain event listeners. The style is fun and it doesn't feel like you're just dumbing things down.

    The code part in the "Creating the MouseEvent" section seems out of place to me, though. I don't think it's necessary to use AS3 pseudocode in order to explain how the MouseEvent is created internally. This is outside the scope of this first guide, considering that the next one actually deals with custom events.

    Moreover, it might be confusing. At least if I was a newbie, I would think it's somehow necessary to write that code and construct and dispatch the MouseEvent myself.