RobotLegs Posts

Try Harder 2012

The above is what it looks like from a speakers position at the try { harder } conference. (click to embiggen).

I had indented to write this post a couple of weeks ago, immediately after the conference but STRATO denied that. But oh well, here it is anyways.

This year was the second annual try { harder } conference / coder retreat / brain explosion. I have spoken about try harder in the past but it really is a uniquely awesome event. Its a rather intimate affair  where 10-15 people getting together and sharing ideas and knowledge in the tranquil forests of Center Parks Nottingham.

The format was largely the same as last year. Everyone gave a talk on a topic of their choosing, some were technical talks such as David Arno‘s on C# (NCrunch, MVC & Mono) or Mattes Groeger‘s on developing iOS social games. Quite a few talks were on non-technical things such as David Wagner‘s talk on ‘the value of tinkering’ or Stray‘s talk on ‘Heuristics, collaboration special sauce’. Each talk was fascinating and the wide range of topics covered adds to the special feel of this event.

When deciding what to give my talk on I couldn’t make my mind up. I have been through a lot this year from launching my first business then having it fail to exploring a great many new tools and technologies to creating and launching my first mobile game. Not to mention all the cool things I have had the pleasure to work on at Playdemic. In the end it was a tweet from David Wagner who suggested that I talk about an exciting tool I had been experimenting around with lately; Adobe Monocle.

Adobe Monocle is the new profiler for flash and mobile content from Adobe and really is very nice. It currently still in pre-release and hence under NDA so I had to ask for permission before giving the talk on it. I haven’t had permission to blog about it get so if you want to find out more about it then check out this video that Thibault Imbert made a few months back:

I personally think it is a game changer for flash game makers. It makes development so much easier by giving better insights as to what is going on inside your game.

Try Harder is more about simply giving talks however. Each afternoon was set aside for pair programming sessions. Like last year we were given a deceptively simply problem then split off in pairs to try to solve that problem in a test-driven way. The kicker was that at the end of your hour with your parter you then must delete all your work and start again with the next person.

The problem we were given this year was “to find and score the palindromes with a length greater than 3 chars in a given string”. Seems simple, but when you get into it, it is deceptively complex. Because of the varied programming backgrounds of the attendees there were many different tools and technologies used.

Of the 6 different partners I had I solved the problem using: Javascript, Actionscript3, Haxe, C#, Java and Ruby using TextMate, Flash Builder, FlashDevelop, Visual Studio and IntelliJ. It was fascinating to see the multitude of ways to solving the same problem

Try Harder is held in the heart of the forests of Center Parks Nottingham. This adds to a sense of “getting away from it all” and I found it to be a really helped with concentrating on what we were doing. In many of the evenings I enjoyed walking around the forests or swimming in the pool or sampling David Wagner’s rather excellent scotch whisky that he brought with his all the way from Scotland (cheers Dave!)

   

So if you cant tell I had a great time at try { harder } this year. I think because I knew what to expect this time I could relax and enjoy the whole thing a little more. I also approached the event with a much more open mind which meant I could relax more and enjoy the format.

Bring on try { harder } 2013!

On Porting RobotLegs2 & SwiftSupenders2 to Haxe

I originally hoped that this post would be about my successful completion of a RobotLegs2 port to Haxe however something else has come up (more on that in a later post) so instead im just going to talk about the process and progress of the port thus far.

So although there is already an excellent RobotLegs 1 Haxe port out there by David Peek, I decided I would like to try to port the brand new Robot Legs 2 Framework  which offers a great many improvements over the original.

Rather than beginning the port from scratch I decided to use as3hx to take the legwork out of converting the AS3 code to Haxe code. To get the tool you must first checkout the library from its google code repo at: http://caffeine-hx.googlecode.com/svn/trunk/projects/as3hx/

Once downloaded its just a simple matter of compiling the source into a neko executable:

[codesyntax lang="powershell" lines="normal"]

haxe as3hx.hx

[/codesyntax]

Then you can run it with:

[codesyntax lang="powershell" lines="normal"]

neko as3hx.n

[/codesyntax]

To convert a AS3 project give it an input and output folder:

[codesyntax lang="powershell" lines="normal"]

neko as3hx.n -vector2array -uint2int robotlegs2 robotlegs2out

[/codesyntax]

In this case the input folder is the source download from the RobotLegs2 GitHub page.

It will start to convert but will get stuck:

[codesyntax lang="powershell" lines="normal"]

C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/api/IEventCommandMap.as
C:/Users/MikeC/Desktop/as3hx/robotlegs2out/robotlegs/bender/extensions/eventcommandmap/api/IEventCommandMap.hx
C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/impl/EventCommandExecutor.as
C:/Users/MikeC/Desktop/as3hx/robotlegs2out/robotlegs/bender/extensions/eventcommandmap/impl/EventCommandExecutor.hx
C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/impl/EventCommandFactory.as
C:/Users/MikeC/Desktop/as3hx/robotlegs2out/robotlegs/bender/extensions/eventcommandmap/impl/EventCommandFactory.hx
C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/impl/EventCommandMap.as
C:/Users/MikeC/Desktop/as3hx/robotlegs2out/robotlegs/bender/extensions/eventcommandmap/impl/EventCommandMap.hx
C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/impl/EventCommandTrigger.as
Called from ? line 1
Called from Run.hx line 66
Called from Run.hx line 55
Called from Run.hx line 55
Called from Run.hx line 55
Called from Run.hx line 55
Called from Run.hx line 55
Called from Run.hx line 55
Called from Run.hx line 38
Called from C:Motion-TwinHaxe/std/neko/Lib.hx line 63
Called from Run.hx line 29
Called from as3hx/Parser.hx line 117
Called from as3hx/Parser.hx line 131
Called from as3hx/Parser.hx line 488
Called from as3hx/Parser.hx line 415
Called from as3hx/Parser.hx line 589
Called from as3hx/Parser.hx line 794
Called from as3hx/Parser.hx line 744
Called from as3hx/Parser.hx line 919
Called from as3hx/Parser.hx line 964
Called from as3hx/Parser.hx line 1106
Called from as3hx/Parser.hx line 1016
Called from as3hx/Parser.hx line 1075
Called from as3hx/Parser.hx line 1179
Called from as3hx/Parser.hx line 330
Called from as3hx/Parser.hx line 1003
Uncaught exception - In C:/Users/MikeC/Desktop/as3hx/robotlegs2/src/robotlegs/bender/extensions/eventCommandMap/impl/Eve
ntCommandTrigger.as(75) : Unexpected .

[/codesyntax]

It seems like as3hx is getting confused around this line in the AS3 source:

[codesyntax lang="actionscript" lines="normal"]

if (describeType(mapping.commandClass).factory.method.(@name == "execute").length() == 0)
				throw new Error("Command Class must expose an execute method");

[/codesyntax]

It looks like a bit of E4X is confusing the script. To solve this sort of problem I made a note of the location and file and just commented the offending line out. This allows as3hx to get past that particular snag. After going through this process a few times the project should be fully converted.

From there I setup a project in FlashDevelop and tried to compile. After fixing a few things that as3hx couldnt solve I came accross a rather major stumbling block.

RobotLegs2 unlike RL1 has a strong dependency on the dependency injection container SwiftSuspenders. So to get RL to compile I first need to port SwiftSupenders2.

So I repeated the process above but for SwiftSuspenders. Eventually this left me with a whole load of broken unit tests. Till Schneidereit the (rather splendid) author of SwiftSuspenders wrote a great number of unit tests for the library, which is one of the reasons why its so excellent. So I knew that to achieve a proper port all I need do is pass all those tests and I can then be confident that the code is solid.

After a few evenings of toil I managed to get 50 tests to pass in the Flash target. This is quite abit shy of the 160+ tests in the original AS3 version of the library, however a great many of those tests are not relevant to Haxe such as ArrayCollection tests, XML tests and DescribeType tests. I also decided for now to remove all of the event dispatching (and thus their tests) code from the library for now due to their dependency on the Flash platform. Despite this I think the 50 tests that do pass are probably representative of the core functionality of the library.

With the Flash target passing I indented to then move onto passing the tests in the other targets (JS, C++, php etc). I was hoping that with the flash part passing that they would all pass considering that im using the inbuilt haxe reflection methods not any platform specific reflection, but alas this was not to be the case. Starting with the JS target I started to get alot of errors on some of the basic Injector tests. After some digging in the compiled JS source I traced it back to an issue in the Meta Data generation for the @Inject tag on the JS target.

Unfortunately, I have run out of time on this little side project for now so am going to have to park it. I have uploaded the progress thus far to GitHub should anyone else wish to take up the mantle on the port:

https://github.com/mikecann/SwiftSuspendersHx
https://github.com/mikecann/RobotLegs2Hx

I had indented, once everything was passing, was to do a branch of the project and incorporate some features that only the Haxe language can support. Features such as proper generics and macros would bring some added awesome.

AS3, Dictionary & Weak Method Closures

This is going to be a technical post so those of you not of the code persuasion look away now..

Okay great, now those guys have gone I can get down to it.

Some of my recent work on the SWFt project has revolved around the use of Robert Penners AS3Signals. If you dont know what Signals are I strongly reccomend that you check out Roberts blog for more info. In brief, they are an alternative to the Events system found in Flash, based on the Signal / Slot pattern of Qt and C# they are much faster and more elegant (my opinion) than native events.

I have been trying to incorporate signals in SWft for both the elegance and performance gains that they bring, however there is an issue that was brought to my attention by Shaun Smith on the mailing list. The issue is that my current use of them will cause memory leaks.

I realised that this too would apply to the work I had been doing using the RobotLegs and Signals libraries. RobotLegs (for those of you that dont know) is an excellent Dependency Injection framework inspired by the very popular PureMVC framework. I have blogged before about its excellence. Signals have been incorporated into RobotLegs as a separate ‘plugin’ by Joel Hooks in the form of the SignalCommandMap. The SignalCommandMap does as the name implies, it allows you to map signals to commands so that whenever a mapped signal is dispatched then the corresponding command is executed.

Its a very nice, elegant, solution to RIA development. However there is one catch. I have so far been using signals such as:

[codesyntax lang="actionscript3" lines="normal"]

public class MyMediator extends Mediator
{
	// View
	[Inject] public var view : MyView;

	// Signals
	[Inject] public var eventOccured : ViewEventOccuredSignal;
	[Inject] public var modelChanged : ModelChangedSignal;

	override public function onRegister():void
	{
		view.someSignal.add(eventOccured.dispatch);
		modelChanged.add(onModelChanged);
	}	

	protected function onModelChanged()
	{
		view.updateView();
	}
}

[/codesyntax]

So here we can see a typical use of Signals in a mediator. There are two things going on here that are of concern, lets break them down.

Firstly on line 12 we are listening to a signal on the view, then passing on the event directly to an app-level event, notice how nice and clean this is, this is what I love about using RL & Signals. Line 13 we are listening for an app-level signal for a change on the model then updating the view to reflect this.

It all looks well and good but unfortunately in its current state it could cause a memory leak. This is because we are listening to events on signals without then removing the listen. For example, we are listening to the app-level event on line 13 “modelChanged.add(onModelChanged);” so now the “modelChanged” signal has a reference to this Mediator. This will cause a leak when the View is removed from the display list. Normally the mediator would also be make available for garbage collection, however, because the singleton Signal has a reference to the Mediator it cannot be removed.

The same goes for line 12. Suppose the “ViewEventOccuredSignal” that is injected is not a singleton and is swapped out for another instance it could not be garbage collected as the “view.someSignal” has a reference to its dispatch function.

Realising this problem I knew that the solution was simply to be careful and add a “onRemoved” override function in my Mediator then clean up by removing the signal listeners. However I like the simplicity and beauty of current way of doing things so I started to wonder if there was another way.

I started thinking about whether I could use weak references with the Signal. If I could then I wouldnt have to worry about cleaning up as the Signal wouldnt store any hard-references to the functions and so the listener would be free for collection. After some digging however I realised that there was no option for weak listening in Robert Penners AS3Signals.

I thought to myself why the hell not? I knew that the Dictionary object in AS3 has an option to store its contents weakly so I thought so long as you don’t require order dependant execution of your listeners it should be possible to store the listener functions in a weakly referenced Dictionary.

It was at this point that I noticed Roberts post on the subject of weakly referenced Signals: http://flashblog.robertpenner.com/2009/09/as3-events-7-things-ive-learned-from.html. In it he references Grant Skinners post concerning a bug with storing functions in a weakly referenced Dictionary.

From Grant’s post:

Note that there is a known bug with Dictionary that prevents it from operating correctly with references to methods. It seems that Dictionary does not resolve the method reference properly, and uses the closure object (ie. the “behind the scenes” object that facilitates method closure by maintaining a reference back to the method and its scope) instead of the function as the key. This causes two problems: the reference is immediately available for collection in a weak Dictionary (because while the method is still referenced, the closure object is not), and it can create duplicate entries if you add the same method twice. This can cause some big problems for things like doLater queues.

