AlecMcE.com

Coding on the Flash Platform

Archive for the ‘opinion’ Category

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

Posted in as3, library, opinion, tdd

Tagged with , , ,

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.&lt;Fruit&gt;;

	public function TheProblemWithVectors()
	{
		var apples:Vector.&lt;Apple&gt; = new Vector.&lt;Apple&gt;();
		apples.push(new Apple());

		// THIS THROWS AN ERROR!
		fruits = apples as Vector.&lt;Fruit&gt;;
	}
}

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.&lt;Fruit&gt; = new Vector.&lt;Fruit&gt;();

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

without problem, but not this:

var fruits:Vector.&lt;Fruit&gt; = apples as Vector.&lt;Fruit&gt;;

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

Reflecting on as3signals

View Comments

Robert Penner has recently produced a new AS3 library called as3signals (which can be found on both Git Hub and Google Code. I have used it in one small ongoing project, and I am really impressed with it.

as3signals includes two methods for adding listeners: an add listener which permanently adds a listener until a remove listener is called, and an addOnce listener which is a one-time listener only. This is a really welcome addition to the event model. Current projects are littered with code like this:

objectThatDispatchesEvent.addEventListener(EventType, onEvent, [false, 0, true]);

private function onEvent(event:Event):void
{
	objectThatDispatchesEvent.removeEventListener(EventType, onEvent);
	...actual code for handling event...
}

Penner’s signals performs the task much more neatly:

signal.addOnce(onEvent);

private function onEvent(data:Data):void
{
	...actual code for handling event...
}

An interesting problem arises by having two methods for adding listeners that have different behaviours. What happens when you call first one, then the other, without calling a remove method in between? There are three main ways in which you could imagine the framework responding to this situation.

  1. Overwrite Model Each time a call redefines the relationship between signal and listener. In this model, subsequent calls overwrite the relationship;
  2. First-Wins Model The first call defines the relationship between signal and listener. In this model, subsequent calls are ignored. To change the relationship the current relationship should be first removed;
  3. Throw Error Model If you attempt to change the relationship between signal and listener without first calling remove then an error is thrown.

Overwrite Model

The add method defines a stronger relationship between signal and listener than the addOnce method. If I had previously called signal.addOnce(listener) and then called signal.add(listener), I am intentionally strengthening the signal-listener relationship, and want the relationship to change. Conversely, I would expect the relationship to weaken.

A weakness of this model is that if you were to inadvertently change the relationship between the signal and listener, this would be extremely difficult to debug.

First-Wins Model

If you assign an event listener with addEventListener in the as3 native event model then you assign a priority to the listener which defines the order in which listeners are called (an optional parameter, which is 0 by default). In the as3 native event model, you cannot change the listener priority with further addEventListener calls unless you first call removeEventListener. Subsequent listener priorities are ignored. Similarly then, we could take this approach for add and addOnce. All subsequent calls are ineffective unless remove is called.

A weakness of this model is that if you intentionally change the relationship between the signal and listener, then your change should be effective! The following code certainly looks like it should work, but in fact the second line does nothing at all!

signal.addOnce(listener);
signal.add(listener);

Throw Error Model

There are scenarios in which developers might purposefully use both add and addOnce methods without calling a remove method in between. However, there will likely be cases where the two methods are called interchangeably by mistake. This may not be easy to debug, and we could easily help the developer out here by changing the functionality so that if signal.addOnce(listener) and signal.add(listener) are called in either order without an intervening signal.remove(listener), that an error is thrown.

In many ways, this is an extension of the ‘first-wins model’, because it preserves the functionality of that model. However, it recognises that the developer that intends to change behaviour might write something like:

signal.addOnce(listener);
signal.add(listener);

and handles it by throwing an error. The developer can then quickly change his code to either simply

signal.addOnce(listener);

or

signal.addOnce(listener);
signal.remove(listener);
signal.add(listener);

Summary

Penner argues that since the as3 native event model follows the ‘first-wins model’ with respect to priorities, this is the preferred model for handling addOnce and add calls. This argument is a little unsatisfactory, not least because if native as3 design decisions were in-themselves satisfactory, he wouldn’t have written as3signals in the first place!

My immediate preference was for the ‘overwrite model’, but I can see why people might adopt the ‘first-wins model’. I imagine that there is a relatively even split between the two camps. Therefore, I believe that throwing an error is the least confusing of all possible decisions. If an error is thrown, it is more difficult to write code that has unintended consequences. It forces the inclusion of remove methods, which makes code more readable. It is easy to explain and to document.

Hopefully it is obvious that I have enormous respect Robert Penner and the as3signals project. However, these small design decisions can have a large influence on workflow and they are important to get right. Penner has given the code an osflash package and he is clearly committed to writing this for the community. I first argued this point very briefly on one of his blog posts on as3signals, but it is an issue that deserved more serious attention. This sort of design decision would be well served by community discussion. If you have an opinion, please comment!

General Notes on Events

AS3 signals came out of a discussion on the problems that exist in the current event model. It is difficult to see Adobe deprecate this model any time soon, because their component framework, Cairngorm and the greater Flash/Flex community are now so dependent upon this model that it is unfeasible to imagine that they would abandon it.

The only way that the signals approach could be adopted en masse is probably if Adobe migrate to it in some future language ASx {x > 3}, or if some major libraries start to adopt it as their event model of choice.

In an earlier post of mine AS4 Thought Experiment, I attempted to think through my preferred API for a future language’s event model. The article was a response to community chatter about the event model, in part driven by Penner.

We share similar perspectives on how an event model ought to work. On reflection, I prefer Penner’s implementation with event.add(listener) and event.addOnce(listener) to my proposed event += listener, though I still stand by the argument that ideally, events should be demarcated from elements of an object through their own syntax; in my example by using #event... and by defining them in interface or class through public event drag or public event #drag. This, of course, is never going to happen!.

Written by alec

October 6th, 2009 at 8:59 am

Posted in as3, library, opinion

Tagged with

Vector – Annoying Naming Conventions

View Comments

When Adobe released the Flash Player 10 last year, it facilitated a new class, a strongly-typed array: Vector.<T>. I suppose we should all be grateful; now we can finally type arrays, leading to more robust code. I don’t feel very grateful, though. Adobe has given me a headache.

In Geometry the word “vector” has a clear meaning: a vector describes a translation in space. To differentiate from other uses of the word, Wikipedia offer the terms Euclidean, Spatial or Geometric Vector. We recognise this use of the word because every single Flash coder understands the distinction between vector graphics and raster (or bitmap) graphics.

I have been working on a Geometric library recently (my as3voronoi library), and have found the need to create an interface to encapsulate a translation in Cartesian space. What will I call it? It’s a vector, but “Vector” is going to cause a lot of headaches, because Adobe’s new Vector class is in the default namespace.

Which leads me to an utterly futile question: why on earth would they call their strongly-typed array class “Vector”? Why not facilitate the strong-typing of Arrays, since Array is the existing term? Untyped Arrays could be considered functionally equivalent to Array.<*> or Array.<Object>. I realise that Adobe cannot change this decision now it has been made, but why did they do it in the first place?

The only answer that I can see is that the vector class is in the C++ standard template library as a one-dimensional array. Was the decision made on the basis that if it’s good enough for C++, then it’s good enough for Flash? I hope not, because the Array class is not like the C++ array, and I don’t see “bitset”, “deque”, “list”, “map”, “queue”, “set”, or “stack” anywhere in the Flash library. Why adopt the C++ convention in just this context?

Flash has a different context to C++. Flash is a word used to describe a player that uses ActionScript and a vector drawing tool rolled into one. Surely the word “vector” has particular significance for the users of Adobe technology?

So what do I call my vector interface? “Vector2D”? “EuclideanVector”? I haven’t called my Polygon interface “Polygon2D” or “EuclideanPolygon”, nor my line interface “Line2D” or “EuclideanLine”. I don’t need to. The terse name does the job perfectly well. If I only target Flash Player 9 I don’t need to call my vector interface anything other than “Vector”.

The headache is unresolved; I am stuck with wanting an array to be an Array and a vector to be a Vector, but will have to accept that an array will be a Vector and a vector … something else.

Written by alec

August 31st, 2009 at 3:39 pm

“Clean Code” in AS3

View Comments

In 2008, Uncle Bob (Robert C. Martin) proposed to the Agile Community that the Agile Manifesto should have a fifth tenet: “Craftsmanship over Execution”.

It is often held as obviously true that functionality is the most important element of code, since without functionality code is useless. So long as code works, readability and execution speed are valuable. Broadly, Martin argued that this is wrong: craftsmanship is more important than functionality; the professionalism with which we produce our code is the most valuable aspect of our work.

Most software development teams execute, but they don’t take care. We value execution, but we value craftsmanship more. Uncle Bob

It is clear to see why this is a difficult sell! At the moment I work at an agency, where in many cases the typical ‘agency mentality’ prevails: work is to be done as quickly as possible. However, all experienced coders know the consequences of trying to do too much too quickly: quick work leads to bugs, bugs lead to more work, dissatisfied clients, frustrated bosses, and – too intangibly to explain to most bosses – more work on future projects because of less code-reuse. Perhaps you know and accept all this, but it is worth repeating. And repeating, and repeating.

That said, too many of the Flash community seem not to know these truths. The Flash community is in great need of learning from the Agile elder statesmen. Most third party libraries value functionality above all and show little care for craftsmanship.

The history of Flash coding has been to strive for speed; to squeeze functionality out of the Flash Player like no-one had squeezed before. Many people have also created third-party libraries to help fellow coders shortcut to functionality and avoid reinventing a particular wheel. Unfortunately those libraries tend to be poorly written, buggy and unreadable. Even classes in the AS3 Core Library, which is run by some significant Flash notables, seem to have been rushed, no effort taken to clean them up for future developers to learn from or extend.

A Practical Example – The Delaunay Algorithm

Recently I wanted to do some work by creating a Delaunay Triangulation Diagram. I knew what it is, and roughly how the algorithm worked, but as would most people, I Googled it in the hope that someone had already created the algorithm in AS3 that I could use. I found this post on indiemaps.com. It’s a lovely post if you want to understand what the Delaunay Triangulation is or what it does, but the accompanying code is utterly horrible. I defy anyone to be able to read through this algorithm and understand how it works. Here’s a snippet:

public static function triangulate(pxyz:Array):Array {

			var v:Array=new Array();
			var nv = pxyz.length;

			for (i=0; i < (nv*3); i++) {
				v[i]=new ITriangle();
			}

			// the points must be sorted on the x dimension for the rest to work
			pxyz.sortOn("x", Array.NUMERIC);
			var complete:Array 		= null;
			var 	edges:Array 		= null;
			var 	nedge 			= 0;
			var 	trimax, emax 	= 200;
			var 	status 			= 0;

			var	inside:Boolean;
			var 	xp, yp, x1, y1, x2, y2, x3, y3, xc, yc, r;
			var 	xmin, xmax, ymin, ymax, xmid, ymid;
			var 	dx, dy, dmax;

			var		ntri = 0;

			/* Allocate memory for the completeness list, flag for each triangle */
			trimax = 4*nv;
			complete = new Array();
			for (var ic=0; ic<trimax; ic++) complete[ic] = false;

			/* Allocate memory for the edge list */
			edges = new Array();
			for (var ie=0; ie<emax; ie++) edges[ie] = new IEdge();

			/*
			Find the maximum and minimum vertex bounds.
			This is to allow calculation of the bounding triangle
			*/
			xmin = pxyz[0].x;
			ymin = pxyz[0].y;
			xmax = xmin;
			ymax = ymin;
			for (var i=1;i<nv;i++)
			{
				if (pxyz[i].x < xmin) xmin = pxyz[i].x;
				if (pxyz[i].x > xmax) xmax = pxyz[i].x;
				if (pxyz[i].y < ymin) ymin = pxyz[i].y;
				if (pxyz[i].y > ymax) ymax = pxyz[i].y;
			}
			dx = xmax - xmin;
			dy = ymax - ymin;
			dmax = (dx > dy) ? dx : dy;
			xmid = (xmax + xmin) / 2.0;
			ymid = (ymax + ymin) / 2.0;

The problem with this class is plain: it was ported. Clearly it was also ported from a functional language that had no pretence towards OOP. Such ports rely on a line-by-line transposition from one language to another and a bit of testing to check they work. Porting normally means that the porter doesn’t understand what is being ported. It is translation but rarely transliteration.

In the case of the Delaunay Algorithm, perhaps this is not much of a problem; there aren’t really many ways to extend this algoritm. In the case of a framework however, it ought to be unforgivable. If people can’t read the code they can’t improve it, amend it, extend it, adjust it. It makes them consumers and prevents community interaction. The code, the users and the original developer all suffer because of it over the long term.

Faced with this code, I decided to write an implementation of Delaunay’s algorithm myself. I have had this reaction to nearly every piece of library code I’ve read recently! Out of frustration, I have started writing unit testing frameworks, bulk loaders, tween engines, architectural frameworks, 3D engines, and game engines before realising that I don’t have enough time to all these libraries’ functionalities, and will have to live precariously by accepting that the library is closed to me because of its practical complexity and unreadability.

I must point out that I greatly admire and respect the coders who have successfully created the versions of these frameworks that I use (and would admire a great many others if only I knew your work better!), but I can’t help be frustrated at the effort I have to expend in order to read what they have done, particularly if I find a bug! It is the wasted effort that frustrates me: someone understood what they were doing when they wrote this the first time, so why didn’t they write it in such a way that I could understand too?

My own version of the Delaunay Algorithm is in Google Code as the first iteration of the as3voronoi library. It is a work in progress and by no means perfect. Uncle Bob would chastise many of my naming choices, ridiculous comments, and probably some of the design choices that I have made. However, I think that you can at least read this implementation, starting with the math.delaunay.Delaunay class and working out into the other classes as necessary. Here is a method:

public function addPoint(point:Point):void
{
	if (!listOfPoints.add(point))
		return;

	if (listOfPoints.count == 3)
		addInitialTriangle();
	else
		addPointToTriangulation(point);

	listOfEdges.clearUnusedEdges();
}

This is not a direct comparision between two functionally equivalent pieces of code, but merely try to give the flavour of the approach.

Please Write More Beautiful Code

If you can’t explain it simply, you don’t understand it well enough. Albert Einstein

If you are a serious AS3 coder, writing serious code that you hope people will take on and use for serious projects, then please write beautiful code, not just functional code. Write code that explains itself, that reads like English, that uses both sides of peoples’ brains.

Please don’t dazzle the community with archane cleverness, complex methods, and huge classes.

Please don’t let your code rot, by adding functional change on functional change without reflecting on the general structure of your code and refactoring where practical.

If you come from an artistic background and aren’t steady on your coding feet, innovate and explore and hack around, but then sit down with a friendly developer and pair program your innovation into something clean, readable, and reusable.

And please fight when your bosses or fellow coders contend that it’s not worth it. If it isn’t worth it on that day (and it probably will be), it certainly will be in three months time.

Agile Software Development Resources

These two books from Uncle Bob are excellent resources for learning about writing more elegant code:


Written by alec

August 26th, 2009 at 12:14 am

Posted in as3, library, opinion

AS4 Thought Experiment

View Comments

Introduction

At the end of last week, parts of the Flash community engaged in a twitter-based reflection on the state of ActionScript. Twitter isn’t the best forum for analysis, but it’s a fairly powerful tool for gauging perspectives, and it ought to cause Adobe some alarm that there was a significant body of notable Flash developers out there who feel that Flash is in danger of falling behind the likes of Silverlight and HTML5.

Part of this reflection was a consideration of the evolution of the language syntax; considering the question ‘What should AS4 look like?’. In one post Robert Penner (@robpenner) suggested an ActionScript syntax modification. This AS3

element.addEventListener(Event.CHANGE, onChange);

should be expressible as

element.change += onChange;

Penner argues that the event model has become unwieldy, and required pruning. He offers a solution that looks more like AS1, but keeps the concept of adding a stack of listeners to an event.

The elegance of the change ought to be apparent to everyone who has read this article so far. I want to consider it in more detail.

Missing Parameters

Let’s take this idea on a few stages, starting with the missing parameters. Years ago now, Grant Skinner (@gskinner) identified the problem with strong event listeners preventing garbage collection from doing its job. We may also want to add event listeners in the capture phase of the event, and give it a priority.

element.addEventListener(Event.CHANGE, onChange, false, 0, true);

We need to be able to make these tuning modifications. Would it be better to do

element.change += onChange, false, 0, true;

or simply one of

element.change.add(onChange, false, 0, true);
element.change.addEventListener(onChange, false, 0, true);

and accept that in the more complicated case, you don’t use the += operator? If so, then it’s a shame because as a matter of principle, I never define an event without setting the event listener as weak, so that I never need concern myself with the problems Skinner identified.

From Natural Language

Our Object-Oriented Programming languages borrow from our natural language. The objects of our language are given natural language labels (nouns) as we code, while their methods expose behaviours (verbs). It is preferable to express object.getURL() as object.url, because a url is a property of Object, and is used as a noun in code, not as a verb. object.load() clearly triggers something to be loaded, load is the verb; object.load without brackets feels wrong because it’s a verb but isn’t being used as a verb.

Events are problematic. If you have two classes, Line and Screen and you want to code a relationship such that when your line changes, the screen updates, you will inevitably use ‘change’ as both a verb and as a verbal noun.

Here I’m referencing the change but I wouldn’t expect the change to be triggered. This is when I’m using the name of the event as a verbal noun:

element.change += onChange;

but I could also imagine doing this

element.change(data);

since change is a verb, and that’s what you do with verbs. I would assume that the change is triggered by this syntax, since calling the method means the object ‘does’ the change.

I am uncomfortable having events expressed in the same way as other properties and methods. It might seem more simple to treat them as the same as other members in an object over the short term, but these sorts of distinctions exist in language because they are useful.

Following the example of namespaces and XML parsing, why not just find a different symbol for expressing the particular type of relationship? What about:

element#change += onChange;
element#change(data);

The hash (or whatever) would indicate that the string following is an event, not your common all-garden member variable or method.

A Fanciful Implementation

Staying within this thought experiment, I don’t want a definition of an event in code to be the same as defining a member variable, because they are different and particular things.

I also want to be able to trigger an event as parsimoniously as I can add and remove listeners to it. Above I suggested that you can use ‘change’ as a method (as a verb) as well as a property (as a noun). Why not make that the mechanism for dispatching an event?

public class Dragger extends Sprite
{
	private var startingPosition:Point;

	public event drag:DragEvent;

	public function Dragger()
	{
		#press += onDragStart;
	}

	private function onDragStart(event:MouseEvent):void
	{
		startingPosition = new Point(event.mouseX, event.mouseY);
		#mouseMove += onDrag;
		#release += onDragEnd;
	}

	private function onDrag(event:MouseEvent):void
	{
		var dX:Number = event.mouseX - startingPosition.x;
		var dY:Number = event.mouseY - startingPosition.y;
		#drag(dX, dY);
	}

	private function onDragEnd(event:MouseEvent):void
	{
		#mouseMove -= onMove;
		#release -= onDragEnd;
	}
}

Summary

This is, of course, a thought experiment, and reflection. The code has not been considered for a long time, and it probably won’t withstand scrutiny. However, the Flash community is considering making adjustments to a language, and I don’t see why we would constrain ourselves to considering changes that are minimal or conservative! I am interested by the change Penner suggested, and would love to hear what you think about my extension of that thought.

Written by alec

August 10th, 2009 at 12:18 pm

Posted in opinion

Tagged with ,