Introducing the XMLLoader class

 

I started the XMLLoader class a few months back, but didn’t post right away because it needed a lot of cleanup. Not cleanup in the sense of performance improvement or refactoring—it simply used my old programming style, full of dollar signs and underscores. If anyone remembers seeing my code in that form, I deeply apologize for the pain it must have caused your eyes.

So why an XMLLoader class?—because 99% of the data I load with AS3/AIR is in XML format. I stay far from JSON when possible because in AS3 it’s slower than a slug on its day off. XML is native and uses E4X, which lets developers navigate its information just like you would an AS3 tree. I load XML so often, I found myself copying and pasting the same code each time I’d need it—this is the clearest indicator that a class must be written.

Parsing String data to XML poses an issue that many don’t know about. I only discovered it because of the Twitter API. The API is so janked, it sometimes returns the HTML error page instead of the XML response. It wouldn’t be so bad if it weren’t for an image tag in the HTML that isn’t closed. This immediately throws an “XML parser failure: element is malformed” error. Using try/catch is the only way to avoid this. That’s why I wrote it into XMLLoader. It automatically handles the data, attempts to parse it, and, if there are any errors, the load stops and dispatches an error signal.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package {
	import com.destroytoday.net.XMLLoader;
 
	import flash.display.Sprite;
 
	public class Test extends Sprite {
		public var loader:XMLLoader;
 
		public function Test() {
			loader = new XMLLoader();
 
			loader.retryCount = 2;
			loader.includeResponseInfo = true;
 
			loader.openSignal.add(loaderOpenHandler);
			loader.completeSignal.add(loaderCompleteHandler);
			loader.errorSignal.add(loaderErrorHandler);
 
			loader.load("http://search.twitter.com/search.atom?q=destroytoday");
		}
 
		protected function loaderOpenHandler(loader:XMLLoader):void {
			trace(loader);
		}
 
		protected function loaderCompleteHandler(loader:XMLLoader, data:XML):void {
			trace(loader, data);
		}
 
		protected function loaderErrorHandler(loader:XMLLoader, error:String, message:String):void {
			trace(loader, error, message);
			trace(loader.responseStatus);
		}
	}
}

Speaking of signals, XMLLoader is the first class in DestroyFramework to use Robert Penner’s AS3 Signals instead of events. If you have to ask why, you haven’t been programming in AS3 long enough. Each XMLLoader instance has signals for open, complete, error, and cancel. The class also includes a retryCount property that indicates how many times to attempt to load a URL before calling it quits. Since some APIs can be down one second, then up the next, this feature really comes in handy. It’s mainly intended for handling the beloved fail whale.

The last two features include a cancel method and an includeResponseInfo property. Sure, URLLoader has a cancel method, close, but an exception is thrown if you call close when no operation is in progress. This makes sense, but the runtime shouldn’t close down shop when it happens. XMLLoader instead cancels and dispatches the cancel signal when the cancel method is called, and if no operations are in progress, it simply does nothing.

The includeResponseInfo property is an incredibly easy way to tell the loader to return the response status code and headers upon success or fail. Without XMLLoader, you could get this information with an event listener and the appropriate handler, but it’s far easier to flick a switch. In all honesty, I’ve neglected to retrieve this info using URLLoader in the past simply because it’s such a verbose process. Now that it only requires setting the property to true, I know I’ll use it more often than not.

As always, the source code is available on GitHub. Be sure to keep watch—my account will be pretty active these next few weeks.

‘Undocumented feature’ in Rob Penner’s AS3 Signals

 

bug_feature

Last week, I started replacing events in DestroyFramework with Rob Penner’s AS3 Signals. They’re faster, shorter, and include a few methods that developers have been dying for. Unfortunately, the first implementation, into my new Group class, didn’t work. I was puzzled to say the least. After literally hours of testing and debugging, I discovered the culprit.

It turns out, the remove(listener) method lacks a check for listener existence in the listeners array. When the method is called, if the index of the listener returns -1, the array splices the first listener. I forked the Git repository and implemented the fix on the Signal, NativeSignal, and DeluxeSignal classes. And because a fix isn’t a fix without proper unit testing (says Joel Hooks), I added the unit tests as well.

Getting back into the swing of things

 

It’s been a solid 17 days since I started Destroy Everyday—the creation-a-day mini blog aimed to balance my life between coding and off-the-computer mediums. So far, it’s been a success, meaning I have yet to miss a day. It’s been such a personal success that I’ve somewhat neglected the mothership—Destroy Today. Now that I have a solid routine down for the new year, it’s time to get back to business and stay active across the board.

