Flashden goes official

Flashden has finally removed the beta from their name. Time to load up on stock flash. You see my creations on my portfolio page.

No Comments


Design pattern wanted.

Calling all design pattern gurus. I’ve got a challenge for all you object orientated persons. I’m currently working on an actionscript component framework, that includes modal behaviour. That is if a component is modal, when it is enabled, all other components are disabled. Think of an alert box that doesn’t allow you to progress through an application until you’ve chosen an option and you’ll see what i’m trying to achieve.

I’ve actually got this all working fine. My only reservation is that the solution i’ve come up with seems a bit clunky. Anyway on with the show. I’ll detail all the steps in the creation, with pseudo-code examples.

The basis for all this is the component class, which all my other components will inherit from. It has enable, and disable public functions.

class com.lookmum.view.Component{
//enable function
public function enable(){
//enable component code here
}

//disable function
public function disable(){
//disable component code here
}
}

Next comes the creation of the modal manager class. This is a singleton which all components will register with when they become enabled, and unregister from when disabling. It also includes methods to enable and disable all active components. Here’s the relevent parts of the class shown with pseudo-code

class com.lookmum.util.ModalManager
{
// the list of all enabled components
private var componentList : Array
//the list of all components that this class has disabled, stored ready for re-enabling
private var disabledList : Array
public function registerComponent (com : Component) : Void
{
//add a component to the active list
}
public function unregisterComponent (com : Component) : Void
{
//remove a component from the active list
}
public function disableModal () : Void
{
//disable all active components and add them to the disabled list
this.disabledList.push ([])
var currentLayer : Number = this.disabledList.length - 1
<![CDATA[for (var i = 0; i < this.componentList.length; i ++)]]-->
{
if (this.componentList [i].enabled)
{
this.componentList [i].disable ()
this.disabledList [currentLayer].push (this.componentList [i])
}
}
}
public function enableModal (forceAll : Boolean) : Void
{
//enable the last disabled batch of components and put them back into the enabled list
var currentLayer : Number = this.disabledList.length - 1
var currentLayerLength : Number = this.disabledList [this.disabledList.length - 1].length
<!--[CDATA[for (var i = 0; i < currentLayerLength; i ++)]]-->
{
this.disabledList [currentLayer][i].enable ()
}
this.disabledList.pop ()
}
}

We then revise the component class to register itself with the singleton on enable, and unregister on disable.

import com.lookmum.util.ModalManager
class com.lookmum.view.Component{
private var modalManager:ModalManager
//constructor function
public function Component(){
//get a reference to the modal manager singleton
this.modalManager = ModalManager.getInstance()
}
//enable function
public function enable(){
//register the component with the modal manager
this.modalManager.registerComponent(this)
//enable component code here
}
//disable function
public function disable(){
//unregister the component from the modal manager
this.modalManager.unregisterComponent(this)
//disable component code here
}
}

Our immediate problem is that the enable functions affect registration with the singleton, so we need to test wether it is the singleton doing the enabling, and not to register/unregister if it is. The quickest thing to do is to pass an argument to the enable functions telling the component that the function is being called by the manager.

//the modified enable modal function in modal manager
public function enableModal (forceAll : Boolean) : Void
{
//enable the last disabled batch of components and put them back into the enabled list
var currentLayer : Number = this.disabledList.length - 1
var currentLayerLength : Number = this.disabledList [this.disabledList.length - 1].length
<!--[CDATA[for (var i = 0; i < currentLayerLength; i ++)]]>
{
this.disabledList [currentLayer][i].enable (true)
}
this.disabledList.pop ()
}

and…

//the modified enable function
public function enable(modal:Boolean){
if(modal){
//register the component with the modal manager
this.modalManager.registerComponent(this)
}
//enable component code here
}

The main problem with this approach is that we are making what should be internal behaviour public. There’s no way to enforce that the boolean value will only be passed by the manager.

Another approach would be to have a pair of enable functions, enable() and modalEnable(). One for general use which performs the registration, and one for use by the manager. However this still makes public something that should happen behind the scenes. There’s nothing to stop another developer accidentally using modalEnable() instead of enable()

The solution I came up with was to have this second enable function, but make it a private member. I then create a function delegate within the normal enable function and pass it to the modal manager with the component registration.

//the modified enable function
public function enable(){
//register the component with the modal manager and pass a function delegate as a scond parameter
this.modalManager.registerComponent(this,mx.utils.Delegate.create(this,this.modalEnable())
}
doEnable()
} 	private function doEnable(){
//enable component code here
}

We then give the manager event dispatching behaviours and let it add and remove the listeners itself.

