AlecMcE.com

Coding on the Flash Platform

Archive for the ‘opinion’ Category

Invalidation Manager

View Comments

Introduction

Invalidation is a pattern employed to solve problems where updating a model’s data may happen multiple times per frame, but updating the view’s rendering should happen only once. When dependencies exist between multiple models this can get complicated and potentially messy. This article looks at a solution to this mess by unifying invalidation logic into a single manager class.

The purpose of this discussion is not to offer a new class for people to take and use in their libraries so much, though you are welcome, if you should want to. Rather it is to discus a problem and my solution. Hopefully some people will learn something from reading it, and hopefully I will learn something by getting feedback about it!

The Invalidation Pattern

Consider the following simple implementation for drawing a coloured circle:

public class Circle extends Sprite
{

	private var _color:uint;
	private var _radius:Number;

	public function get color():Number { return _color; }
	public function set color(value:Number):void
	{
		_color = value;
		resolve();
	}

	public function get radius():Number { return _radius; }
	public function set radius(value:Number):void
	{
		_radius = value;
		resolve();
	}

	private function resolve():void
	{
		graphics.clear();
		graphics.beginFill(_color);
		graphics.drawCircle(0, 0, _radius);
		graphics.endFill();
	}

}

The problem here is that if in one frame I changed both the radius and the color, the resolve() function would be called twice. Though not a problem in this case, it could be if the resolve() function involved a lot of complex logic.

The invalidation pattern resolves it this way:

public class Circle extends Sprite
{

	private var _color:uint;
	private var _radius:Number;

	public function get color():Number { return _color; }
	public function set color(value:Number):void
	{
		_color = value;
		invalidate();
	}

	public function get radius():Number { return _radius; }
	public function set radius(value:Number):void
	{
		_radius = value;
		invalidate();
	}

	public function invalidate():void
	{
		... at some future point of my choosing, trigger resolve() ...
	} 

	public function resolve():void
	{
		graphics.clear();
		graphics.beginFill(_color);
		graphics.drawCircle(0, 0, _radius);
		graphics.endFill();
	}

}

Often in AS3, the invalidate() function looks like this:

public function invalidate():void
{
	addEventListener(Event.ENTER_FRAME, onEnterFrame);
}

private function onEnterFrame(event:Event):void
{
	removeEventListener(Event.ENTER_FRAME, onEnterFrame);
	resolve();
}

It is a good pattern that solves the problem of multiple resolve() calls. The actual mechanism contained inside invalidate() which causes resolve() to be called once at a convenient point is unimportant. For this sort of structure, this simple implementation does the job.

Where The Invalidation Pattern Becomes Complicated

Imagine that you have two classes: a line, and a circle, the intersection of which defines two circular segments. In fact, don’t imagine: look at this:

The Flash plugin is required to view this object.

Both the line and circle implementations consist of two points which, on moving, invalidate the their equations. On resolve() the equations are resolved. The segments depend upon the the line and circle; when the line or circle is invalidated, they should be invalidated also.

A mechanism for the segments to know when their definiens (that which defines them) are resolved is required, suggesting that each element conforms to a common interface:

public interface Invalidates
{

	function invalidate():void;

	function get invalidated():Signal;

	function resolve():void;

}

and an implementation along these lines:

public class Line implements Invalidates
{

	private var _ax:Number;
	private var _ay:Number;
	private var _bx:Number;
	private var _by:Number;

	private var _invalidated:Signal;

	public function Line()
	{
		_invalidated = new Signal(Invalidates);
	}

	public function get ax():Number { return _ax; }
	public function set ax(value:Number):void
	{
		_ax = value;
		invalidate();
	}

	... missing a few uninteresting methods ...

	public function invalidate():void
	{
		_invalidated.dispatch(this);
	}

	public function resolve():void
	{
		... resolve the line ...
	}

}

public class Segment implements Invalidates
{
	private var _line:Line;
	private var _circle:Circle;

	... missing the constructor ...

	public function get line():Line { return _line; }
	public function set line(value:Line):void
	{
		_line = line;
		_line.invalidated.add(onInvalidated);
	}

	... missing a few uninteresting methods ...

	private function onInvalidated(definien:Invalidates):void
	{
		invalidate();
	}

	public function resolve():void
	{
		_line.resolve();
		_circle.resolve();

		... the rest of the resolution ...
	}
}

The problem here is the same problem that led us to consider the Invalidation Pattern in the first place: namely, that the Line’s resolve() method is going to get called a lot. Sure, we can pack the methods with lots if calls like:

private function invalidate():void
{
	if (_isInvalidated)
		return;

	_isInvalidated = true;
	invalidate();
}

public function resolve():void
{
	if (!_isInvalidated)
		return;

	_isInvaldiated = false;
	_line.resolve();
	_circle.resolve();

	... the rest of the resolution ...
}

However, it starts to feel like the classes are consumed with handling the invalidation management, rather than with what should be their single responsibility of properly modelling the geometrical entities for which they are named.

An important feature of this implemenation is that it guarantees that the Line’s and Circle’s resolve() methods are called before the sgement resolves. If B depends on A, then A must resolve before B resolves. This is a key feature of the Invalidation Manager, below.

Managing Invalidation

The current as3geometry library attempts to solve the problem of invalidation using the InvalidationManager.as class.

The Invalidation Manager handles classes that satisfy the Invalidates.as interface. Invalidates objects can be registered to the InvalidationManager, and dependencies can be established. As this happens, objects are categorized into tiers.

Initially, since every object is independent of each other when registered, newly registered elements are considered in tier 0. However, if a dependency is established such that B depends on A, B is put into the tier above A, so if A is in tier 0, B is in tier 1. If then C depends on B, since B is already in tier 1, C goes into tier 2.

The utility of the tiers comes from the fact that all objects in tier 0 are independent of each other and may be resolved in any order. Tiers are resolve in ascending order, ensuring that any object that is depended upon is resolved before any object which depends on it.

The problem with this approach comes when, for example, A depends on B depends on C already so they have the following tiers:

Then, if I have another object D already in tier 3, and define that B depends on D, I must move B to tier 4 and therefore also move C to tier 5.

Circularity presents an interesting problem within this system. If A depends on B depends on C, and then I define that C depends on A, the tier system breaks down. Currently attempting to create a circular reference will fail and an error will be thrown.

