Problems & Solutions

Writing a decent API

Posted in Adobe Flash, Problems & Solutions on June 8th, 2010 by Øyvind – 1 Comment

Over the last 6 months I’ve had to employ many Flash libraries that I have not worked with before. What strikes me is how poorly documented they are and how badly written some of them are. I won’t mention names, but I suspect some of you have an idea of where to find code like this. In order to make the world a better place — as always — here are two reminders that would help.

Use coding standards and best practices

Proper method names, argument names, argument types and return values are crucial to the mere mortals trying to use your API. Keep an eye on your naming schemes! Use the common denominator of data types when you can and create specialized value objects when necessary. This method signature might make perfect sense to you at a time of writing:

?View Code ACTIONSCRIPT
1
getCoords( arg1:*, arg2:*, ar3:*):Object

…but please clean that up when you release it to the general public! Answer me this: What kind of coordinates are we requesting? What kind of input is expected and what are their types? And what the hell does that generic return type contain exactly?? Might I suggest something like:

?View Code ACTIONSCRIPT
1
getCityCoordinates( region:String, country:String, city:String):Coordinates

You might think this kind of thing is trivial and basic. And it is, hence my bafflement when I read stuff like the first example in library released as the official API for one of the more common social media RIAs. You couldn’t imagine how many APIs out there break away from such common sense.

Clean up after yourself!

There are libraries out there without a single line terminated by a semi colon. As we know, the semis are optional, but they can cause the dreaded “internal build error/classes may not be nested” situation in Eclipse-based IDEs which usually eats up at least half a day of valuable time. I’ve had it happen to me, and needless to say I don’t consider semi colons to be optional. I use FDT to write my code and I have it set up to present me with an error whenever it comes across an unterminated line.

Other known culprits of internal build error are empty constructs like if-, for-, while and switch statements in addition to empty classes and interfaces. If there are incomplete sections in the API, pull them out and make sure the rest of the code doesn’t reference them.

Write proper ASDocs

How many libraries out there merely repeat the method signatures in the ASDocs? Then what’s the point? Most sane people use advances IDEs that will present ASDocs even inline with the code hinting, so make the most of it when the function and argument names cannot convey the full purpose of a property, event or method. To demonstrate, I will give an example from the ASDocs of my own logger utility, the Olog. I will not be humble in this case, because Olog’s ASDocs are in fact immaculate.

The main logic is spread across 10 classes, but there’s only two access points to the log console; the specialized event type and the Olog class itself. The Olog class serves a single purpose: It is the interface, the Application Programming Interface. It serves as the entry and exit point and the position of all the documentation. The core of the module is not as pretty, but that’s my problem. The Olog class consists of well named functions and getters and setters, all with comprehensive and highly cohesive ASDocs. In a sense you could say that this class’ primary purpose is to act as the black surface coating in the black box principle; it’s there to stop the reader from digging deeper, or should I say to make it totally unnecessary to dig deeper. Most of the methods have a single line in them, a call to another core method. This allows this class to focus on the task of providing decent documentation. The ASDocs are generated from this file.

This is a method from within the core of Olog:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
internal static function newTimeMarker(name:String = null, origin:Object = null):int
{
	var n:String = (name) ? name : "Operation";
	var o:String = Otils.parseOrigin( origin );
	var t:int = getTimer( );
	return _runTimeMarkers.push( [n, t, o] ) - 1;
}

But from the outside of the box it appears like this:

?View Code ACTIONSCRIPT
1
2
3
4
5
6
7
8
9
10
11
/**
* Creates a timing marker that you can later complete by calling completeTimeMarker() to
* output the time in between.
* @param name String reference to use when the marker completes an results are displayed.
* @return An integer ID to use as argument when calling completeTimeMarker().
* @see completeTimeMarker()
*/
public static function newTimeMarker(name:String = null, origin:Object = null):int
{
	return Ocore.newTimeMarker( name , origin );
}

Thats a ratio of 5:2 of respectively documentation and actual code! By using the Olog class as a dedicated API layer, I’m able to use that class as both a source of proper ASDocs and a structural reference for myself.

Now, pretty please…?

Microphone confirmation dialog not showing in Firefox

Posted in Adobe Flash, Problems & Solutions on May 11th, 2010 by Øyvind – Be the first to comment

A few days ago I was struggling with an application that made use of the client computer’s microphone for crucial functions. The problem was that the built-in security settings panel for granting access to the microphone did not open in Firefox on the Mac.

Normally, whenever you do this:

var mic:Microphone = Microphone.getMicrophone();

The Flash Player automatically opens this panel to ask the user to allow the microphone to be connected:
Flash Player Microphone confirmation dialog box

Of course this panel is never invoked if the user has the settings set to always allow or always deny, but very few do.

When this sucker never presented itself, I naturally thought that I was doing something wrong. Let’s face it, that’s the most probable cause. But after a while I noticed that the problem was specific to Firefox on the Mac. Knowing that SWFObject has had it’s issues with FIrefox in the past, I tried swapping it out for the jQueryFlash plugin, and voilà! How the JavaScript insertion method of the flash content could possibly cause it is beyond me. Honestly I don’t have the JS knowledge or interest to investigate either, seeing as I had a solution.

With SWFObject 1.5 there was a problem causing the stageWidth and stageHeight to be 0 for a certain time after the movie was loaded. That might be relevant in this case as well, but the microphone dialog was supposed to open long after the movie was fully loaded. That kinda rules it out.

So now you know. Don’t spend an entire night on this, like I did.

Get the Flash plugin for jQuery here:
http://jquery.lukelutman.com/plugins/flash/

RegExp matching unterminated ActionScript lines (semicolon)

Posted in Adobe Flash, Problems & Solutions on February 4th, 2010 by Øyvind – Be the first to comment

Skjermbilde 2010-02-04 kl. 11.40.44

Today I had the dreaded “1131: Internal build error” in Flash Builder coupled with the “Classes must not be nested error” despite no classes actually being nested. Googling around, I found a few posts that provide some tips towards a solution. The most frequent two of which are empty switch statements and ActionScript lines that are not properly terminated with a semicolon. The project in questing uses over 100 classes, so I decided to create a RegExp for use in “Find In Files” to search for lines that were not properly terminated.

As an extra caveat, many types of lines in programming are not supposed to be terminated, so the RegExp is quite long and I have not been able to test it any more than the said 100-class project I’m working on.

NOTE: This might macth some multiline ASDoc comments, empty lines and method argument lists spanning multiple lines as well.

?View Code REGEXP
(?sim)(?<!/\*)^\t*((?!\{|\}|@)(?!function|import|class|embed|SWF|if|else|switch|case|while|for|event|try|catch|finally|package|default|//|/\*|\*/)[^;])+$(?!.*\*/)

Here are the posts I found:

EDIT: Added “default” to the RegExp. If anyone has any improvements to this, please let me know. Especially on how to make it not match so many empty lines.