public function disableModal () : Void
{
this.disabledList.push ([])
var currentLayer : Number = this.disabledList.length - 1
var dispatchList:Array = new Array()
for (var i = 0; i < this.componentList.length; i ++)
{
if (this.componentList [i][0].enabled)
{
dispatchList.push(this.componentList [i][1])
this.disabledList [currentLayer].push (this.componentList [i])
}
}
for (var i:Number = 0; i
this.addEventListener(DISABLE,dispatchList[i])
}
this.dispatchEvent(new Event(DISABLE,this))
for (var i:Number = 0; i
this.removeEventListener(DISABLE,dispatchList[i])
}
}

What i really want is some way to make a method of a class A only available to instances of another class B, bearing in mind that these two classes are unrelated, and i want any errors to be compile time, which means doing fancy things with arguments.caller isn’t quite what i want.

Any ideas anyone, or am i just being a pedant?

5 Comments


Particle Playground

I finally released my finished particle simulation extension for flash7+. You can purchase it from flashden here for a mere 10 bones.

No Comments


Featured item on flashden (with thoughts on wallop)

A simple little extension I created for flashden is currently a featured item. This site rocks. It allows me to package up little utilities i created for other jobs and sell them for a few bucks without the hassle of setting up my own on-line store.

This got me thinking about microsofts new myspace competitor wallop. A few people have pointed out that you can make quick cash from creating little widgets for the site. But i wonder if this is really such a great idea. The fact that you need to invest the development time for such items, coupled with the rather large API you need to learn in order to implement widgets for the site, seems to suggest that you need to ship a lot of units before you see any return on the time you’ve invested. And i’m not event sure how many people are actually using wallop.
Compare this to flashden where all i have to do is package things i’ve already developed, and i think it’s easy to see that there’s better ways to spend your time.

2 Comments


Holiday snaps

People and police on the beach

I finally got round to uploading some of my holiday pictures to flickr. You can see them as a slide show here.

When I get some free time, I’ll hopfully be integrating my flickr account into this site, so you can view the pictures here.

1 Comment


Actionscript: The rules #2 – Observer pattern for all events

All classes that generate events should do so via the observer pattern.

This one might prove a little more contravertial than the last, but i’m going to stick my neck out and say that all classes should use the observer pattern for events, rather than myEvent=function() callbacks, or object listeners.

For those who don’t want to read up about the observer pattern check out the EventDispatcher class which is basically an implementation of this. or better still grant skinners GDispatcher which has a few extra tricks up its sleeve. The first benefit of this method is that you can have multiple objects listening to the same event. This is all covered in the chapter on the observer pattern in Colin Moocks Essential ActionScript 2. If you want to start using these classes i suggest you read the tutorials on EventDispatcher and Delegate over at actionscript.org.

I also tend to use Dynamic flash’s Delegate class rather than macromedias own for scoping the listener object, as this also has a few added extras, such as passing the delegate itself to a listening function, as well as the event object, which makes removal of anonymous delegates an easy task.

This may sound like overkill for a lot of simple class structures, and you will have to remember to remove your event listeners, but it does mean consistency. If you’re using EventDispatcher in one class, and myEvent=function() style callbacks in another, then it’s easier to make mistakes. And harder to pick up code that you havent looked at in a while, because you have to figure out which method you used.

When using EventDispatcher it’s always useful to include static constant variable strings (try saying that 10 times quickly) for all the events a class will dispatch. This not only lets you keep track of which events a class broadcasts easily, but also provides compile time checking to make sure you are subscribing to events that actually exist. For example:

import com.gskinner.event.GDispatcher
class com.lookmum.Broadcaster{
public static var MYEVENT:String = 'myEvent'
public var addEventListener:Function
public var removeEventListener:Function
public var dispatchEvent:Function
public function Broadcaster(){
GDispatcher.initialize(this)
}
public function myFunction(){
this.dispatchEvent({type:MYEVENT,target:this})
}
}

and…

import com.lookmum.Broadcaster
import com.dynamicflash.utils.Delegate
class com.lookmum.Observer{
private var broadcaster:Broadcaster
public function Observer(){
this.broadcaster = new Broadcaster
this.broadcaster.addEventListener(Broadcaster.MYEVENT, Delegate.create(this, this.eventHandler))
}
public function myFunction(){
this.broadcaster.myFunction()
}
private function eventHandler(){
trace('event handled')
}
}

Two added benefits are that this makes it easy to document events because you can attach javadoc comments to the string constants and they stand out from other class members so events are easy to find rather than function callbacks which apart from their names look just like empty functions.

This is all very similar to the way events are used in AS3 and so if you can get used to using this methodology now, then the transition should be that much easier. In fact another useful methodology that AS3 uses is the use of a proper Event class, as the event object rather than using a standard object, which makes it easier to keep track of what properties your event object will hold.

1 Comment


