AS3, Dictionary & Weak Method Closures

August 16, 2010 – 7:44 pm | by admin

Tags: , , , , , ,

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:

  1. public class MyMediator extends Mediator
  2. {
  3. // View
  4. [Inject] public var view : MyView;
  5.  
  6. // Signals
  7. [Inject] public var eventOccured : ViewEventOccuredSignal;
  8. [Inject] public var modelChanged : ModelChangedSignal;
  9.  
  10. override public function onRegister():void
  11. {
  12. view.someSignal.add(eventOccured.dispatch);
  13. modelChanged.add(onModelChanged);
  14. }
  15.  
  16. protected function onModelChanged()
  17. {
  18. view.updateView();
  19. }
  20. }

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:

  1. package
  2. {
  3. import flash.events.EventDispatcher;
  4. import flash.utils.Dictionary;
  5.  
  6. public class SimpleDispatcher
  7. {
  8. protected var _listeners : Dictionary;
  9.  
  10. public function SimpleDispatcher(useWeak:Boolean)
  11. {
  12. _listeners = new Dictionary(useWeak);
  13. }
  14.  
  15. public function add(f:Function) : void
  16. {
  17. _listeners[f] = true;
  18. }
  19.  
  20. public function dispatch() : void
  21. {
  22. for (var o:* in _listeners)
  23. {
  24. o();
  25. }
  26. }
  27. }
  28. }

And a very simple listening object:

  1. package
  2. {
  3. public class SimpleListener
  4. {
  5. public function listen(d:SimpleDispatcher) : void
  6. {
  7. d.add(onPing);
  8. }
  9.  
  10. protected function onPing() : void
  11. {
  12. trace(this+" - ping");
  13. }
  14. }
  15. }

And then a simple Application to hook it all together:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
  3. xmlns:s="library://ns.adobe.com/flex/spark"
  4. xmlns:mx="library://ns.adobe.com/flex/mx">
  5.  
  6. <fx:Script>
  7. <![CDATA[
  8. import mx.controls.List;
  9.  
  10. protected var _dispatcher : SimpleDispatcher = new SimpleDispatcher(true);
  11. protected var _listener : SimpleListener;
  12.  
  13. protected function onAddListenerClicked(event:MouseEvent):void
  14. {
  15. _listener = new SimpleListener();
  16. _listener.listen(_dispatcher);
  17. }
  18.  
  19. protected function onRunGCClicked(event:MouseEvent):void
  20. {
  21. try
  22. {
  23. new LocalConnection().connect('foo');
  24. new LocalConnection().connect('foo');
  25. }
  26. catch (e:*) {}
  27. }
  28.  
  29. protected function onDispatchClicked(event:MouseEvent):void
  30. {
  31. _dispatcher.dispatch();
  32. }
  33.  
  34. ]]>
  35. </fx:Script>
  36.  
  37. <s:VGroup width="100%" height="100%" horizontalAlign="center" verticalAlign="middle">
  38. <s:Button label="Add Listener" click="onAddListenerClicked(event)" />
  39. <s:Button label="Run GC" click="onRunGCClicked(event)" />
  40. <s:Button label="Dispatch" click="onDispatchClicked(event)" />
  41. </s:VGroup>
  42.  
  43. </s:Application>

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 ;)

Shader Based 2D Shadowing

August 15, 2010 – 11:10 am | by admin

Tags: , , , , , , ,

Those who know me know I used to do quite abit of development in c# using Microsoft’s XNA platform.

Well I like to check back in every now and then with some of the big players in the community to see what’s going on.

One of those players is Catalin Zima, who is famous for producing many great shader and effect samples.

One of Catalin’s reccent project particularly caught my eye however as I had tried to tackle the same problem several years ago when I was in my final year of university. That is, Dynamic 2D Shadows Calculated on the GPU (http://mikecann.co.uk/university-projects/shadowshader-in-rendermonkey/)

Catalin’s approach to the problem is far more elegant that my brute force iterative approach. He uses a clever technique of distorting the desired casting image about the light in such a way as not to require iterative pixel lookups.

If you are interested in the more details in the technique I encourage you to check it out over on Catalin’s blog: http://www.catalinzima.com/2010/07/my-technique-for-the-shader-based-dynamic-2d-shadows/

Assembly 2010 – CNCD & Fairlight Demo

August 9, 2010 – 5:08 pm | by admin

Tags: , , , , , , , , , , ,

It was the massive annual Assembly gathering last week. Traditionally its a place for the demo scene to gather and present their demos and to hack out new ones.

For those not in the know the demo scene or “scene” is where a team of people come together and compete to make a music video. Except that they arent videos in the traditional sense as its all generated using code and runs in realtime. This means that you have to be super efficient with your code. Some of the competitions are “64k” or even “4k” competitions which means that the whole demo must fit in 64kb or 4kb! The music is also produced by the groups and often excellent.

I have been checking out some of the demos produced by the teams this year and they are simply stunning. Every year they get better and better.

This one from CNCD and Fairlight particularly caught my eye as it has massive numbers of particles and a stunning soundtrack kinda reminiscent of glitchy Radiohead. Therefore I thought it essential I share it here.

Enjoy:

Oh while im at it check out this one from last year:

If you are interested in more demos from assembly you can get them all here: http://scene.org/newfiles.php?dayint=7&dir=/parties/2010/assembly10/

Oh I have also posted about the demoscene before here: http://mikecann.co.uk/art/andromeda-software-development-lifeforce-2007/

A Few Site Changes

August 6, 2010 – 9:55 pm | by admin

Tags: , , ,

As im not out tonight I thought I would do a little work on the site.

I have been meaning to add the retweet and facebook buttons for ages. I have also updates the flash header to make it a little prettier :)

