Posts Tagged ‘AS3’

VerifyError: Error #1024: Stack underflow occurred.

Tuesday, July 31st, 2012

I just completed hunting down a Stack underflow error. It was a little tedious since the error is not thrown when I compiled for debug player, only release.
The source of it? A trace statement in a try block. For some reason the compiler doesn’t like that at all.

The solution seemed to be to remove all traces from try-catch blocks, which worked, but I wasn’t satisfied.

After binary searching trough the svn commits, I found what triggered the above error, an empty for-each loop.
Removing that loop made all traces work again normally inside try-catch blocks, which is what I prefer.

for each (var fruit:String in fruits) {
   // Empty loop, a BIG NO NO!
}

So to prevent your swf from corrupting, do not have empty for-each loops in your project! Remove them completely or fill them with some code.

Mxmlc ANT compiler error: “Error: Java heap space”

Thursday, September 29th, 2011

A simple error that causes a lot of headache that has a simple solution that is hard to find on the internet.
Don’t you just love these problems?

If you are calling mxmlc via ANT you’ve probably seen this error and had to resort to solutions like setting the ANT_OPTS or Java arguments for the SDK on every single computer that uses that build script.

The solution is actually much simpler than that, mxmlc allows you to set this in the ANT target itself. Just add the parameters fork=”true” to make it run on it’s own Java thread, and then set maxmemory to something like “1024m”.


	

It would have been nice if adobe had this in the documentation, but no such luck.

AS3 Polygon Clipper

Monday, May 23rd, 2011


I was looking for an open source polygon clipper library for AS3 to use on a commercial project.
I found a few ports of the General Polygon Clipper library (GPC) but it is only free for non-commercial projects.
After more searching around I found this excellent library called Clipper by Angus Johnson. It did not have an AS3 port so I made one using Alchemy to wrap the c++ code.

The SWC and source code can be found on github: https://github.com/Flassari/as3clipper

It is completely free and open source for both personal and commercial projects. Clipper uses the Boost Software License.

Supported clipping operations: difference, intersection, union and XOR.

Here’s an example of how to use the AS3 port after importing the Clipper.swc file:

import com.flassari.geom.Clipper;
import com.flassari.geom.ClipType;

var subjectPolygon:Array = [new Point(0, 0), new Point(200, 0), new Point(100, 200)];

var clipPolygon:Array = [new Point(0, 100), new Point(200, 100), new Point(300, 200)];

var resultPolygons:Array = Clipper.clipPolygon(subjectPolygon, clipPolygon, ClipType.DIFFERENCE);

Update
There is now an AS3 port available at https://github.com/ChrisDenham/PolygonClipper.AS3

Prefixing private variables with an underscore in AS3

Tuesday, April 26th, 2011

A coworker and I had a discussion about using underscores for private variables in AS3.
I’ve always added an underscore before my private variables, like so:

private var _myVariable:int;

While he wanted to only use underscores for when you have a variable which has a getter/setter:

private var _myGetAndOrSetVariable:int;
private var myPrivateVariable:int;

public function get myGetAndOrSetVariable():int {
	return _myGetAndOrSetVariable;
}

This was a little alien to me and I didn’t get the point of it. Why should you only sometimes use an underscore? He answered that then you know that private variable has a getter/setter if it has an underscore.

Well, that’s not a bad reason. I googled around and it sounds like Adobe actually enforces this kind of rule in their Coding Conventions document; “Give the storage variable for the getter/setter foo the name _foo.”.
They don’t say anything about if the other variables shouldn’t have underscores though, so I dived into the source code of the Flex SDK to see what they were using.
Turns out, both! In some classes every single private variable had an underscore, and in other ones only variables with a public getter/setter had one.
In this poll, majority of AS3 developers always use underscores.

I thought long and hard, and I came up with these reasons for why one should always use underscores for private variables:

  • It can be confusing “sometimes and sometimes not” putting an underscore.
  • You can see immediately if the variable is accessible to another class when you always prefix private variables with underscores.
  • Most of the in-house code and frameworks always use underscores (consistency).
  • Pressing ctrl+space for IDE code completion shows you all the local private variables if you type an underscore first, if you don’t you get every single variable in the class with every class in the project together in one gigantic list.
  • Most other coders and their frameworks online use it.
  • If you are going to create a getter/setter for the variable, you have to rename it first to include the underscore.
    • Also, if you rename it without refactoring, all references in the class will now pull from the getter (possible calling extra code) when maybe they were only supposed to get the raw data.
  • If the other method is used I will know much less about the variable just from looking at it, possible making debugging harder. It could be a local variable, a class function, a function parameter, a private variable without a getter/setter, a getter/setter function or a public variable.

Personally, I don’t really care when I’m writing code in a class if a variable has a getter/setter. That’s encapsulation, and I think mostly of it when working in/thinking of other classes that interact with the current one. I much more care knowing if I’m working with a variable or calling a getter function (it could be a public variable too, but still less complicated).
I also prefer to write “_id = id” instead of “this.id = id”.

Also, adding an underscore just to avoid a name conflict doesn’t sound proper to me. It sounds like you had to make a workaround to make the code do what you want (read: a shit mix).

So far these are enough reasons for me to stick with prefixing my private variables with underscores. I have an open mind though, a comment can easily change my mind if it has the right arguments.

What is your method, and why? Please do share =)

Populating a Vector in the constructor

Wednesday, January 19th, 2011

There is a small difference between populating a Vector while instancing it and an Array.
While an Array is instanced this way:

var names:Array = ["Bob", "Larry", "Sarah"];

a Vector can be instanced like this:

// In the constructor
var names:Vector.<String> = new <String>["Bob", "Larry", "Sarah"];
// Converting from a regular Array using the Vector global (about three times slower)
var names:Vector.<String> = Vector.<String>(["Bob", "Larry", "Sarah"]);

Preloader without a loader-swf in AS3

Wednesday, November 17th, 2010

Here’s one method of loading your AS3 movie, using a preloader class that loads before all other classes.

The flex compiler can actually split up the code for you so one class loads before all others. Even though we’re using the flex compiler to do this we do not have to have a Flex project, it can be a Flash project or a pure actionscript project. If we’re using a Flash project we do have to set the flex compiler path though.

Anyways, the way it works is that in your main class you add the Frame metadata, like this:

package com.flassari {
// Preloader meta tag
[Frame(factoryClass="com.flassari.Preloader")]
// Start of our own application code
[SWF(backgroundColor="#FFFFFF", frameRate="24", width="800", height="600", pageTitle="My preloaded project")]
public class Main extends Sprite
{

The preloader has to extend movieClip, because behind the scenes it is using frames for its magic.
In your preloader class, when it is done loading (by checking if it is at the last frame), your have to instantiate the main class with no strict typing. If you were to use strict typing, the whole application would have to load before the preloader can be shown so that would defeat the purpose of a preloader:

private function onEnterFrame(e:Event):void {
	if (currentFrame == totalFrames) { // If we're at the frame where Main is ready
		// Stop and clean up
		stop();
		removeEventListener(Event.ENTER_FRAME, onEnterFrame);
		// Create the main application and add it to the display list
		var mainClass:Class = getDefinitionByName("com.flassari.Main") as Class;
		addChild(new mainClass() as DisplayObject);
	}
}

Just remember, everything that the preloader references will be loaded before the preloader can be shown, so keep it to a minimum.
Also, because the main class is created before it is put on the stage, be sure not to reference the stage in the constructor.

The OR ( || ) operator in AS3

Tuesday, September 21st, 2010

Here’s a quick tip: the OR operator ( || ) in AS3 does not return true if either condition evaluates to true; it returns the actual value of the first condition to evaluate to true.

What does that mean? Lets try an example:
This statement:

trace ( "foo" || "bar" );

will trace out the string “foo”, not “true” (in an if statement “foo” will evaluate to true).

This statement:

trace ( undefined || false || "bar" );

will trace out the string “bar”.

If no condition evaluates to true, it will return the last condition.

trace ( false || undefined || 0 || "" || NaN || null );

will trace out “null”.

This can be really handy when making sure variables are not uninitialized before using them.
Check out this example:

function doSomething(arr:Array, data:Object, path:String):void {
    this.args = arr || [];
    this.dataObject = data || {};
    this.dataUrl = path || "http://default.url";
}

And even sexier (thanks MonkeyMagiic):

this.args ||= [];

Re-dispatch an event

Monday, July 19th, 2010

I just stumbled upon a sexy and simple way to forward an Event that I wanted to share with you:

myEventDispatcher.addEventListener("someEvent", dispatchEvent);

AS3 “with” keyword and casting

Monday, July 12th, 2010

I’ve rarely (if ever) used the “with” keyword in as3, but I recently found a neat trick to use it with.

When I quickly need to cast an object to access a few methods/properties I don’t always want to
create a new casted variable:

var child:DisplayObject = getChildThatMightBeMovieClip();

if (child is MovieClip) {
	var childAsMc:MovieClip = child as MovieClip;
	trace(childAsMc.numChildren);
	trace(childAsMc.currentFrame);
}

or cast it every single time:

var child:DisplayObject = getChildThatMightBeMovieClip();

if (child is MovieClip) {
	trace((child as MovieClip).numChildren);
	trace((child as MovieClip).currentFrame);
}

Using the “with” keyword, we can temporarily cast it without creating a temporary casted variable or casting it again and again:

var child:DisplayObject = getChildThatMightBeMovieClip();

if (child is MovieClip) {
	with (child as MovieClip) {
		trace(numChildren);
		trace(currentFrame);
	}
}

Elegant =)

Global error handling with Flash Player 10.1

Wednesday, June 23rd, 2010

Since the official release of Flash Player 10.1 is out, now might be a good time to start implementing the global error handler.

When this is written, flash builder 4 doesn’t have a native way that lets you use it, so we have to do a little mix. (Update: The update is out.)
The global error handler works by adding an event to the uncaughtErrorEvents property of the loaderInfo of the application.
There are currently two methods of getting it to work.

Method 1 – The backwards compatible one:

Here the code doesn’t crash in flash player 9/10, but the error handling will only work in 10.1.

if(loaderInfo.hasOwnProperty("uncaughtErrorEvents")){
	IEventDispatcher(loaderInfo["uncaughtErrorEvents"]) .addEventListener("uncaughtError", uncaughtErrorHandler);
}
private function uncaughtErrorHandler(e:Event):void {
	trace("Global error:", e);
}

Method 2 – The type safe one:

Get the Flex 4.1 SDK if you haven’t already and choose that one as your project’s SDK.

Now you can use the new global error handling like it was meant to be used:

import flash.events.UncaughtErrorEvent;

loaderInfo.uncaughtErrorEvents.addEventListener( UncaughtErrorEvent.UNCAUGHT_ERROR, uncaughtErrorHandler);

private function uncaughtErrorHandler( e:UncaughtErrorEvent):void {
	trace("Global error:", e);
}