Actionscript: The rules #1 – Refactor over reuse

Lately i’ve been trying to formalise a lot of the processes i use for coding actionscript so I started to write them down. I then was going to post them to my blog, however this quickly grew into a very large post, so i’ve decided to break them up into a series. Also this should make discussion of each of these points easier, and allow me to add more as i think of them (also it means i shouldnt be stuck for content for a while ;) ).

This isn’t a definitive list of best practices, and i’m sure people will disagree with me on some of the points but i think it helps to write this stuff down and discuss it. And with the introduction over it’s time to dive into the first rule.

“When creating classes don’t create them to be reused. Reusability should come from refactoring old classes”

This is an important but tricky skill to master, the ability to go back to some code you’ve already written and rework it. It can be a major headache the first time you want to reuse something, but if you can generalise a little more the code you’re useing every time you look at it, eventually you’ll end up with a solid code base. This goes hand in hand with not writing for reusability as raised by qlod, but rather letting reusablility come out of refactoring by itself.

Heres a simple example. Lets say we write a class for a specific task:

class myClass{
private var a:Number = 1
public function doSomethingWithNumbers():String{
//multiply by 2
a*=2.toString()
//then return the new value
return a
}
}

Later we want another class that does something similar. We could subclass our original like so:

class mySubClass extends myClass{
public function doSomethingWithNumbers():String{
//multiply by 2
a*=2
//then add 1
a+=1
//then return the new value
return a.toString()
}
}

However another approach is to move the common functionality to a super class, then have both classes extend this. First We create the super class:

class mySuperClass{
private var a:Number = 1
public function doSomethingWithNumbers():String{
return doSomethingSpecificWithNumbers().toString()
}
public function doSomethingSpecificWithNumbers():Number{
return a
}
}

Then we create our two sub classes:

class myFirstSubClass{
public function doSomethingSpecificWithNumbers():Number{
//multiply by 2
a*=2
//then return the new value
return a
}
}

And:

class mySecondSubClass{
public function doSomethingSpecificWithNumbers():Number{
//multiply by 2
a*=2
//then add 1
a+=1
//then return the new value
return a
}
}

So we now have two sub classes that do exactly what we wanted, and we also have a more generalised superclass, that should we want to create a third class in the future, is easy to extend for whatever we need it for.

I realise this may be an overly simplified example, but hopefully you’ll see the benefits of what i’m getting at here. Most importantly we’ve acheived reuse without having to waste time guessing what functionality we will need in the future while writing the first class. This means we’ve avoided writing any code that we don’t actually use, and anything that helps us to do less work can only be a good thing right?

2 Comments


Extending Actionscript implicit getter & setters.

Here’s something i only just noticed. If you overwrite either a getter or setter in a subclass of a class with both, but don’t provide a hook for the other one, then the property will become either read or write only. For example:

MyClass{
var _i:Number
public function get i ():Number{
return _i
}
public function set i(num:Number):Void{
this._i=num
}
}

Will produce the following expected behaviour:

var myClass = new MyClass()
myClass.i=10
trace(myClass.i) //traces 10

In the subclass we overwrite the setter with some new behaviour:

mySubClass extends MyClass{
public function set i(num:Number):Void{
this._i=num*2
}
}

Will produce the following not so expected behaviour:

var myClass = new MySubClass()
myClass.i=10
trace(myClass.i) //traces undefined

Which means the property i has become write only. To keep the property read and write you need to copy the getter into the sub class:

mySubClass extends MyClass{
public function get i ():Number{
return _i
}
public function set i(num:Number):Void{
this._i=num*2
}
}

And you then get the following:

var myClass = new MyClass()
myClass.i=10
trace(myClass.i) //traces 20

I know it makes a kind of sense, but it does mean you have to be careful you’re not changing the signature of your subclasses, as they dont behave exactly as you might expect.

3 Comments


Nice design blog.

Just a quick one to point out webcreme. It’s a great design blog with hardly any text, just large thumbnails linking to some beautifully designed websites. The emphasis seems to be on sites that work too which is always good news. Skip intro need not apply.

1 Comment


Certified flash certification certificate

It’s been a while coming but i finally got my certification pack today. I suppose it took a while to get all the certificates reprinted after the Macromedia/Adobe merger. It is very shiny though so i’ll let them off.

certificate

On a related note, one thing i forgot to mention in my previous post on the certification was that during the exam, a lot of questions were about code and techniques that beginners to flash would use. This makes a lot of sense, because as an experienced developer you’re supposed to be able to look at code from anybody and figure out whats going on. Not just completely datatyped, and neatly packaged stuff.

Keep that in mind if your coming up to the exam to not only revise the more advanced areas of the program, but also try to remember the techniques you used when you first started with flash.

No Comments



  • SetPageWidth