This was starting to look bad for my idea. Me being me however, I thought I knew better, and that post was written pre Flash 10 so I thought to myself: perhaps its been fixed in Flash 10. So I set to work coding a simple example.

I created a very simple Signal dispatcher:

[codesyntax lang="actionscript3" lines="normal"]

package
{
	import flash.events.EventDispatcher;
	import flash.utils.Dictionary;

	public class SimpleDispatcher
	{
		protected var _listeners : Dictionary;

		public function SimpleDispatcher(useWeak:Boolean)
		{
			_listeners = new Dictionary(useWeak);
		}

		public function add(f:Function) : void
		{
			_listeners[f] = true;
		}

		public function dispatch() : void
		{
			for (var o:* in _listeners)
			{
				o();
			}
		}
	}
}

[/codesyntax]

And a very simple listening object:

[codesyntax lang="actionscript3" lines="normal"]

package
{
	public class SimpleListener
	{
		public function listen(d:SimpleDispatcher) : void
		{
			d.add(onPing);
		}

		protected function onPing() : void
		{
			trace(this+" - ping");
		}
	}
}

[/codesyntax]

And then a simple Application to hook it all together:

[codesyntax lang="mxml" lines="normal"]

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx">

	<fx:Script>
		<![CDATA[
			import mx.controls.List;

			protected var _dispatcher : SimpleDispatcher = new SimpleDispatcher(true);
			protected var _listener : SimpleListener;

			protected function onAddListenerClicked(event:MouseEvent):void
			{
				_listener = new SimpleListener();
				_listener.listen(_dispatcher);
			}	

			protected function onRunGCClicked(event:MouseEvent):void
			{
				try
				{
					new LocalConnection().connect('foo');
					new LocalConnection().connect('foo');
				}
				catch (e:*) {}
			}				

			protected function onDispatchClicked(event:MouseEvent):void
			{
				_dispatcher.dispatch();
			}		

		]]>
	</fx:Script>	

	<s:VGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
		<s:Button label="Add Listener" click="onAddListenerClicked(event)" />
		<s:Button label="Run GC" click="onRunGCClicked(event)" />
		<s:Button label="Dispatch" click="onDispatchClicked(event)" />
	</s:VGroup>

</s:Application>

[/codesyntax]

So what I should expect to see from this example is that when I click “Add Listener” it should create a listener reference which will then listen for when the signal is dispatched and trace out a “ping”.

What actually happens is you get nothing. No trace out, despite the fact that there is clearly still a reference to the listener in the Application file.

So whats happening here? If you break into the debugger at the point that the listener is added then you get the following:

You can see that the type “MethodClosure” is added as the key to the dictionary rather than Function which is passed in. MethodClosure is a special native Flash Type that you dont have access to. It exists to resolve the issues we used to have in AS2 where passing a function of a class to a listener would cause the listener to go out of scope and other nasties. From the Adobe docs:

Event handling is simplified in ActionScript 3.0 thanks to method closures, which provide built-in event delegation. In ActionScript 2.0, a closure would not remember what object instance it was extracted from, leading to unexpected behavior when the closure was invoked.

..

This class is no longer needed because in ActionScript 3.0, a method closure will be generated when someMethod is referenced. The method closure will automatically remember its original object instance.

The only problem is that it seems that using a MethodClosure as a key in a weak dictionary causes the MethodClosure to have no references and hence be free for garbage collection as soon as its added to the Dictionary which is not good :(

So thats about as far as I got, I have spent a few evenings on this one now and I think im about ready to call it quits. I had a few ideas about creating Delegate handlers to make functions very much in the same way as was done in AS2 but then I read this post: http://blog.betabong.com/2008/09/26/weak-method-closure/ and the subsequent comments and realised it probably wasnt going to work.

I also had an idea about using the only other method of holding weak references the EventDispatcher class. I thought perhaps somehow I could get it to hold the weak references then I could loop through the listeners in there calling dispatch manually. Despite “listeners” property showing up in the Flex debugger for an EventDispatcher you dont actually have access to that property unfortunately so hence cant get access to the listening functions. Interestingly however the EventDispatcher uses “WeakMethodClosure” object instead of the “MethodClosure” object according to the debugger.

Well I guess for now Ill have to make sure I code more carefully and unlisten from my Signals ;)