In order to keep the InvalidationManager clean, it does not actually handle when it resolves, but instead dispatches a signal when it has elements that require resolution. In the as3geometry implementation the AS3GeometryContext.as wraps the InvalidationManager and hooks it to the player events to so that when invalidation occurs it is resolved in good time.

The Invalidates classes, other than telling the contxt what it has a relationship to and what it does not, no longer contains any code that tries to manage other objects’ invalidations:

public class Line implements Invalidates
{

	private var _ax:Number;
	private var _ay:Number;
	private var _bx:Number;
	private var _by:Number;

	private var _context:InvalidationManagerContext;
	private var _invalidated:Signal;

	public function Line(context:InvalidationManagerContext)
	{
		_invalidated = new Signal(Invalidates);

		// elements that don't depend on other classes  like this don't really need the
		// context stored, but I store it here for consistency, and in case the structure
		// changes
		_context = context;
		context.register(this);
	}

	public function get ax():Number { return _ax; }
	public function set ax(value:Number):void
	{
		_ax = value;
		invalidate();
	}

	... missing a few uninteresting methods ...

	public function invalidate():void
	{
		_invalidated.dispatch(this);
	}

	public function resolve():void
	{
		... resolve the line ...
	}

}

public class Segment implements Invalidates
{
	private var _line:Line;
	private var _circle:Circle;

	private var _context:InvalidationManagerContext;
	private var _invalidated:Signal;

	public function Segment(context:InvalidationManagerContext)
	{
		_invalidated = new Signal(Invalidates);

		_context = context;
		_context.register(this);
	}

	public function get line():Line { return _line; }
	public function set line(value:Line):void
	{
		_line = line;
		_context.addDependency(_line, this);
	}

	... missing a few uninteresting methods ...

	private function onInvalidated(definien:Invalidates):void
	{
		invalidate();
	}

	public function resolve():void
	{
		... just resolve here! this is the big win ...
	}
}

Conclusion

A benefit to this approach is that Invalidates classes need very little boiler-plate code. The author of an Invalidates class need know only that changes should call invalidate() and that all resolution logic happens in resolve(). Responsibilities are extremely well separated.

The as3geometry implementation wraps the InvalidationManager into an AS3GeometryContext.as class that has a little more logic than the InvalidationManager, which does not have a mechanism for actually triggering the mass resolution. While the InvalidationManager handles the internal logic set-out above, the AS3GeometryContext handles hooking up the InvalidationManager to the player events.

There is a downside, of course. Currently in as3geometry, the constructor of every class contains a reference to the AS3GeometryContext, and every class stores a reference to it. It is not clear to me that this approach is avoidable, unless the manager is defined as a singleton. There are lots of good reasons why singletons are bad, not least because I might have good reason to have two parallel geometric contexts in one application.

Written by alec

August 11th, 2010 at 11:45 pm

Why we need Generics in AS3

View Comments

Introduction

Almost not a day goes by that I write some code destined for a library and wish that Adobe had implemented generics for AS3. Generics is the ability to specify a type that will be used within a class without explicitly defining the type. If you are developer that has started coding for player 10, then you’re probably familiar with the Vector implementation. This is currently the only place that generics exists in AS3, and it sticks out like a sore thumb. Generics are useful for one main reason: it is easier to write code that can be massively re-used if you can use generics. More code reuse means less code. Less code means smaller applications, faster code, and more time for better features. There are few down-sides to generics.

What Are Generics?

Object pooling is something I need to do reasonably often. I would like to be able to create an interface that allows me to describe some common features of an IObjectPoolable item, such as a reset() method that could be called to clear out any data particular to an ‘instance’ of the object. I would then like to be able to specify an ObjectPool class and specify which kind of IObjectPoolable type it is pooling. Then, when I call ObjectPool.consume(), I don’t have to type-cast the object it gives me, because the compiler knows what kind of object it is. It knows, because I defined it when I constructed the ObjectPool.

The code for such a class might look something like this:

class ObjectPool.<T:IObjectPoolable>
{
	private var _pool:Vector.<T>;
	private var _index:uint;

	public function ObjectPool.<T>()
	{
		_pool = new Vector.<T>();
		_index = 0;
	}

	public function alloc(count:uint):void
	{
		for (var i:uint = 0; i < count; i++)
			_pool.push(new T());
	}

	public function dealloc(count:uint = 0):void
	{
		if (!count)
			count = _pool.length;

		_pool.length -= count;
	}

	public function consume():T
	{
		return _pool[_index++];
	}

	public function release(object:T):void
	{
		var i:uint = _pool.indexOf(object);
		if (i == -1)
			throw new Error("You cannot release an object into a pool that it does not come from");

		object.reset();

		_pool[i] = _pool[index];
		_pool[--index] = object;
	}
}

T in the above example stands for the type which the ObjectPool pools. Of course, I can’t test this code so there may be logical errors, but hopefully you see where I’m going with this.

Perhaps you think that I could do the same thing without generics, by adding run-time checks into my code. That will make the code slower than it should be, and in order to check whether it works I’ll have to run it because errors will only arise at run-time. Compile-time checking is better than run-time checking.

Perhaps if I have Robot objects and Donkey objects I could create two object-pool classes: a RobotObjectPool and a DonkyObjectPool class? That implies that for each IObjectPoolable object that I create I will also need to create a new object pooling class. That’s bad in so many ways. It means less code reuse (in fact, I may end up copying-and-pasting code into classes!), the application’s code weight will increase (fewer bangs for your bytes), there are more places where errors could creep into my code, and I have to spend all that extra time creating all those extra classes.

A Related Limitation of interface

You may have noticed that in the alloc method above I am constructing the type using new T(). Within the interface IObjectPoolable I have no way of enforcing that the constructor requires no arguments. I should have, either by being able to specify:

public interface IObjectPoolable
{
	function IObjectPoolable();
}

or

public interface IObjectPoolable
{
	function new();
}

or something like C#, in the ObjectPool class itself, specifying new() to indicate a parameterless constructor:

class ObjectPool.<T:(IObjectPoolable,new())>

Note also that to illustrate generics I chose an example in which I wanted to be able to restrict T to a particular set of types, using <T:IObjectPoolable>. This is elegantly done in C#, it should be done in ActionScript too.

Vector.<T>

