March 6th, 2007
Out With Thee
Apparently someone is clamoring for a class that we use here called “Out”. This post will deliver said class, as well as provide a brief overview of its usage.
“Out” really doesn’t do anything particularly useful, but it does make it a lot easier to scan through large volumes of trace() output and find the information you’re looking for by formatting it nicely. This means that every line traced out is prefixed with the classname of the instance executing the trace, as well as the type of event the trace is intended to represent. There’s also the option of filtering the outputs such that only traces from specific classes or of specific types are displayed.
Now click on through for more ad impressions!
Usage
Now, the AS2 version and the AS3 version (links to the classfiles are available at the bottom of this post) are radically different, primarily because the AS2 version was written years ago when I had neither experience nor sobriety on my side. The AS2 version might be ugly on the inside, but it hasn’t changed since way back then. Its usage is pretty simple, paste this into an empty FLA:
import com.bigspaceship.utils.Out;
Out.enableAllLevels();
Out.debug(this, "foo");
…test-movie, and you should see this:
DEBUG: undefined: foo
Now, I can hear you asking, “how on earth can this be useful?” Well, when you really pepper your code with calls to Out, you can wind up with this in your output window:
DEBUG: Physics: Tile 45 added
DEBUG: Game: taking off at (x=64927.160, y=-40.081)
DEBUG: Game: landing at (x=64961.775, y=-61.1264
DEBUG: Physics: player rotated -45 degrees
DEBUG: Game: taking off at (x=65116.4251, y=-183.635)
DEBUG: Input: adding input L to L
DEBUG: Game: begin input
DEBUG: Input: adding input U to L,U
DEBUG: Game: trick attempting
DEBUG: Input: fail - trick input timed out
DEBUG: Game: cancel input
DEBUG: Game: end input
DEBUG: Physics: Tile 44 removed from game world
DEBUG: Physics: Tile 45 sealed at 65250
DEBUG: Game: landing at (x=NaN, y=NaN)
DEBUG: Physics: player rotated -100.55 degrees
DEBUG: Game: crash report from segment sink tile 0 at location (x=NaN, y=NaN)
ERROR: Bike: position vectors corrupted!
ERROR: Bike: restoring corrupted position to 66237.718 (was 0)
FATAL: Game: player position lost
In that example, it’s easier to scan and make sense of the output since you know where each call is coming from, and you know the type of output it is. When you call “Out.error(this, [string]);”, it prepends “ERROR” to the output string, and the same is true of the other output levels: “info”, “status”, “debug”, “warning”, and “fatal”. If that’s still too much output, you can decide to display only the errors with the following statements:
Out.disableAllLevels();
Out.enableLevel(OUT_FATAL);
…similarly, you could decide that you’re no longer interested in output generated from the “Physics” class like so:
Out.silence("Physics");
The above output, by the way, was stored in-game and HTTP POST’ed to my machine by people playing the game and submitting bug reports. You can do this too by extending the Out class and hacking it to your liking.
AS2-Specific Usage
In AS2.0, there was no built-in means of identifying your own custom classes, and as a result, all of our classes have the following property:
private var _classname : String = "MyClassName";
“Out” will look for that property and attribute any traces coming from it with its value. If there isn’t a “_classname” property, you’ll have to settle for “undefined”.
AS3-Specific Usage
The AS3 version is both more robust and less embarrassing for me to show to the public. It functions nearly identically, but takes advantage of the flash.utils.getQualifiedClassName() method, so you no longer need to include a “_classname” property of your own. The biggest difference is that you can now subscribe to output events, like so:
import com.bigspaceship.utils.Out;
import com.bigspaceship.events.OutputEvent;
.
.
.
Out.addEventListener(OutputEvent.DEBUG, myDebugHandler);
This lets you easily re-pipe the output to wherever you like, be it a textfield or a PHP socket. You can subscribe to output calls of specific levels, or you can specify OutputEvent.ALL to receive every call.
Important Note
“Out” isn’t and wasn’t really ever intended to be efficient, so where performance is an issue, I’d suggest globally commenting out “Out” lines before going into production
Hope this is useful to someone! Here is the download in one archive: