Posts Tagged swiz
Swiz EventHandler Filtering With Pub/Sub Topics - Part 2
After giving my first pass at this a little thought (which gives all of the details and explains how I got here) I realized the topic value defined in the EventHandler metadata tag was essentially hardcoded and set at compile time — this can work for some situations, but obviously isn’t ideal. I then decided I needed a way to filter events in Swiz by topics with data and values set at runtime. The event dispatching is still the same:
/**
* Allows this class to dispatch global events. Only methods using an
* EventHandler metatadata tag with the property of scope="global" can
* handle this event. This means other modules and even the shell application
* can handle this event if we want.
*
* <p>
* The event dispatcher is injected by Swiz due to the [Dispatcher] metadata
* and the class member's type of IEventDispatcher.
* </p>
*/
[Dispatcher(scope="global")]
public var globalDispatcher:IEventDispatcher;
...
public function sayHello():void
{
logger.debug("sayHello");
var appEvt:AppEvent;
appEvt = new AppEvent(AppEvent.SAY_HELLO);
appEvt.hello = "Hello World!";
appEvt.topic = "wasiTopic";
this.globalDispatcher.dispatchEvent(appEvt);
}
But the event handling is setup with a new, additional attribute called topicProperty.
public var myTopic:String = "wasiTopic";
...
[EventHandler(event="AppEvent.SAY_HELLO", properties="hello", scope="global", topicProperty="myTopic")]
public function helloWithTopic(hello:String):void
{
logger.debug("hello = " + hello); // WORKS
}
This now allows the developer to set the member variable for the object doing the event handling at runtime. Internally in Swiz’s org.swizframework.utils.event.EventHandler’s method public function handleEvent( event:Event ):void we now look for the attribute “topic” and “topicProperty” in the EventHandler metadata. If the user has set the topicProperty, the method looks at the Bean that’s using EventHandler and inspects it for this String property and then compares it to the topic passed in the event. This requires some more changes to the Swiz class org.swizframework.utils.event.EventHandler.
Grab the changes I made to Swiz here.
Swiz EventHandler Filtering With Pub/Sub Topics - Part 1
We tend to build many Flex applications with modules, so having the ability to broadcast and listen for messages based on the scope attribute for both Dispatchers and EventHandlers is essential in Swiz.
UPDATE: Part 2 has Swiz framework code changes and a more robust solution.
If you don’t know about Swiz Event Scoping, then read on; otherwise, skip to the section labeled Filtering With Topics below.
Background
You can read the actual documentation from Swiz in the last link, but the gist is that you can tell Swiz to either broadcast events on a “global” level (using the highest level Application object) or on a “local” level (using the Module itself) and then listen to those events in the same fashion. This allows you to tell modules to listen to events only from themselves and not other modules (that might have the same events) or to listen to all events from your main, shell application and/or all other modules. Let’s look at a quick example by assuming the dispatching code is in LoginViewMediator and the handling code is in LoginController in a Module.
Local Event Dispatching
Local Event Dispatching From LoginViewMediator
/**
* Allows this class to dispatch local events. Only methods using an
* EventHandler metatadata tag with the property of scope="local" can
* handle this event.
*
* <p>
* The event dispatcher is injected by Swiz due to the [Dispatcher] metadata
* and the class member's type of IEventDispatcher.
* </p>
*/
[Dispatcher(scope="local")]
public var localDispatcher:IEventDispatcher;
...
public function login(userName:String, password:String):void
{
logger.debug("login");
var appEvt:AppEvent;
appEvt = new AppEvent(AppEvent.SERVICE_LOGIN);
appEvt.username = userName;
appEvt.password = password;
this.localDispatcher.dispatchEvent(appEvt);
}
Local Event Handling in LoginController
[EventHandler(event="AppEvent.SERVICE_LOGIN", properties="username, password", scope="local")]
public function login(username:String, password:String):void
{
logger.debug("login: username = " + username + ", password = " + password);
}
If we had other Modules with this same EventHandler statement in their LoginController they would not fire because we specified the scope as local. If we change the scope property to global and the AppEvent is in a common library that all Modules can use, then they would each hear this event and all fire, which in many cases is not what you want. Just so we have a full understanding of what’s going on, let’s show an example of broadcasting global events in a similar fashion:
Global Event Dispatching
Global Event Dispatching From ModuleA
/**
* Allows this class to dispatch global events. Only methods using an
* EventHandler metatadata tag with the property of scope="global" can
* handle this event. This means other modules and even the shell application
* can handle this event if we want.
*
* <p>
* The event dispatcher is injected by Swiz due to the [Dispatcher] metadata
* and the class member's type of IEventDispatcher.
* </p>
*/
[Dispatcher(scope="global")]
public var globalDispatcher:IEventDispatcher;
...
public function sayHello():void
{
logger.debug("sayHello");
var appEvt:AppEvent;
appEvt = new AppEvent(AppEvent.SAY_HELLO);
appEvt.hello = "Hello World!";
this.globalDispatcher.dispatchEvent(appEvt);
}
Global Event Handling in Module B
[EventHandler(event="AppEvent.SAY_HELLO", properties="hello", scope="global")]
public function hello(hello:String):void
{
logger.debug("hello = " + hello);
}
Again, this is awesome…but what if you want to broadcast a message that you only want some of the modules to hear? You could obviously put in some simple logic in the event handler that determines if your Module was supposed to listen to the event based on a parameter passed in the EventHandler MetaData, but this could potentially become a large and unwieldy task that you’ll need to apply to all new modules…so what if we introduce filtering of Swiz events via a topic attribute in the EventHandler metadata and a corresponding topic property in our dispatched event?
To do this, we’ll need to do some quick monkey patching to Swiz (by creating the same package structure and adding the same classes we want to change that exist in the Swiz SWC). First, let’s add the topic property to the org.swizframework.metadata.EventHandlerMetadataTag. Add the topic property:
protected var _topic:String;
public function get topic():String
{
return _topic;
}
Then add the following to the method override public function copyFrom( metadataTag:IMetadataTag ):void
if( hasArg( "topic" ) )
_topic = getArg( "topic" ).value;
Next we’ll edit the method public function handleEvent( event:Event ):void in org.swizframework.utils.event.EventHandler. Add the following right after the first if() statement:
// look for a topic -- if the one exists in the EventHandler MeataData and
// the event does not have one or the value does not equal the EventHandler's
// then we'll filter out this event and not allow it
if(metadataTag.topic != null)
{
if(event["topic"] == null)
{
return;
}
else if(event["topic"] != metadataTag.topic)
{
return;
}
}
That’s it. Let’s give it a whirl by using a global dispatcher again, but adding a topic property to the event and a topic attribute to the EventHandler metadata.
Global Event Dispatching From ModuleA
/**
* Allows this class to dispatch global events. Only methods using an
* EventHandler metatadata tag with the property of scope="global" can
* handle this event. This means other modules and even the shell application
* can handle this event if we want.
*
* <p>
* The event dispatcher is injected by Swiz due to the [Dispatcher] metadata
* and the class member's type of IEventDispatcher.
* </p>
*/
[Dispatcher(scope="global")]
public var globalDispatcher:IEventDispatcher;
...
public function sayHello():void
{
logger.debug("sayHello");
var appEvt:AppEvent;
appEvt = new AppEvent(AppEvent.SAY_HELLO);
appEvt.hello = "Hello World!";
appEvt.topic = "wasiTopic";
this.globalDispatcher.dispatchEvent(appEvt);
}
Global Event Handling in Module B
[EventHandler(event="AppEvent.SAY_HELLO", properties="hello", scope="global", topic="wasiTopic")]
public function helloWithTopic(hello:String):void
{
logger.debug("hello = " + hello); // WORKS
}
[EventHandler(event="AppEvent.SAY_HELLO", properties="hello", scope="global")]
public function helloWithOutTopic(hello:String):void
{
logger.debug("hello = " + hello); // NOPE
}
[EventHandler(event="AppEvent.SAY_HELLO", properties="hello", scope="global", topic="fooTopic")]
public function helloWithOutTopic(hello:String):void
{
logger.debug("hello = " + hello); // NOPE
}
UPDATE: Part 2 has Swiz framework code changes and a more robust solution.
eventhandler, filtering, flex, metatadata, pub-sub-topics, swiz
Swiz + SourceMate + Metadata Preferences FTW!
Posted by brianr in flash builder, swiz on April 22nd, 2010
I’ve obviously been using Swiz quite a bit lately and recently I added SourceMate to my arsenal of Flex tools — if you don’t know what SourceMate is, just think of what a good Java IDE can do and envision Flash Builder being able to do the same — it’s basically like feeding Flash Builder steroids or Big Papi in 2007 with PEDs. Anyways, here’s a quick list of goodies that it adds to the IDE.
Well my favorite set of enhancements is without a doubt the MetataData Features:
No more trying to remember the exact syntax for custom metadata for frameworks like Swiz…and even better is the fact that the Swiz doods at UM created a metadata config/preferences XML file for you to import to just start your Swiz project with SourceMate. Grab the file here from the Swiz Github repo and simply add it to your projects’s SourceMate preferences: Project Properties -> SourceMate -> Metadata -> Import… browse for the file and boom, you’r
e good to go!

SourceMate Metadata -> Import Swiz Configs
Nice work Swiz doods.
big-papi, dev-tools, development, dispatcher, flex, ide, inject, mediate, metadata, postconstruct, postdestroy, sourcemate, swiz
-
-
Archives
- April 2011 (2)
- March 2011 (1)
- February 2011 (1)
- January 2011 (1)
- December 2010 (5)
- October 2010 (4)
- September 2010 (1)
- August 2010 (2)
- April 2010 (6)
- March 2010 (2)
- January 2010 (2)
- December 2009 (1)
- November 2009 (7)
- October 2009 (3)
- September 2009 (1)
- August 2009 (3)
- July 2009 (6)
- June 2009 (5)
- May 2009 (9)
- April 2009 (8)
- March 2009 (2)
- January 2007 (1)
- August 2006 (1)
-
Meta