Currently one implementation of generics exists, for Vector.<T>. On the face of it, it is extremely perplexing why generics have been implemented only for Vector, but there are practical reasons why Adobe can’t simply roll generics out. The Vector.<T> was implemented because of a realisation that iterating over Array represented a specific performance overhead that Adobe could do something about.

During his recent visit to the Flash Gaming Summit, Nicolas Cannasse explained to me that Vector is a hack comprising three classes under the hood. In fact, Adobe engineers have created Vector.<int>, Vector.<Object> and (I think – though this one is hazy) Vector.<Number>.

UPDATE: Robert Penner informs me that I remember this incorrectly. There are in fact four Vector implementations. Follow the link to the comment below for more details.

The two numerical implementations are designed to give specific speed improvements when iterating over collections of numbers. The Vector.<Object> implementation is the catch-all for all other type. However, Adobe has clearly done the work necessary for compile-time checking that the type being passed into the Vector.<Object> is preserved throughout the code.

Adobe then has done a lot of work towards implementing generics, but the Vector implementation was a specific workaround. As we are probably all aware, there’s a huge difference between a workaround and a truly flexible feature.

haXe

If I like generics, why not start using haXe, since haXe has generics already built in?

There are a few reasons why I’m reluctant to go down the haXe road at the moment.

  • Firstly, there’s code I write for myself, and code I write for my work. The work code has to be AS3. I find it harder writing in two dialects of the same fundamental language than I do writing to completely different languages.
  • Then, there’s the prospect of having to rewrite almost everything in my library. If I move back into a self-employed mode in the future, then there is little doubt that I’ll adopt haXe, but if I’m doing this in spare time, it is a daunting task.
  • Then there’s the lack of haXe support in FDT. This is going to change soon, but until I can write haXe without having to give up the tools that I love to work with, that represents a significant barrier to entry.

In many ways, haXe blazes far ahead of AS3 for these sorts of language requirements. It is frustrating that AS3 lags behind haXe when AS3 has a team and corporation behind it, while haXe has a handful of extremely talented people. If AS3 can’t iterate closer to haXe and soon, there may be no option but to go down the haXe road in the next few months.

Issues

With generics there are certain complications that should be addressed. The most subtle of these is something I highlighted in my article The Problem with Vector<T>. I incorrectly argued that the following should be ok:

public interface Fruit;
public class Apple implements Fruit;

var fruits:Vector.<Fruit>;
var apples:Vector.<Apple> = new Vector.<Apple>();

fruits = apples;

The problem was really that perhaps I had a makeSmoothie(Vector.<Fruit>) method somewhere that expected Vector.<Fruit>, I would have to construct a new Vector.<Fruit> and pass in each member from Vector.<Apple> before then passing that newly constructed object into makeSmoothie. This seemed like an expensive overhead to me.

My brother Ewan pointed out that this is not straightforward. He wrote three articles on this:

  • the first exploring the problem of trying to add an Orange to the fruits vector, and the consequences surrounding that;
  • the second discussing how C# 4.0 has the potential functionality to get around that problem, by defining two generic types, so that perhaps a class could be defined as Vector.<Fruit, Apple>, where essentially the first type is the exposed type (what you get if you reference an index in the Vector), while the second type is the required type (what type is allowable to be set as a reference for an index).
  • and finally an article which explains the concepts behind the C# 4.0 implementation from it’s core concepts of covariance and contravariance.

Conclusions

This stuff it extremely complex; it is a can of worms that if AS3 did implement generics it would have to consider and take seriously. Though designers complained about AS3′s complexity over AS2, I doubt anyone can seriously argue that AS3 wasn’t a huge step forward in terms of potential and power. ActionScript is now grown up, but it is still young and it still has lots to learn. Now Adobe are creating tools that allows designers to produce many of the more simple functionalities in Flash without having to touch code. That’s great in my opinion, it allows people like me to spend more time developing more interesting stuff that can’t be tied down to a drop-down menu in Flash CS5. I have a good toolset for that right now, but I want and need more tools. While the IDE and player evolve, the language is standing still.

The ActionScript developer community is a huge asset for Adobe. We are the heart of the Flash Platform. Right now, it’s much stronger than most people give it credit. For example, Microsoft’s new KIN website was developed in Flash, not Silverlight! This is surely because the UI developer talent still works in ActionScript for Flash, not in C# for Silverlight.

However, this can change quickly. The Flash Platform is now clearly challenged, from Apple, HTML5 and Silverlight. Many developers are considering migrating to other languages and platforms. Many have retooled to work on Objective-C, Android, and HTML5. Many work in multiple languages. The danger for Adobe is that gradually more and more people drift away from using ActionScript as their day-to-day language of choice. If people move elsewhere and the quality of Flash content starts to wane, Adobe’s power-base dissolves with it.

ActionScript needs to evolve. It could do worse than evolving to support generics.

Written by alec

April 13th, 2010 at 10:27 am

Posted in as3,opinion

3-Party Swingometer

View Comments

The BBC coverage of UK elections is well-known for its use of the Swingometer. The Swingometer represents parliamentary constituencies as points on a line. A central point represents equality between the two major parties: the Labour Party (red, politically centre-left) and the Conservative Party (blue, politically centre-right). How far from that central point the seat is to the left or right denotes how strongly that seat is held by Labour or the Conservatives respectively, and how big a shift in opinion is required for the seat to fall into the other party’s hands.

However, if two parties can be compared one-dimensionally, then three parties can be compared two-dimensionally. In many ways, the UK has a three-party parliamentary system. The Liberal Democrats hold a position in UK politics far stronger than any other party that would be considered ‘others’ (see political notes below). It is not inconceivable that at some future point the Liberal Democrats could displace one of the two major parties, and after the upcoming general election their roll could be the most significant for a generation if – as the polls have been predicting – the UK experiences a hung-parliament.

This small application was the product of a day or so prototyping, using Bit 101′s Minimal Components and RobotLegs to see if I could come up with something a bit more interesting than theBBC’s online Swingometer. It lacks the BBC’s finesse (which is unsurprising for a very quick prototype), but I think it is rather more fair to the Liberal Democrats.

The Flash plugin is required to view this object.

Political Notes

Several smaller parties exist, notably the Scottish National Party and Plaid Cymru, the Welsh nationalists. However, these do not have UK-wide reach, and swings to or from either party will not have large national implications, simply because the populations of Scotland and Wales are so much smaller than that in England.

