100 Posts! A retrospective and the best links from my blog.

TADAAAAA ! This post is the 100th blog post on my blog. Its been a fun ride so I figured I wrote a bit on the history of this blog as well as link to my favorite posts here.

Winning the People's choice award at Flash Forward, Austin, 2006
Part of the Comcast Interactive Media Flash Team at Flash Forward, Austin, 2006. The Fan 3.0 won the People’s Choice Award (which is voted for by people on the www and not a panel of judges). A lot has changed since then: The team has changed, Fan 4 is a 100% Flex app and I have longer hair ;).
My first post here was on July 19, 2006. That said, this was my second attempt at blogging, the first attempt was something on blogger, where I posted my opinions on Flash, but I got bored of that real quick as I hardly got any traffic. I started Code Zen with the basic assumption that I will get no traffic at all. I basically wanted a place to keep all the code I worked on and get back to it months later. This was around the time Flex 2 was coming out of beta, and I needed a place to host FlexAmp, my entry to the Flex developer contest (FlexAmp was featured on labs.adobe.com for quite a while and is still featured on the community sample apps section on Adobe.com).Of course once in a while the entries here would be purely opinion, like defending Flex when someone took cheap shots at it, but for the most part, I used this blog to document Flex techniques and gotchas or full blown components (list at the end of this). Some of the examples have even inspired greater work within the community. For example, SuperTabNavigator, one of the most used components on FlexLib, the open source Flex library that seems to be the one with the most traction right now was developed by Doug McCune on top example code on this blog (He of course packaged it into a complete component from the proof of concept I had here).

One of the most memorable moments was getting on the main page of Digg. I had been working on an implementation of a Treemap algorithm, and just to test it out, I used Digg api’s (undocumented at the time) to render the stories in the treemap. I posted the result here and the next morning I had had 904 diggs and comments by some big names including Kevin Lynch, CTO of Adobe and some folk from within Digg itself. The link to the now busted application is here and the Digg page is here. I later repackaged the DiggGraphr application as an AIR application and entered it for the Digg Api contest. I didnt win but I was in the final 10 so I got some Digg T shirts and stuff. The air application was even featured on TechCrunch, one of my favorite blogs.

Around a year or so ago, we adopted Flex as a framework here at Comcast Interactive Media for a lot of our applications. This was definitely big since Flex 2 had just been launched, but I had been working with it since Beta 1. So when I architected and developed the forth version of Comcast Interactive Media’s flagship video portal-esque application in Flex, I blogged about it here. That entry got picked up by some high profile blog as well, including Mashable, ZDNet and Cable 360. That entry also allowed me to strengthen the case for developer blogging within Comcast. That has come to fruition with the recently launched developer blogs at CIM including the Flash/Flex team’s blog here.

Continuing on the cultural revolution within CIM, we recently even started releasing code under some of the most permissive open source licenses. A few months back we released LogBook, an AIR application for logging events from Flex applications under the MIT license. The launch was announced on this blog as well. Ryan Stewart from Adobe blogged about it as well, which was kinda cool :).

Like I said, its been a fun 100, even if it did take me a year and a half ! I am still as passionate about Flash and Flex today as I was earlier if not more. My life of course has changed a bit in the meanwhile, so that may start getting reflected in the content here. I am getting really interested in Ruby and a little intrigued by Processing. Meanwhile, at CIM, my role is changing as I move towards a principal engineering position. That means I spend a lot more time coding these days which is cool ;).

Here is a list of some downloadable code from here:

ScrollImage Flex component: An implementation of ScrollPane for Flex that isn’t based on the Canvas container, making it a lot lighter and efficient.
ImageSlicer: A class for cutting any DisplayObject into a grid and grabbing slices out of it.
MP3Playback Package: A pure AS3 package for playing MP3 sound.: A class for loading content into Flash from WordPress based on XML-RPC.
AS3 WordPress class

TabNavigator with closable/draggable tabs: The FlexLib container has more functionality but this has an explanation and can be extended arbitrarily.

Fixed Treemap code coming soon. I released it earlier but its broke again, so I’ll release it once its fixed.

Thanks all for visiting :).

Flex development within teams: Using patches to update projects

Working in teams on Flex projects requires some discipline, something we at CIM are learning fast as our projects grow beyond individual developers. We have always used version control but traditionally, we have worked with open libraries that all developers had access to. Anyone could commit to the repositories and everyone checked out the latest code the first thing when they began work in the morning. As more and more developers checked code into our core library, the chances of it being in flux escalated. One idea I am now implementing is the concept of release management. Working with patches is one part of this. This idea is being used, for example, in the LogBook open source application that we released earlier last month (and was blogged about by Ryan Stewart as well).

So here is the situation: At no time should we allow untested code to enter LogBook. However, individual projects have features that they need to be built into LogBook. These features need to be committed back into the LogBook repository. Right now, to maintain code quality, I am the only developer that has commit access to LogBook. Developers can write their extensions to LogBook, usually after a conversation we have about the best way to implement this (the conversations all happen on the cimlogbook google group to maintain transparency). Once they have code working, they send me a patch file which I ensure works and doesn’t include hacks for the sake of a feature. Once the patch is confirmed to be good, I commit the patch to the repository.

Working with patches is a new thing for me and I just wanted to blog about this quick. Working within Flex Builder 3 and with the Subclipse plugin installed, creating patches is as easy as right clicking on the source project and selecting Team > Create Patch … .This creates a patch file that basically documents the difference between the committed project and the user’s local files. The developer then sends me the patch file.
Patch Menu on Subclipse

There is a bug in Subclipse that puts absolute paths to local files rather than relative paths and since a developers local file paths may not be the same as mine, we cannot use Subclipse’s apply patch feature out of the box. To apply the patch, making sure I have no local changes in the project, I navigate to the project within my filesystem using the terminal. Once there, I apply the patch by typing

patch -pNumber-of-directories-to-get-to-project < path-to-patch-file

the -pNumber-of-directories-to-get-to-project parameter is basically to remove the folder references to the project directory in the patch file. So for example, if you open a patch file and the first line references the project root as

/Users/comcast/Documents/workspace/cimlogbook/src/LogBook.mxml

you would use -p6 . This removes the /Users/comcast/Documents/workspace/ reference. Once the patch is applied, refresh your project within Flex Builder and you will get the uncommitted changes icon on the changed files/folders. You can synchronize with the repository to see what changed, build the application to make sure it compiles, and then if everything looks good, commit the code to the version control system.

Special thanks to Mat Schaffer for getting me working with patches. I really like this way of committing code since it makes me feel a lot more confident around the libraries I am supposed to be responsible for.

UPDATE:
Another useful tip: Use SVN to generate change logs that can then be published, example:

svn log --revision 217:239 -v

Can PicLens be done in just Flash and Papervision3d ? Here ya go !

PicLens has been one of the new interfaces that has wowed quite a bit of people I know (including myself). But the application is written in native code and needs to be installed on your computer as a plugin to be usable. Off late I have been playing with Papervision3D a bit and I figured it was possible to kind of get the functionality just by using that. Here is the result of my experiments so far. (warning: this demo requires a good internet connection since I am loading a lot of images)

Update: Uploaded a video for users on poorer connections:

Click on the input text field, enter a search term and hit enter:

The code is built on top of the Paged – data classes I had talked about in my last post. So basically new photos are loaded from Flickr as you reach the edge of the currently loaded data set. The code is pretty awful right now since I had to revisit my basic algorithm a couple of times so if you scroll around quite a bit, it may begin to spike your memory or act all weird. I need to implement some recycling of renderers strategy which seems to be advised strongly for such applications. Also I am not completely happy with the tilting algorithm I have right now (to get it really right I need to change the algorithm to do a little more math, right now the transition from tilt to normal is a little jarring). Ah well, that happens later. Right now, I am just stoked this works :).

Photowall: Scroll based data prefetch

Photowall is part 1 of a secret project I am working on (secret only since I am not sure part 2 will work, so I’d rather not declare yet what its about 😉 ). This component on its own is an exercise in data-prefetch. The idea is to load data as the user scrolls to the end of the current set rather than ask the user to click on a “more photos” link. In this case, the component is feeding off Flickr data.

Type in a search word inside the text input and hit enter. Once the first set of data has loaded in, use the scrubber below the photos to scrub through the photos. Note: Data prefetch is triggered on mouse-up rather than mouse-move, I need to implement that in the final version.

/blog/swf/Photowall.swf

Under the hood, I have a class called PagedDataService that computes which page of the remote data the user is on (Flickr apis support paged data, with each call out asking for a certain number of photos and a page offset, so page 1 has 0 to 1 x pagesize photos, page has 2 x pagesize, etc. Right now my pagesize is 60. ). The code also uses a PagePolicy class that the container looks at to see when the more data should be fetched. For example, in this case, I have asked the container to get more photos when the user is about 18 photos (6 columns) away from the last photo in the set.

There is no optimization of the code here yet, so I am not managing the photo renderers that aren’t visible to the user (which would free up memory). Another optimization would be to reuse renderers rather than create new ones like I do for every photo. Finally, a priority queue for the load requests would be great here.

So much for part 1, on to part 2. Stay tuned :).

LogBook 1.2.1 available for download.

LogBook 1.2.1 patch release is now available on googlecode now. The release addresses quite a few bugs and feature requests. The list of patches can be found here.
We are also discussing features for LogBook 1.3 at the Google group for the project. If you have a feature you would like to see added or contribute, join the conversation here. Like Mat said in a previous thread there, the importance of a feature is only as much as the conversation around it.

There are some interesting discussions I have had around LogBook with a couple of folk within Comcast Interactive Media where I work. For example, one of the things we have had to deal with is QA bugs that we cannot reproduce. Running LogBook in the background on QA machines and looking at the logs generated would be an interesting idea to implement, thus making LogBook a part of the QA cycle. The biggest thing that needs is a notion of a session in LogBook which is something we dont have right now. I guess that could be a part of 1.3 or 1.4. Other ideas are welcome.

If you have any code around debugging Flex applications that you would like to contribute to LogBook, do let me know as well.

Links:
Download LogBook 1.2.1
LogBook on Googlecode

Flex optimization tip: ArrayCollection.removeAll() vs. ArrayCollection.source = new Array(). Is this a bug ?

One of the bugs reported on our recently released LogBook application was around the “Clear Logs” button. Within LogBook, we keep all the LogMessage messages in an ArrayCollection. When Clear Logs was clicked, we called a removeAll() function to clear the ArrayCollection. However when the size of the ArrayCollection grew more than a hundred or so, the clear command took a while and the whole application would freeze for a few seconds. A quick change of that to ArrayCollection.source = new Array() fixed the performance immediately. Interesting.
Looking deeper into the removeAll function and following the hierarchy to the ArrayList class, I saw that the removeAll loops through the entire source array, looking at each member to see if its an event dispatcher and if so calling a function to remove the propertyChange listener. Confused a bit, I posted a message on flexcoders to see why this was the case. Alex Harui from Adobe resonded with this:

Our code has to look like that otherwise if someone kept a reference to one of the objects that got removed, it would keep the ArrayList from being GC’d. We added listeners, so we should remove them. If the data objects are going away too, then you can probably reset the source, but if you see a memory leak later, I’d definitely check in that area.

Makes sense, but only kind of since the way the eventlistener was added was with the weak keys flag turned on, which means that I did reset the array, even if the old LogMessage objects were in memory, the garbage collector could still get rid of them whenever it ran. So I responded to Alex so:

Hmm, maybe I am missing something here? The only place I see addEventListener being called is

protected function startTrackUpdates(item:Object):void
{
if (item && (item is IEventDispatcher))
{
IEventDispatcher(item).addEventListener(
PropertyChangeEvent.PROPERTY_CHANGE,
itemUpdateHandler, false, 0, true);
}
}

which has the weak-keys boolean flag turned on. Shouldnt that allow garbage collection to run without explicitly calling removeEventListener ?

And Alex’s response:

Because of the way GC works, I still think it is best for us to remove the listeners. GC is only on allocation so again, if someone had a handle to an object that got removed and twiddled a value, the notification code would run needlessly until GC kicked in.

However, I think you’ve come up with a great optimization for folks who know they are destroying everything all at once.

