LogBook 1.2.1 available for download. 0

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

Gears Of War 2 trailer on the gameinvasion blog! 0

I am drooling already…Check it out here.

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

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 1

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 6

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 2

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:
  1. <response status="0" xmlns="some:ns:declaration">

Here is the code to actually parse such a document:

Actionscript:
  1. var u:URLLoader = new URLLoader();
  2. u.addEventListener(Event.COMPLETE, onLoadComplete);
  3. u.load(new URLRequest("document.xml"));
  4.                                   
  5. function onLoadComplete(event:Event):void{
  6.     XML.ignoreWhitespace = true;
  7.     var x:XML = XML(event.target.data);
  8.     var ns = x.namespace();
  9.     trace("node value: "+x.ns::node1.ns::node2);
  10. }

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