Northern Ireland politics is also omitted from this graph. The source data did not contain Northern Ireland data, but I have not sought to add it either, since Northern Ireland has a quite different political system which is largely based on religious and cultural social differences; the trends in the rest of the UK do not apply to Northern Ireland, and vice versa. Its data would be trivial for the purposes of this visualisation.

Apparently, the change of popularity in the Liberal Democrats has caused the BBC to change its use of the swingometer over the years. They reduced the role of the swingometer as the Liberal Democrats’ power grew in the seventies, and reintroduced it as it waned in the eighties and nineties. Now, the current implementation on their website has three swingometers that can be tabbed between. It is strange then that they haven’t chosen to adopt a more sophisticated representation.

The source data that I used for this application can be found at pippanorris.com. The limitations of the data is most evident in the 1997 election data. The landslide Labour victory is masked by the omission of most of the Scottish constituencies. The problems with historical data are frustrating. If any better data source is known, I would love to know of it.

Written by alec

April 7th, 2010 at 11:09 pm

Posted in as3,opinion,project

Ifs and Buts and Strings

View Comments

It has been a fun morning in the twitterverse. @kaeladan (aka David Wagner, my replacement at Yomego, and friend) tweeted that:

Dear Flash programmers, stop using if( foo ) or if( !foo ) to check if an object is null. It’s both Bad and Wrong. Luv, K #dodgylibraries

To support the argument, David put this gist on github:

var iAmAStringInstance :String = "";
var iAmANullString :String = null;

if(iAmAStringInstance)
    trace("iAmAStringInstance: That there is an instance!");
else
    trace("iAmAStringInstance: That there is a null object!");

if(iAmANullString)
    trace("iAmANullString: That there is an instance!");
else
    trace("iAmANullString: That there is a null object!");

It took me a while to understand what I had trouble with in David’s tweet, but the gist helps. The trick is that the semantic label that David has applied to the if (foo) conditional is not correct in the context of a String. If we use if (foo) we are not in fact testing for existence. We are testing for existence and non-triviality. The implication that all we’re doing is testing for existence versus nullity comes from the trace statements within the conditionals. These are well-meant, but misleading.

That David used a String for this example is significant. A typed object reference can only resolve to false if it is null. String is one of the few ambiguous cases, like a Number or an Object (which is ambiguous because it could be a String or a Number).

Once we got going some people argued that we should change the language so that an empty string or 0 casts to a Boolean as true. Clearly this is a hypothetical decision, since you can’t change the API of a language after the fact. They have a point in terms of consistency with a typed Object I suppose, though I think it’s a over-the-top to argue as DavidArno does that:

@alecmce The idea that a non-zero length string is true and a zero-length string is false is a broken paradigm. That was my point.

That’s a bit strong I think. How often does it break down your code? Sometimes, it is positively useful that an empty string (or 0) casts to Boolean as false.

I often want to test whether something is substantive. Take a URL for example – potentially someone could have initialised a variable for a URL in the constructor, or potentially it could be null. I want to know if it’s been filled in, so I can use if (url) to test for that. It would be as annoying in this brave new paradigm to have to write if (url != "") as it would to have to write if (url == null) in the current one.

To go back to the example then, we need to be careful to be clear about what our code actually means:

if(iAmAStringInstance)
    trace("iAmAStringInstance is neither null nor empty");
else
    trace("iAmAStringInstance is either null or empty");

if(iAmANullString)
    trace("iAmANullString is neither null nor empty");
else
    trace("iAmANullString is either null or empty");

In one sense then, I agree with David, though not in the sense he intended. It goes over Twitter’s character limit, and it’s rather less pithy, but perhaps he might have tweeted:

Dear Flash programmers, stop using if( foo ) or if( !foo ) to check if an untyped object, string or number is null. It’s Bad and Wrong in these particular contexts, if what you really are trying to do is to check for existence, rather than substance..

Written by alec

March 19th, 2010 at 12:13 pm

Posted in as3,opinion

When is a sub-class appropriate?

View Comments

My colleague Anatoly and I regularly need to create dialogs which pop-up in front of our application. Anatoly has created a class which allows the dialog to be configured by a packet of data which contains header, any text or images, button labels, footers, and information about how the buttons are processed, like this:

public class Dialog extends Sprite
{
	public function Dialog(data:DialogData)
	{
		... composes the dialog according to the data that is passed into it ...
	}
}

Anatoly – Dialog Composition

Let’s say that Anatoly wants to create a dialog in a particular view class (please ignore any other architectural considerations – I say “view class” broadly, hoping not to rile anyone who might shout “mediator”, which is beside the point in this case):

public class SomeClassWhereDialogsAreShown
{
	...

	public function onActionWhichTriggersExampleDialog():void
	{
		// this is a simplified structure to avoid complicating the point
		var header:String = "This is Header";
		var body:String = "This is body";
		var buttons:Array = ["OK","Cancel"];
		var data:DialogData = new DialogData(header, body, buttons);
		var dialog:Dialog = new Dialog(data);

		showDialog(dialog);
	}

	// this is one of many dialogs defined here...
	public function onActionWhichTriggersADifferentDialog():void { ... }
	public function onActionWhichTriggersAThirdDialog():void { ... }
	public function onActionWhichTriggersAFourth():void { ... }
	public function onActionWhichTriggersAFifthDialog():void { ... }
}

It is important to note that I have massively over-simplified the DialogData. It could be dozens of lines long, contain nested arguments, and so on. This point becomes part of the discussion later on.

Me – Dialog Inheritance

In contrast, I want to create a dialog sub-class and package away the dialog data:

public class ExampleDialog extends Dialog
{
	public function ExampleDialog()
	{
		// this is a simplified structure to avoid complicating the point
		var header:String = "This is Header";
		var body:String = "This is body";
		var buttons:Array = ["OK","Cancel"];
		var data:DialogData = new DialogData(header, body, buttons);

		super(data);
	}
}

public class SomeClassWhereDialogsAreShown
{
	public function onActionWhichTriggersExampleDialog():void
	{
		showDialog(new ExampleDialog());
	}
}

This approach allows me to encapsulate the ExampleDialog very neatly, though it requires more lines of code than the composition approach. ActionScript is verbose enough without actively seeking to add more lines of code.