I have a number of new DestroyFramework classes ready to document and check-in over the next few days. I plan to get back into sharing interesting and useful things I come across, regarding both programming and design. And, now that I’ve been introduced to MVC(S) and RobotLegs, I have a lot more to talk about—expect a tutorial in the near future.

To add some imagery to this post, below is yesterday’s Destroy Everyday post featuring Andy Mangold. I also included a detail shot because the web-sized image really doesn’t do it justice.

andy

andy_detail

2010 is destroyeveryday.com

 

destroyeveryday.com

It’s the new year and the best day to start anything. In my search for a hobby off the computer, I compromised and found a semi-off-the-computer challenge. Jen led me to the “Make Something Cool Every Day” concept. It’s a great motivation to consistently produce work while strengthening creativity. The best example I’ve seen yet is Brock Davis’s portfolio on Behance. Surely, I don’t expect to think up ideas as original as his, but I plan to use this as a stimulus to return to photography, print, and any other physical mediums I’ve neglected over the years.

The daily creations will reside on destroyeveryday.com as a Tumblr blog. The service provides a dozen different ways to post content, so “I didn’t have access to a computer” won’t be an excuse for missing a day—believe it or not, you can post content via a 1-800 number. Here’s to the new year and the beginning of a new venture.

Where to find the right fontName

 

To preface, I embed fonts using the Embed metatag and fontName parameter with an SWF as the source. If you’re unfamiliar with this method, it looks like this:

1
2
[Embed(source="assets/fonts.swf", fontName="Helvetica")]
protected static const HELVETICA:String;

This past week, I came across the same issue twice. Up until now, I only worked with fonts that used the fontName as it appears in Flash’s properties panel. Sure, this works for fonts with simple names, but when you start getting fancy, things get messy. I needed to embed Alternate Gothic No. 2 and Flash labeled it as “AlternateGothic” with “No2″ as the style. I set the fontName as “AlternateGothic No2″ and was presented with this familiar gem:

fontname_error

I get shivers each time I see it. After a few minutes of failed guess and check, I set out for a solution. I opened FontExplorer X and discovered that the font is labeled as “AlternateGothic-No2″.I gave it a shot and boom went the dynamite. From then on, I thought that would be the correct fontName—the font’s label in Font Explorer X.

fontname_fontexplorer

I was wrong. This week, I needed to embed Helvetica Neue Roman, which is labeled as “12 pt Helvetica* 55 Roman 05472″ in FontExplorer X—freaky, eh? I tried it out and the error returned. At first, I was bummed because I thought I had a foolproof solution. I was close, but no cigar. I opened Font Book to get a second opinion. Apparently, the font’s true name is “12 pt Helvetica* 55 Roman 05472″, which means FontExplorer X removes redundant whitespace, found in our example between “Roman” and “05472.” I tried it out and, sweet sassy molassy, it worked.

fontname_fontbook

From now on, I’ll consult Font Book when embedding a new font.

Merry Christmas!

 

merrychristmas

Correcting the Canon 5D MKII’s awful audio input

 

Following my last post on the DIY steadycam, I decided to improve upon the second downside of shooting video with the 5D—its audio input. The built-in microphone is completely unusable, adding a grinding noise to every video. I tried using an external mic with the 5D’s input port, but the audio was just as bad because the 5D still controls the levels.

My brother, Ben, is pretty big into audio. He has the Zoom H4, a portable recorder that provides true x/y stereo recording. I looked into it and found that Zoom upgraded it with the H4n. I took the plunge, but also purchased a hot shoe adapter with 3/8″ male thread so it could sit atop the 5D.

When picking up a quick release for the steadycam, I also got one for the recorder. Now, everything is set. Video is captured with the 5D, audio recorded with the H4n, and I have a big smile on my face.

h4n_0

h4n_1

DIY steadycam for under $20

 

Yesterday, I set out to revisit my building days with a DIY project. After finding my high school films, I felt compelled to utilize the video aspect of my Canon 5D MKII. It’s brilliant for capturing HD video, but if your lens doesn’t have image stabilization and your grip isn’t rock solid, it might look like you’re always shooting during an earthquake.

A while back, I stumbled upon Johnny Chung Lee’s tutorial on building a $14 steadycam, “The Poor Man’s Steadicam.”  A father/son trip to Home Depot and 20 minutes later, I had a steadycam that worked beautifully. I did come across an issue or two.