What d’you think?

Gourmet Ranch

August 4, 2010 – 11:57 am | by admin

Tags: , , , , ,

I cant believe I haven’t talked about this yet.

I spoke about 6 months ago about joining a new startup called Playdemic as the Lead Flash Developer. I couldn’t say much at the time as we were in stealth mode. As our first product has been out for about a month however, I think its about time I wrote a blog post on the subject.

Gourmet Ranch is Flash game for face book that follows closely on the heels of the other Facebook game successes such as Farmville and Cafeworld. The premise is simple, you grow crops and animals in your fields and then when the time comes you harvest them and use them to bake recipes. Those recipes are then served to your waiting customers by your waiters.

As the lead flash dev on the project its my responsibility to code all the engine and game play elements. Despite my several years worth of experience with flash games this was a challenging project . Making a game that is a multiplayer game but not a multiplayer game (no client pushing) is definately not for the feint of heart.

Despite the challenges and the occasional heated moment during development I think the product we have produced is excellent and is superior to many of the similar games available on Facebook. The stats for the first month of the game are impressive as can be seen from the data gleamed from AppData.

The main challenge now is to continue the early growth we have seen and retain the existing users we have won. So that means players of the game should be looking forward to regular updates with new content and bug fixing :)

Anyways if you wanna check it out head over to facebook –> http://apps.facebook.com/gourmetranch/


Flex 4 Spark & Rollover Group Containing Rect

August 2, 2010 – 8:25 am | by admin

Tags: , , , , , , , ,

Was working on my top-secret Flex-based project over the weekend when I discovered something I hadn’t come across before.

The issue is that when you have a Spark Rect GraphicsElement within a Spark Group it seems that the rollover event of the group is triggered even though the mouse doesn’t roll over the Rect.

Here is a video I made to explain my issue on Twitter:

The code in the video is as follows:

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"> 
 
	<s:Group rollOver="trace('ya')">
		<s:Rect x="100" y="100" width="20" height="20">
			<s:fill>
				<s:SolidColor color="0x00ff00" />
			</s:fill>
		</s:Rect>
	</s:Group> 
 
</s:WindowedApplication>

It turns out (after posting the issue on the Adobe Forums) that I was simply missing the “mouseEnabledWhereTransparent” property on the Group. Setting it to false causes the mouse to perform a hit-test rather than a simple bounds check. Thank you Mr Shongrunden for pointing this out to me :)

So this now works:

<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
   xmlns:s="library://ns.adobe.com/flex/spark"
   xmlns:mx="library://ns.adobe.com/flex/mx"> 
 
	<s:Group rollOver="trace('ya')" mouseEnabledWhereTransparent="false">
		<s:Rect x="100" y="100" width="20" height="20">
			<s:fill>
				<s:SolidColor color="0x00ff00" />
			</s:fill>
		</s:Rect>
	</s:Group> 
 
</s:WindowedApplication>

I hope this helps someone else out!

Exploring The World of Lucid Dreaming

August 1, 2010 – 1:27 pm | by admin

Tags: , , , ,

Im not too sure if I have spoken before about Lucid Dreaming. I was interested in the concept several years ago when I first heard about it and then by accidentally managed to do it once while on holiday. It was an incredible experience and ever since the concept of consciously influencing your dreaming state has fascinated me.

I read about this book in New Scientist so added it to my Amazon wish-list for next time I buy some books. I have only just gotten round to begin reading it.

Its basically a how-to guide to Lucid Dreaming and seems very well written and has had many excellent reviews. One of the very first techniques the book suggests is to keep a “dream journal”, a diary of your dreams so that can start to recognise patterns and signs in the dreams allowing your concious to detect when you are dreaming and wake you up.

So thats what im going to be doing for the next few weeks, keeping a diary of my dreams. Im thinking it should make for a rather interesting experience ;)

Oh BTW, no this isnt a knee-jerk reaction to Inception (which I went to watch last week and is a terrible film IMO), I had book ordered before I had heard of Inception, just coincidence.

Defcon 2010 – Hacker Intercepts GSM

August 1, 2010 – 9:58 am | by admin

Tags: , , , , , ,

I know I have been posting alot of videos lately but this one caught my eye for a couple of reasons this morning.

Firstly its an impressive video showing how easy it is to intercept 80% of the worlds calls with just $1,500 worth of equipment. Also the source article over on Venture Beat says that he can also jam a band preventing calls just as easily which is quite scary.

The second reason why this video caught my eye is it appears that this brit-hacker is wearing high-heels throughout his presentation, check it out:

Starcraft II & TDs

July 27, 2010 – 8:11 am | by admin

Tags: , , , , , ,

I, like many others have been eagerly anticipating the latest Blizzard release Starcraft 2. I have been looking forward to the game but more importantly I have been eagerly anticipating the custom maps from the community.

I used to spend hours and hours playing the custom maps released with Warcraft III, I still log in every now and then to check out how its going and am suprised every time to see people still making new maps. Some of the most popular game genres in existence today wouldn’t be around if it wasnt thanks to be map making community in WC3. Genres such as Tower Defence (TD) and Defence of The Ancients (DOTA) were born there.

So it made me extremely happy to see this video on YouTube showing that yes custom maps are possible in SC2 and yes you can make TDs with them, horaay!

The Fifth Element Fan? Watch This!

July 26, 2010 – 12:35 pm | by admin

Tags: , , , ,

Its no secret that im a sci-fi fan and The Fifth Element is my favourite film. Watched it again in epic 1080p BluRay quality last night. Went poking about on Youtube afterwards and found this little gem:

I didnt even know it was possible to reach notes like that let alone move between them so quickly.