Single Responsibility Principle

If the dialog needs to be changed, the inheritance approach ensures that the only place that code editing need take place is in the code which relates to the particular dialog. This conforms to the Single Responsibility Principle, based on the principle of cohesion: the degree to which lines of code form a single unit of functionality is the extent to which they should be in their own class.

I would argue that creating a particular dialog is a functional unit, especially in user-interface code. Anatoly makes the point that all our dialogs are functionally equivalent (more of which below). I suppose he thinks of functionality in terms of the developer, and I the interface.

OOP Design principles are not inviolate, but they point us towards ways of writing code which lead to more robust code. This principle points towards the dialog configuration data not being defined in the SomeClassWhereDialogsAreShown class. (which is different from saying it supports the inheritance approach!)

Liskov Substitution Princple

Creating inheritance chains can be problematic. It might be considered reasonable to create a Square class as a subclass of the Rectangle, like this:

public class Rectangle
{
	...

	public function set width(value:Number):void
	{
		_width = value;
	}

	public function set height(value:Number):void
	{
		_height = value;
	}

	public function get area():Number
	{
		return _width * _height;
	}

}

public class Square extends Rectangle
{
	override public function set width(value:Number):void
	{
		_width = _height = value;
	}

	override public function set height(value:Number):void
	{
		_height = _width = value;
	}
}

However, this can cause problems. Imagine, during your code that you utilise Rectangle like this:

public class SomeOtherClass
{
	public function doubleRectangleArea(rectangle:Rectangle):void
	{
		rectangle.width *= 2;
	}
}

The doubleRectangleArea method presupposes that the Rectangle‘s width and height properties are independent. Polymorphism allows a Square to be passed into the doubleRectangleArea method, but as configured this would quadruple the square’s area. The functionality of the doubleRectangleArea method is broken because the Square-Rectangle relationship breaks Liskov Substitution Principle (LSP).

This principle serves as a general warning against inappropriate inheritance. Anatoly invoked it in our discussion as a reason to be cautious about inheritance, but I remain unconvinced – surely not all inheritance is bad, and I am pretty sure that as things stand, no particular thing about our dialogs violate LSP?

Function and Configuration

Let’s suppose you want to model two cars: A Honda Jazz and a Lotus Exige. The following class structure may be appropriate:

public class Car { ... }

public class HondaJazz extends Car { ... }

public class LotusExige extends Car { ... }

If, on the other hand, you have two colours of Honda Jazz, the following structure makes little sense:

public class HondaJazz extends Car { ... }

public class BlueHondaJazz extends HondaJazz { ... }

public class WhiteHondaJazz extends HondaJazz { ... }

More sensible would be:

public class HondaJazz extends Car
{
	public function HondaJazz(color:uint) { ... }
}

In the case of the two types of car there are clear functional differences: acceleration, top-speed, fuel efficiency, to name a few. In the case of the two jazzes, there are no functional differences, merely different configurations.

Anatoly argues that different dialogs are essentially like different configurations, rather than different functionalities. Therefore, they should all be the same class, but the Dialog should be configured through parameters in its constructor.

Discussion

So what is the right approach? The Single Responsibility Principle (SRP) definitely points away from the composition approach, if the class in which the composition is made has many other responsibilities. Anatoly has offered to meet me half-way having conceded this point, instead storing the various configurations in static methods of Dialog, or elsewhere, rather than create a subclass.

To me, this still feels wrong. The Function and Configuration argument is a good one, and points towards no sub-class being created. However, I still feel that the sheer quantity of configuration that some dialogs require start to make the act of configuration feel inappropriate.

Furthermore, if all we are really doing is is configuring the same dialog over and over, then I do not think that the Liskov Substitution Principle (LSP) is a concern. If all dialogs really are functionally equivalent, then how can they violate LSP?

Aesthetically, the inheritance approach feels right to me, but it is important to respect that Anatoly comes from a very different tradition and has been coding a lot longer than me! The discussion was an interesting (and pleasant) one. If any of you can add to it, then I would be delighted to hear your points of view.

Written by alec

February 15th, 2010 at 9:00 am

RobotLegsPong Part 1 – Overview

View Comments

Introduction

RobotLegsPong attempts to combine RobotLegs application framework with the as3signals event model and a Frame-Ticker (as well as a pinch of ASUnit unit-testing) to create a ‘game’.

It is an open-source project, available on GitHub as an example of using RobotLegs together with these other technologies.

Source Code: github/alecmce/RobotLegsPong

RobotLegsPong is not a very good game; it is playable only in the loosest sense. Bats require to be dragged in order to move (and there is no computer-logic to play against), so you could not really play against an opponent. The purpose of the exercise was to see what structure a game like Pong would take within the RobotLegs framework.

The purpose of this article is to describe the particulars of the technologies and why I chose them. In a follow-up article, I will look in more detail how RobotLegsPong is wired up.

Why I Chose These Technologies

RobotLegs

The RobotLegs framework is a lightweight, flexible application framework that allows coders to spend less time wiring up their application, and more time working on its functionality.

Frameworks are often criticised because they force developers to write code in a particular way, which might be inappropriate for a particular context. I have used Cairngorm, Pure MVC, as well as some proprietary frameworks, and have found that all of them do some things well, and do other things clumsily. So far I have not found this problem with RobotLegs, because most of the time it gets out of the way and lets you code; in fact, it does more than that: it reduces the amount of code you have to write.

as3signals

RobotLegs comes with an application event bus, but I have decided to circumvent that and use as3signals instead. as3signals allows you to define an object which acts as an event dispatcher within an application.

I like as3signals because describing an event as a Signal object allows my event model to be described through interfaces. as3signals is supposed to be fast too. Then again, interfaces are slow. The relative speeds of the approaches is interesting, but not a significant factor in my decision making process.

Frame-Ticker

The frame-ticker is a simple idea: rather than creating multiple enter-frame event listeners, each creating event objects, create one enter-frame listener and a main game loop iterating through those methods that need to be called per-iteration.

This implementation came out of a discussion on Twitter that I was involved in on the fringes; I wrote about it in a previous blog post.

ASUnit

Unit testing enables developers to test portions of their code in isolation, so that they can be confident that every method works exactly as the developer intended. They also represent a secondary form of documentation-in-code; if you want to know how I meant a method to work, reading the unit test will tell you almost everything you need to know (including, if a good test is missing, what I didn’t consider).

