Signals

Title: Signals Date: 2011-06-13 15:53 Author: eamonnfaherty Category: development Tags: actionscript3, signals Slug: signals

Anyone that knows me offline has probably heard me singing the praises of signals.

I really like the stricter typing of signals compared to events.  For me, strict typing means that my code is checked by the compiler (instantly, at compile time) as apposed to being checked by the AVM (eventually, at runtime).  I have had countless times where I have seen code fail due to the event types declared in the handler method being wrong, even when the string values are stored as variables instead of using literals. The checking that event handlers are added correctly is not checkable by the compiler.  This means we need to either blindly hope it all works out or rely on testing.

Signals (out of the box) fixes this issue but there is still another issue for me, the contract between an event (also a signal) and its handler.  With events there are two contracts, the event type (the Event.type String) and the event data.  Signals (out of the box) handles the event type issue by moving the name of the type into an interface as a signal, which is a great idea!  The data problem is harder to solve.

There are two checks that should be performed on the data.

The first is validation. At the moment this is limited to type checking.  When you set up a signal, you specify that the signal should be an int, String etc.  I think this is a great start but I think there should be more (optional) validation checks available; range checks for ints and regex checks for Strings.  When these validations fail then the signal should have a built in mechanism to throw an InvalidSignalError.  This would tighten up the robustness of projects using signals and would definitely reduce the amount of code I write.

The second check is verification. This is a lot harder to check but is a much more valuable check to perform. I think this is up to developers to check when developing. I am currently using signals to send messages between objects. I like to keep the implementation of my objects hidden from others so when writing a class I am always mindful of what values are available to other objects. So, when writing a signal I often find myself doing the following:

[code lang=”as3” ]
public class ShowScreenSignal extends Signal
{
private static const MENU:int = 0;
private static const PLAY:int = 1;

public function ShowScreenSignal()
{
super(int);
}

public function dispatchMenu():void
{
dispatch(MENU);
}

public function dispatchPlay():void
{
dispatch(PLAY);
}

public function isMenu(message:int):Boolean
{
return message = MENU;
}

public function isPlay(message:int):Boolean
{
return message = PLAY;
}


}
[/code]

This means in my controller/mediator I call signal.dispatchPlay() and in my listener/command I check signal.isPlay(message) to check the message. This means nothing knows about the message values other than the signal. I can change the message to be a String without changing any of my controllers/mediators/command. This is better encapsulation. This works really well when using RobotLegs + Signals as you can subtype your command classes and have a condition in your execute method if (message.isPlay(message)).

This is solving one problem. I want to have one signal with many handlers based on the message. eg:

[code lang=”as3” ]
public class ShowPlayCommand extends SignalCommand
{
[Inject]
public var message:int;

[Inject]
public var signal:ShowScreenSignal;

override public function execute():void {

if (!signal.isPlay(message)) {
return;
}

//do something
}
}
[/code]

Published: June 13 2011

  • category:
  • tags:
blog comments powered by Disqus