SWFAddress in a Command Pattern: Part 1
Posted by Elliot.
The implementation of Asual SWFAddress 2.2 in a Command List Pattern design pattern was done in a Shared Command manner. This is of interest to those who use the Cairngorm framework.
I separated the events that would drive the changing of the content:
- SWFAddress events responds from the URL call from a server and to internal calls to SWFAddress class via setValue() to change the content, which execute the content change.
- The button events of the menu items, these set the value of the new page uses the setValue() method which drive the event handlers in the first event above.
What happens is the button events call the setValue() method of the SWFAddress class, these are instantiated in one invoker. Another invoker is used for the SWFAddress Events and the page address query and its content command. This invoked SWFAddress Command Lists works independently as well as initiated from the button events.
It may seem strange to have a sequence of events instead of one but this is the point of extended the Command List Pattern in a shared command manner – independence and extension. It also is a clean solution and also supports other events to drive the structure change via the SWFAddress, in the same manner that the button events call the setValue(). It also allowed for a simple retro fit of the SWFAddress system.
Two Invoker panel classes were created to handle these, both with a typical structure as in documented in Actionscript 3.0 Design Patterns except I have removed the creation of the button elements and just pass a reference to its display instance:
This code below is the InvokerButton class
package com.elliotrock{
import flash.display.*;
import flash.events.*;
import com.asual.swfaddress.SWFAddress;
import com.asual.swfaddress.SWFAddressEvent;
//
public class InvokerButton extends Sprite {
private var addressList:Array;
private var buttonList:Array;
private var pageTitleList:Array;
//
//This handles the button events and the call to SWFAddress via setValue
//
public function InvokerButton(list_len:int) {
this.addressList = new Array(list_len);
this.buttonList = new Array(list_len);
this.pageTitleList = new Array(list_len);
}
public function setButton(nSlot:int, btn:SimpleButton):void {
this.buttonList[nSlot]=btn;
btn.addEventListener(MouseEvent.CLICK, buttonClicked);
}
public function setAddress(nSlot:int, adr:String):void {
// when the panel is instantiated, the adr is set from the XML feed link
// which is set from Wordpress
this.addressList[nSlot]=adr;
}
public function setPageTitle(nSlot:int, pg_title:String):void {
// when the panel is instantiated, the adr is set from the XML feed link
// which is set from Wordpress
this.pageTitleList[nSlot]=pg_title;
}
// button Events
private function buttonClicked(e:Event) {
for (var i:int = 0; i < buttonList.length; i++) {
try {
if (buttonList[i]===e.target) {
// set SWFAddress
SWFAddress.setValue(this.addressList[i]);
// set browser title
SWFAddress.setTitle(this.pageTitleList[i]);
break;
}
} catch (err) {
i++;
trace(err);
}
}
}
}
}
This sets up the buttons events and the associated page address/query string, this is through having the same index in the arrays for the title and address of the pages. I grab these off my RSS feed of my Wordpress CMS, so they could be anything, being a bit geeky I like the numeric query but could easily set up pretty urls in Wordpress.
The next events invoker is the SWFAddress part which response to the setValue call. The top level class of SWFAddress does the majority of the work:
This is the InvokerSWFAddress class:
package com.elliotrock{
import flash.display.*;
import flash.events.*;
import com.asual.swfaddress.SWFAddress;
import com.asual.swfaddress.SWFAddressEvent;
//
public class InvokerSWFAddress extends Sprite {
private var commandList:Array;
private var addressList:Array;
/*
This handles the EventHandler for the SWFAddress event
*/
public function InvokerSWFAddress(list_len:int) {
this.commandList = new Array(list_len);// may need to pull in the length of the setup object plus the categories
this.addressList = new Array(list_len);
//
SWFAddress.addEventListener(SWFAddressEvent.CHANGE, handleSWFAddress);
}
public function setCommand(nSlot:int, c:ICommand):void {
this.commandList[nSlot] = c;
}
public function setAddress(nSlot:int, adr:String):void {
// when the panel is instantiated, the adr is set from the XML feed link
// which is set from Wordpress
this.addressList[nSlot] = adr;
}
// SWFAddress handling
private function handleSWFAddress(e:SWFAddressEvent) {
var found:Boolean = false;
try {
for (var i:int; i < addressList.length; i++) {
if (addressList[i] === e.value) {
found = true;
this.commandList[i].execute();
break;
}
}
if(!found){
// if url doesn't exist
this.commandList[1].execute();
}
} catch (err) {
// executes the home page if a URL server query is not found
this.commandList[1].execute();
}
}
}
}
The Invoker is setup with the query address from Wordpress and the page build command. The SWFAddressEvent listens for both the page change initiated from the InvokerButton and from page changes via the back, forward and history changes from the browser.
In Part 2 I will show the initialisation of these two invokers. This is done from what ever Creational Pattern or method you use.