That said, I have not unit tested every method; in this example I have only unit-tested the geometric logic for the bats. This is bad practice, however under time constraints I think that it is most important to unit test what is complex, mathematical or ambiguous, since this is where behaviour is most likely to fall down.

[Inject]

The ‘trick’ to using RobotLegs is that you do not need to inject dependent objects into classes when you contruct them; this is done automatically. This code:

public class Dependee {}

public class MyExample
{
	public var dependee:Dependee;

	public function MyExample(dependee:Dependee)
	{
		this.dependee = dependee;
	}
}

becomes this code:

public class Dependee {}

public class MyExample
{
	[Inject]
	public var dependee:Dependee;
}

The metadata tag [Inject] has the effect of automatically injecting the dependee into the class when it is constructed. This isn’t much on the face of it, but it is enough. It feels to me as though a quarter of my code is actually just wiring up classes so that they each have access to the classes that they need to function, or passing objects around methods. The [Inject] tag lets me shift all of that wiring into the RobotLegs framework.

Context

There is a little more to the RobotLegs story however; how should RobotLegs react when it comes across an [Inject] tag? It could construct a new Dependee object, or it could be that I want only one Dependee object to be injected wherever the [Inject] tag is found. This is where the Context class becomes meaningful.

In the PongContext, different classes are wired up in different ways. Their definitions are defined by adding injector mappings and the mediatorMap mappings in the startup method.

public class PongContext extends Context
{
	override public function startup():void
	{
		...
		injector.mapSingleton(DragMechanism);
		injector.mapSingletonOf(Geometry, GeometryModel);
		injector.mapClass(BatGeometry, BatGeometryModel);
		...
	}
}

injector.mapSingleton

injector.mapSingleton(DragMechanism)

mapSingleton indicates that only one instance of the class entered should be constructed. In this case, just one DragMechanism will be created, and injected whenever this is found:

[Inject]
public var mechanism:DragMechanism;

injector.mapSingletonOf

injector.mapSingletonOf(Geometry, GeometryModel);

mapSingletonOf extends the mapSingleton idea to interfaces and their implementing classes. In this case the Geometry interface is mapped to the GeometryModel class. The injection is called as follows:

[Inject]
public var model:Geometry;

No reference to the GeometryModel is needed in any class other than the PongContext. This allows a very pure use of interfaces across the application.

injector.mapClass

injector.mapClass(BatGeometry, BatGeometryModel)

injector.mapClass works a little differently; whenever a BatGeometry interface is flagged to be injected, a new instance of BatGeometryModel is constructed and injected into the class, so the following code is used to create the injection:

Each BatMediator needs its own BatGeometry object. By using the mapClass method, multiple BatGeometryModel objects will be constructed, one for each time the following code is found:

[Inject]
public var model:BatGeometry;

Mediators and Components

public class PongContext extends Context
{
	override public function startup():void
	{
		...
		mediatorMap.mapView(Background, BackgroundMediator);

		addChild(new Background());
	}
}

mediatorMap references a slightly different aspect of the application: your view objects. The mediatorMap allows users to define associations between display objects and Mediators. These two parts comprise the View aspect of the standard MVC pattern.

The DisplayObject – in this case Background – is the asset that you want to be visible on the stage. In my pong example this is essentially just a Sprite, though it might just as well have been imported as a graphical asset in a SWC.

The Mediator is associated with the DisplayObject so that when an instance of the DisplayObject is created, the corresponding Mediator is also constructed. The BackgroundMediator looks something like this:

public class BackgroundMediator extends Mediator
{
	[Inject]
	public var view:Background;

	override public function onRegister():void
	{
		...
	}
}

The DisplayObject Background is injected into the BackgroundMediator when it is constructed. The DisplayObject can then be manipulated. It is an elegant solution that separates display object from UI logic.

addChild(new Background());

is all that is needed to wire the entire DisplayObject/Mediator combination.

RobotLegs & Tickers

The RobotLegs structure is particularly useful for wiring up a Ticker-based application because one ticker can be mapped as a singleton, and injected to all those methods that need to iterate every frame:

public class PongContext extends Context
{
	override public function startup():void
	{
		...
		injector.mapSingletonOf(Ticker, EnterFrameTicker);
		...
	}
}

RobotLegs with as3signals

I really like the style of event dispatching that as3signals provides, but my implementation demands that if one class requires another class then it must flag it to be injected, and then the signal wired up in a method flagged as [PostConstruct] (see GeometryModel). This doesn’t feel like the right solution.

Integrating as3signals with RobotLegs is beyond the scope of this article. It looks like Joel Hooks and Robert Penner are making inroads into this problem through as3signals’ Google Group. I look forward to seeing what they come up with.

Written by alec

January 19th, 2010 at 7:01 am

The Problem With Vector.<T>

View Comments

I thought I’d found a bug with respect to Adobe’s new Vector class. I logged it in JIRA, but the answer came back that it is Not A Bug. Respectfully, I disagree. Here’s why.

UPDATE: I may be wrong about this. My brother has written a response: http://bit.ly/9OotIS. For further discussion, please also see the comments below.

The Problem

// create an interface and implementing class
public interface Fruit {}
public class Apple implements Fruit {}

// create a vector of Apple objects and try to cast it to a vector of Fruit objects
public class TheProblemWithVectors
{
	public var fruits:Vector.<Fruit>;

	public function TheProblemWithVectors()
	{
		var apples:Vector.<Apple> = new Vector.<Apple>();
		apples.push(new Apple());

		// THIS THROWS AN ERROR!
		fruits = apples as Vector.<Fruit>;
	}
}

The following is indisputable:

  • All (elements in) apples must be an Apple;
  • All Apples are Fruits;
  • Therefore, (elements in) apples are Fruit.

In which case, why can’t apples be cast as fruits? The Flash player does not accept that a Vector of Fruit could be described as a Vector of Apple. To me this feels like a bug. Does it to you?

Not A Bug?

To Adobe it is Not A Bug:

http://bugs.adobe.com/jira/browse/ASC-3836

According to Chris Peyer who works at Adobe:

This is the expected behavior. Vector. and Vector. are unrelated types no matter what the relation is between Example and ExampleA.

It seems to me that this argument can only stem from the idea that if one object is composed of Fruits and another composed of Apples, that does not mean that the two objects are themselves related:

public class MarketStall
{
	public var forSale:Apple;
}

public class Supermarket
{
	public var forSale:Fruit;
}

There is no relationship between MarketStall and Supermarket in this code.

Surely though the relationship between two Vectors defined by a generic is much stronger than that? The Vector is nothing more than an indexed plurality of the objects that compose it. We know it doesn’t have other unrelated functionality. We can do this:

var fruits:Vector.<Fruit> = new Vector.<Fruit>();

for each (var apple:Apple in apples)
	fruits.push(apple);

without problem, but not this:

var fruits:Vector.<Fruit> = apples as Vector.<Fruit>;

Most importantly however, can’t the Adobe engineers see how damned useful it would be if we could cast Vectors like this? Languages should not get in the way of what is intuitively right. You should not have to struggle with the language like this, or find workarounds. Flash developers are almost always looking for improvements in speed and memory, but here you the language makes you waste memory and take time. Or, use the other workaround and avoid Vector and use Array instead. That’s what I did; what a triumph, Adobe!

Please Vote On This Bug

I’ve been here before! My former Colleague Vizio360 rediscovered this bug about buttonMode=true preventing unloading of SWF files, but it too was resolved by being called Not A Bug. The clamour for it to be reopened has so-far fallen on deaf ears, but the only way anyone will ever take any notice is if you vote and comment.

Currently Adobe consider this issue closed. Pehaps if you comment on the post they will give it second thoughts. (this is edited text after it was pointed out to me that you can’t vote for closed bugs)

http://bugs.adobe.com/jira/browse/ASC-3836

Written by alec

December 16th, 2009 at 3:11 pm

Posted in as3,opinion

Replacing ENTER_FRAME – Testing Tickers

View Comments

Last week I posted a reflection on a discussion about strategies for replacing ENTER_FRAME listeners. The ActionScript 3 event model requires an event object to be constructed every time an event is dispatched. Constructing objects is slow, which doesn’t matter in many contexts, but in speed-critical contexts, we would like to minimise the amount of time we spend dispatching events. The article considered a way to do this.

This article discusses a first attempt to test the relative performance of two ‘solutions’ to the problem of optimising a game loop ‘ticker’, and is based on this source code:

http://github.com/alecmce/TickerStrategies/

Two Approaches To The Problem

If you have already read the previous article, you might want to skip this section.

From the discussion, it appears that most developers who’ve run into this problem have created a ‘ticker’, which creates one ENTER_FRAME listener:

stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);

Robert Penner introduced a second idea which uses a two-frame MovieClip and exploits the undocumented addFrameScript method to attach methods to the timeline frames. Both do the same thing: each frame they iterate over an array of methods and call them:

addFrameScript(0, onEnterFrame, 1, onEnterFrame);

This idea stems from an hypothesis that because the scripts are called from a MovieClip timeline, they do not have an associated event object. There should therefore be a small but potentially significant time-saving in using the frame script approach.

Compiling For The FrameLoop Approach

The two-frame loop is required because if you try to ‘play’ a one-frame timeline, Flash is smart enough to recognise that it’s a bit pointless, and will do nothing. If you play a two-frame timeline, it will loop continuously.

One solution is to create a symbol in an FLA with two empty frames, but I rarely if ever touch the Flash IDE as a developer, and would prefer an elegant solution which does not require the IDE.

My first thought was to use the [Frame(factoryClass=etc)] metadata structure, but this turns out to be problematic. I could build without problems and what I built ran within certain player contexts, but not others.

The metadata structure is unsatisfactory, because it required creating two classes that act as ‘main classes’ – it looked messy. Happily, I have since found (via senocular.com‘s documentation of the MXML compiler) a rather pleasing way of creating a 2-frame (or more) MovieClip through MXMLC. By adding the following line to the end of the compiler arguments, I force the SWF to be built with a second frame (frame 1, zero-based indices):

-frames.frame 1 flash.display.Sprite

Testing The Hypothesis

My implementations of the ‘ticker’ can be found in the tests that I have created can be found at http://github.com/alecmce/TickerStrategies/. Comments, critiques and suggestions would be gratefully received.

The solution therefore was to create MovieClips with minimal structure built on top of them that would put the player under stress, and to implement both strategies. They could then be run side-by-side and evaluated. Here are the test builds. They run only if you mouse-over them.

EnterFrame Ticker

The Flash plugin is required to view this object.

FrameLoop Ticker

The Flash plugin is required to view this object.

Notes on the Tests

The profiling tool at the top is a hacked version of the Lost In Actionscript SWFProfiler tool. I modified the styles and exposed more of the API by making some minor changes to his original. My variation can be found here.

Unlike the original idea of replacing an event listener with a signal from #as3signals, the frame loop implementation I created is as pared down as possible. This is in order to make the test as fair as possible.

As far as I can interpret the tests so far, there is almost no performance difference between the two, but there might be a small memory gain by using the frame loop. Every time I run the tests I get different results however, and a thorough record of results in order to find their normal distribution is probably needed.

The test probably need to be more rigorous. They currently test one particular point of heavy stress for the player, but there may be circumstances in which one or the other strategy starts more obviously out-performing the other. If you have an idea about how to improve these tests, please post it.

I did consider using Grant Skinner’s Performance Harness but dismissed it in this circumstance. Test harnesses perform tests on synchronous code very well, but it is not clear to me how you could test this sort of performance on a similar basis. Rather than testing milliseconds for execution, this test is trying to evaluate the memory overhead of events object construction and destruction and any potential performance implications of that and the different mechanisms for firing methods on entering a frame.

Written by alec

November 29th, 2009 at 11:34 pm

Posted in as3,opinion

Replacing ENTER_FRAME

View Comments

Today an interesting discussion took place on Twitter, in which I was involved. It caught my attention for a variety of reasons, and I wanted to document the conversation, the problem and the solution here. It started when it was identified that Flash’s event dispatcher is sub-optimal in performance terms, and revolved around trying to find a solution.

Why replace the ENTER_FRAME?

Every event that is dispatched creates an object. An ENTER_FRAME creates as many objects per second as there are frames. If you have mutliple objects dispatching ENTER_FRAME events, that’s many objects creating event objects many times per second. Computationally, chains of “many” are one of those things you want to avoid. So, can we do better?

