Flash Friday - AS3 Signals Basics

A short while back I mentioned a couple new open source projects I started working with at my new job. One of those projects was AS3 Signals. Since I've begun using it I've really grown to like it and I wanted to explain why. Hopefully my explanation of why will also include enough of the how. First off, have been a big fan of the AS3 event model since it came out with flash player 9. It, like many other AS3 updates, was much cleaner than the ways we were doing things in AS1/2. However, there have always been a few things that have bugged me just a little about the native event model.

I have to look at documentation to see what events a class object fires.

I can't count the number of times I am looking into a new framework, or even native classes, and I hope it fires an event but I can't just tell by code completion alone. Worse yet, sometimes important events don't even get documented so I have to search through source code to see what gets dispatched. On the flip side, if I'm writing custom classes I don't like writing documentation. I like my code to be readable like a good book, if at all possible. The AS3 event model forces you to read and write documentation. How could AS3 Signals clear up this problem though?

AS3 Signals clears up the problem of needing the documentation by having you create individual signals as objects in a class. This allows the programmer the opportunity to name the signal appropriately, thus making it easy to understand for the user of this class. Thus eliminating the requirement for documentation.

Let's give a simple example.  Let's say you have a class that loads an external file and isn't ready until that file is loaded and parsed. With AS3 Signals this is a relatively simple process.

First create the signal in the class:

public var becameReady:Signal;
public function MyFileLoader( url:String ):void{
	becameReady = new Signal();
	// you can come up with your own code here.
}

Now anyone wanting to use the MyFileLoader class can see that you have a signal called becameReady. Hopefully they can tell from just that info what it does. Or perhaps you can come up with better naming. Either way this is an improvement.

Event types are strings

Strings are flexible and easy to read ( such as in a trace or error message ). The other problem is that they are not type safe and I've had times where event type naming collisions do happen. AS3 signals takes care of this problem by both solving and circumventing the problem.

AS3 Signals circumvents the problem by having you create separate ISignal objects for each type of event you would have dispatched in the past. Even though they are all of type ISignal, they are each distinct fields on an object. For example, if I had a class controlling a form, some of its signals might look like this:

public var submitClick:NativeSignal;
public var clearClick:NativeSignal;
public var completed:Signal;

AS3 also solves the problem by having event type checking, if you are working with the native event model. I haven't worked much with this at this point so I won't get into this in this article. If you'd like to know more about this comment below and I can write about it in a future article.

Custom events and event dispatcher classes take too much code for the simplest task

We've all been there, we want to make a custom events for a project but we have to write a whole new class to encapsulate what we need. Also, if we want to dispatch these events from a class that doesn't extend EventDispatcher we need to make sure to implement IEventDispatcher. Sure, these are relatively simple tasks but they take time and you are writing code that reeks of duplication.

As you have seen above, it is really simple to create a "custom" signal. Just define and initialize a new signal. Dispatching it is just as easy.

public var somethingHappened:Signal;

private function init():void {
	somethingHappened = new Signal();
}

private function doSomething():void {
	// custom code that does something ;)
	somethingHappened.dispatch();
}

Too make the signal more custom you can send as many objects as you want in the dispatch call. I'll leave that as an exercise for the reader ( or you can exercise the comments section and I'll show you what I mean below ).

If you just want to listen once you have to write extra code

The native event model doesn't make it easy to listen once. Perhaps you want to listen to a view's close button for just one click. With the native event model you have to remember to call removeEventListener in you event handler or else your program may not work as expected and it will likely create a nasty memory leak. AS3 Signals simplifies the process with the addOnce() call.

private function init():void {
	doSomething();
	view.closeButtonClick.addOnce( onCloseButtonClick );
}

private function onCloseButtonClick(){
	view.close();
}

The previous addOnce call was so minor you might not have noticed it in the code. Really, that's all it takes. Signals are really quite easy to clean up.

Cleaning up listeners is difficult

When trying to find memory leaks, the first thing I look for is calls to addEventListener. They are usually the major culprit because it is so easy to lose track of which listeners were added to an object and for which event type. As you saw above, Signal objects have a built in mechanism for removing listeners after a single call if you want. They also have a simple way to remove all listeners from themselves, the aptly named removeAll function.

function close():void {
	closeButtonClick.removeAll();
	otherSignal.removeAll();
}

Conclusion

This article was much longer than I thought it would be. If you made it this far, thank you for reading. I hope you see how AS3 Signals is an improvement over the native event model. Once you start using Signals you'll likely find yourself using events less and less. The event model is still core to AS3 though so there are some good ways to use them together. I plan to write a ( hopefully shorter ) article on using AS3 Signals with the native event model in the future. If you have any questions, comments or requests regarding AS3 Signals please let me know in the comments below.