If you ever plan to use your camera/camcorder off the steadycam, a quick release system is a necessity. For a solid and reliable quick release, look no further than the Manfrotto 323 RC2 System. At just under $30, it defeats the claim of a steadycam under $20, but I’d gladly pay extra to know my camera is safe, sitting on a reliable system. The standard tripod thread size is 3/8″, but the 323 RC2 comes with a 1/4″ reducer bushing, making it compatible with Lee’s specs.

I’m happy with the steadycam for now, but I certainly see a few mods in the near future. Top on the list is rubber grips. Holding the steadycam for a minute leaves your hands smelling like galvanized steel for the rest of the day. And if you have any plans to shoot in cold weather, these pipes will freeze faster than a Jack Rabbit on a hot date.

This project has gotten me back into the building spirit and it was just what I needed to fill my free time away from the computer.

steadicam_0

steadicam_1

Introducing the AsyncLoop class

 

Out of my recent work, I’m especially proud of and excited about the AsyncLoop class. It’s a serious performance enhancer that takes heavy processes and spreads them out over time, preventing stalls and possible lockups. I originally wrote it to deal with a for loop that contained a complex process and iterated 1000 times. Needless to say, the beach ball made an extended stay each time the loop ran. After implementing AsyncLoop, the beach ball disappeared and animations played smooth throughout.

AsyncLoop works around a timer limit. The developer sets the maximum number of milliseconds to loop through the process function. Once the timer exceeds that limit, it carries over to the next frame and repeats. The loop can be ended a number of ways, providing great flexibility. A limit can be placed on the loop count, mimicking common for loop usage. The loop can return the AsyncLoopAction.BREAK constant. When using that method, AsyncLoopAction.CONTINUE is used to tell the loop to continue to the next tick. Each loop provides analytics, keeping track of its duration, loop count, and frame count. Here are two ways you can use it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// new AsyncLoop(callback:Function, countLimit:int = -1, timerLimit:int = 20);
var loop:AsyncLoop = new AsyncLoop(tick, 1000);
 
loop.addEventListener(Event.OPEN, loopOpenHandler);
loop.addEventListener(Event.CHANGE, loopChangeHandler);
loop.addEventListener(Event.COMPLETE, loopCompleteHandler);
 
loop.start();
 
function tick():void {
	// heavy process
}
 
function loopOpenHandler(event:Event):void {
	// loop started
}
function loopChangeHandler(event:Event):void {
	// loop carries over to next frame
 
	trace(loop.duration); // incomplete loop running time
	trace(loop.currentCount); // number of callback calls
}
function loopCompleteHandler(event:Event):void {
	// loop complete
 
	trace(loop.duration); // completed loop duration
	trace(loop.frameCount); // frames needed to complete
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var loop:AsyncLoop = new AsyncLoop(tick);
 
loop.start();
 
stage.addEventListener(MouseEvent.CLICK, clickHandler);
stage.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
 
function tick():String {
	// heavy process
 
	if (loopShouldEnd) {
		return AsyncLoopAction.BREAK;
	}
 
	return AsyncLoopAction.CONTINUE;
}
 
function clickHandler(event:MouseEvent):void {
	if (loop.running) {
		loop.pause();
	} else {
		loop.start();
	}
}
function doubleClickHandler(event:MouseEvent):void {
	loop.cancel();
}

I’m really happy with the class and how far it has come since its original form as fLoop. As always, the source code is on GitHub, so take it and run! If you find it useful, feel free to share how you used it, or simply let me know what you think.

Introducing the ApplicationUtil class

 

Yesterday, during my weekly football “service”, I spent a few minutes starting the ApplicationUtil class. So far, it consists of only two methods, getVersion and closeOpenWindows. The first accesses the application descriptor and returns the application’s version. closeOpenWindows is a necessity I learned in the Apollo days from Christian Cantrell. I had issues with my first AIR app, DestroyFlickr, where it wouldn’t quit, even if all of the visible windows were closed. I commonly use window visibility to show/hide utility windows, so the invisible ones were hanging around, keeping the app open. This method runs a quick loop to close all open windows, visible or not. It also includes an andQuit argument that, when true, sets autoExit to true, which quits the app upon close of the windows. Here’s some unnecessary example code to give this post more character:

1
2
3
4
5
6
7
8
9
10
var version:String = ApplicationUtil.getVersion();
trace(version); // v1
 
trace(NativeApplication.nativeApplication.openedWindows.length); // 3
ApplicationUtil.closeOpenWindows();
trace(NativeApplication.nativeApplication.openedWindows.length); // 0
 
// suppose three windows are open again
ApplicationUtil.closeOpenWindows(true); // closes windows and quits before trace is called
trace(NativeApplication.nativeApplication.openedWindows.length);