Doing Better

Robert Penner proposed creating an as3signal and using a MovieClip with two frames to dispatch that signal on each frame. He posted his idea to this GitHub gist.

One drawback to this approach is that it requires a MovieClip symbol with two empty frames, to which the two event dispatcher methods could be attached. I remembered reading in this excellent article by Bit 101 how using a [Frame] metadata tag would force your application to have two frames. This seemed to be what Penner needed for his functionality to work correctly, so I came up with my own GitHub gist which extends the concept. The code is also added ‘below the fold‘, at the bottom of this article.

[Update, after Jackson's comment, below] The idea behind the approach is that a frame-loop is an internal Flash player structure. It sits underneath the AS3 functionality, and so it doesn’t produce ENTER_FRAME events. By hooking into them we can produce our own iterative ‘event’ (Penner proposes using an as3signal), which doesn’t construct an object each time it is dispatched. It is a lovely idea, and quite distinct from invoking one ENTER_FRAME dispatcher on the root or stage of the application.

[Update, after Joa Ebert tweeted test results] Whether this method is superior to the ‘one-event ticker’ is open to question. Joa Ebert applied the frameloop concept to AudioBox and found no memory nor performance improvements.

Background

It all started today with a statement on Twitter from Robert Penner:

Listening to a single #AS3 enterFrame will create over 1000 event instances per minute. @robpenner

In fact, at a decent frame rate, you’re looking at 1800 event instances per minute. Across the blogosphere and on Twitter, there has been a lot of talk about the cost of object construction in AS3. People are pushing the limitations of the player, and are looking for performance optimisation wherever they can find it. Strategies such as object pooling are becoming mainstream in order to avoid the creation and destruction of objects. In the meanwhile, the internal Flash event model is creating and destroying huge numbers of objects to furnish us with an event model.

At the same time however, there has been a murmur of discomfiture about the state of the event model. (Not that I have much of a voice, but I chimed in to this debate as well!). The most notable result of this murmur was Penner’s decision to create as3signals. It is an on-going project to which I have contributed in a small way, and which I whole-heartedly support.

After Penner’s tweet, the #as3 twitterati (please tweet if there are glaring omissions from this list) became very excited indeed.

My initial thoughts led to the idea that maybe the setInterval/setTimeout functions, which are hangovers from AS2 might offer a solution – perhaps they shortcut the event system? Not only ain’t it so, they’re even worse as this Action Script Viewer deconstruction of the setInterval methods demonstrate.

So what else? Mike Chambers (aka @Mesh) in conversation with @TheFlashBum pointed towards a solution using a ‘ticker’; a single ENTER_FRAME dispatcher, and @bengarney confirmed that he also uses this technique.

It seems that @scottjanousek and @robpenner had the idea of using the player frameloop (which the solution offered here exploits) at pretty much the same time. (@scottjanousek’s tweets are protected, but it was reported by this tweet.)

Whether and how this vein of thought will develop is really interesting. It is fascinating how a tweet from one of the best-known ActionScript developers can provoke such a lot of attention from the general community. It is interesting too to see the envelope of what is possible being pushed.

Read the rest of this entry »

Written by alec

November 26th, 2009 at 11:37 pm

ASUnit – A Conventional Problem

View Comments

There are several conventions involved in unit-testing. If you use FDT, this structure will be familiar to you. If not, you should get the picture anyway:

A standard structure for a unit-tested project in FDT

TestRunner does one thing: starts the unit-test framework by adding the AllTests TestSuite. That AllTests will then in-turn add all of the AllTests in the next level of packages (in this case, just the one AllTests in the alecmce package). This happens recursively through the entire package tree. Any tests that lie in the same package as an AllTests are added by that AllTests, so alecmce.topsecret.AllTests is responsible for adding alecmce.topsecret.ThisClassWillChangeYourLifeTest.

This convention works really well. More and more people are adopting unit-testing while developing their tools/frameworks. Their tests are published alongside their tools/frameworks, so that you can be confident that they work as anticipated, and so that you can use the tests as a form of documentation for the known working functionality of the tools/frameworks.

Suppose you want to import a tool/framework into your project. For example (as it was the reason that this problem arose), let’s suppose I want to add as3signals into my project. Since it has a suite of tests, in case I need to make changes to the library, I want to add those tests to the suite of tests that I run. I download the framework from github and add it to my lib folder, adding the src and test folders as source folders:

A file-system with as3signals added as a library

There’s a problem here. There are two classes in the default package called AllTests. First there’s mine, which is responsible for adding alecmce.AllTests, then there’s also as3signal’s which is responsible for adding org.AllTests.

There is no way to differentiate between them; they conflict:

Error: Can not resolve a multiname reference unambiguously. AllTests

The convention of creating a class called AllTests in each package is clean and simple in the one-library environment. If you import multiple projects then the convention breaks down. Of course, there are other ways of importing libraries into yours: you could package them up as swcs (or else, use the swc provided), or you could create separate projects in FDT and link the projects together (assuming you use FDT of course – though I’m sure other environments can work similarly).

For me, that diminishes the point of using unit-testing. I want to have all the code that goes into my project tested all the time. While I don’t expect to change signals, I want to be able to reassure myself that everything is still working as I anticipate it to for all the code, every time I run my tests.

A change in convention?

If instead of AllTests I called my tests TopsecretAllTests or AllTests_topsecret and the signals tests were called SignalsAllTests or AllTests_signals the class ambiguity would disappear. It is feasible however that two people could end up using the same project name under different packages. Then, maybe two people would end up with AllTests_topsecret classes and the ambiguity would persist.

The guaranteed solution is to append the full package name onto each AllTests class: AlllTests_alecmce_topsecret is a candidate. Then, two tests’ packages would only conflict if the packages themselves conflict (in which case the tests are the least of their problems). However, this seems like over-kill.

Unfortunately, because the AllTests convention is the convention, this problem is thorny. Even if the AllTests_topsecret pattern is an acceptable work-around, it will not be adopted by people until the need arises, and then, probably, any number of different practises will emerge. The existing norms are well known, well documented and in common practise. It is, effectively, a problem without a solution.

Written by alec

October 29th, 2009 at 11:32 am

Posted in as3,opinion,tdd