So the final verdict: If you are destroying all the objects within the Arraycollection, use ArrayCollection.source = new Array() instead of ArrayCollection.removeAll(). Calling removeAll() on large ArrayCollections seems to be a really heavy operation and could kill responsiveness of the app.

I do feel that this is a bug and not a simple optimization. Here is the final email I sent to flexcoders a couple of minutes back:

Hi Alex,

Thanks for responding. Should this be tracked as a bug? I think there may be a better way of handling this:

On removeAll() you can set a flag like removeEventListenersPending = true, copy the old elements to a temporary new array and run through the it in smaller sized increments (removing event listeners from say 40 objects every enterframe using something like calllater). In the meanwhile if a property change event is fired, you can see if the flag is set and if so make sure the item is in the current source array and not the temp array. When all objects in the temp have had their event listeners removed, set the removeEventListenersPending = false.

I think the current implementation may be causing a lot of performace issues since a lot of people may be using ArrayCollections for large data sets (thats what Flex is great for 🙂 ) and may not know of the penalty of the removeAll().

If anyone has any opinions, please feel free to comment. Okay, back to real work :).

Released: LogBook, An Open Source AIR based Flex Logging Application

126399-logbook_1_4_0_1_alpha_development_other

As promised, today we are formally releasing LogBook, our internally developed tool for logging events from Flex (and coming very soon, pure Flash AS2/AS3) applications. For the uninitiated, logging is the process of recording and storing information about events in your application. The functionality is similar to the trace command, but a lot more robust. Logging combined with a strong log viewer like LogBook gives you a much deeper understanding of the state of your application.

Some quick notes on LogBook:

1) LogBook is being released under the MIT open source license.
2) A detailed post on its features and how to use it is here at the CIM Flash Team Blog.
3) The code for LogBook is being hosted at http://cimlogbook.googlecode.com/.
4) We have also set up a Google group for logbook that we can use to discuss features that we should add in upcoming releases and bugfixes/patches.
5) The installer can be found in the downloads section there.
6) LogBook runs on the AIR beta 3 runtime.

At CIM we already have a list of features we are going to release in the next build. But of course if you have any feature you would like to request, please drop us a mail at cimlogbook@googlegroups.com. We are really hoping LogBook 1.2 is the first step towards a robust Flex/Flash development/debugging toolset.

Happy debugging :).

Releasing tomorrow: LogBook, an open source AIR based Flex logging application

The team at Comcast Interactive Media is putting the final touches to an internally developed tool we use for logging events from Flex applications. The application is built on top of the Flex framework and runs as an installable AIR application. Best of all, we will be releasing it under the MIT open source license. A much more detailed blog entry about logbook’s features will be published soon but here is a quick screengrab of the application (click to open in a new window):

Stay tuned ;).

Update: LogBook has been released and can now be downloaded at http://code.google.com/p/cimlogbook/

E4X parsing caveat: Watchout for the Firefox-hidden Namespaces

A friend of mine was having issues with parsing an xml file using E4X today. We were trying parsing an XML file generated by a webservice and for all he tried, the nodes were completely inaccessible to his code. Viewing the XML in Firefox didn’t give any clues and everything should have worked. I have debugged exactly the same thing before so I was able to help but since I have seen developers do this more than a couple of times, I thought I should mention this: Loading an XML file within Firefox hides all Namespace declarations. To actually see the document as its coming in, view source on the document and all namespaces will be seen there.
The document he was parsing turned out to have a default namespace declaration in the root tag which means all the nodes were in that Namespace. The root tag of the xml document looked like:

[xml]

[/xml]
Here is the code to actually parse such a document:

[AS]
var u:URLLoader = new URLLoader();
u.addEventListener(Event.COMPLETE, onLoadComplete);
u.load(new URLRequest(“document.xml”));

function onLoadComplete(event:Event):void{
XML.ignoreWhitespace = true;
var x:XML = XML(event.target.data);
var ns = x.namespace();
trace(“node value: “+x.ns::node1.ns::node2);
}
[/AS]

Note the ‘ns:: … ‘ prefix to the node-names you are trying to reach.

Hope this helps :).

More links on E4X and Flash:
Referencing ActionScript Reserved Words in E4X
Parse a document with namespaced nodes and a variable to be evaluated