Archive for category ActionScript 3.0

Wan’t to get rid of your traces to trace? (Flex)

Update: to clearify I want to mention already here that this post regards using the Flex SDK, since the Adobe CS have an “Omit traces” checkbox which totally removes all traces in the bytecode as well.

I noticed a high FPS-loss in one of my applications when testing some Z-sorting in the Flash 10 3D functionality which I hadn’t been seing before. This even when using release mode when compiling! I had to use the profiler through Flash Builder 4 beta to track it down to a trace in the Z-ordering algorithm (just using a regular Painters Algorithm based on the actual Z-value compared to the root). /Update

What’s up with that trace draining performance even when compiling in release mode?

Believe it or not, but the bytecode regarding traces look identically no matter if you use release or debug compilation mode, it’s just up to the flashplayer itself to actually make something with the call to trace depending on the release mode.

So here’s the proof, and solution:

A normal constructor for a Main class:

public function Main():void 
{
	trace("Test");
}

So, you’re running your little flash-application in debug mode while developing, of course because you want to see the trace messages. But what happens behind the scene?
This is what the ABC2 byte-code looks like for the above Main constructor, notice the trace with 13, 15 and 17 in front (which by the way is the sum of instructions for the AVM2 engine).

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=2 code_len=24
	0       debugfile     	"E:\temp\TraceTest\src;;Main.as"
	2       debugline     	13
	4       getlocal0     	
	5       pushscope     	
	6       debugline     	13
	8       getlocal0     	
	9       constructsuper	(0)
	11      debugline     	15
	13      findpropstrict	trace //find the trace function
	15      pushstring    	"Test" //the string to trace
	17      callproperty  	trace (1) //call the function
	20      pop           	          //end - start of next, 20-13 = 7 instructions for the AVM2 engine
	21      debugline     	16
	23      returnvoid    	
}

Okay, nothing weird here since its compiled with debug, but what really happens when we switch to release mode?
Well, mainly the compiler will remove the debugline, telling what line in the actual source-code (.AS files) the flashplayer executes the code for. This is the information shown in unhandled exceptions that gets thrown so you easily can find the broken code.

But, what about that trace?

This is the exact same code, only switched to release mode:

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=2 code_len=13
	0       getlocal0     	
	1       pushscope     	
	2       getlocal0     	
	3       constructsuper	(0)
	5       findpropstrict	trace //Didn't I just tell you to go away by switching to release mode?
	7       pushstring    	"Test" //Even the strings are left intact
	9       callpropvoid  	trace (1) //And also the function call.... sigh
	12      returnvoid    	     //still adding upp to 12-5 = 7 instructions as well since it's the exact same code
}

But how can we solve this?
One solution could be to add a global flag in the main class and then use it as condition when to use the trace

private const DEBUG:Boolean = false;  //change to true when developing

But this would only make the release build to evaluate that flag to see if we want to trace or not,
so how about removing all traces by hand ? Not too funny when we want to continue to develop again.

The solution is called conditional compilation and is supported by the Flex compiler.
See Adobes reference here: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_21.html

The solution for this example:

public function Main():void 
{
	IFDEF::DEBUG {
		trace("Test");
	}
}

And by passing this to the compiler:

-define=IFDEF::DEBUG,false
//or
-define=IFDEF::DEBUG,true

we simply make the compiler remove the whole block of code within the { } when IFDEF:DEBUG is set to false

This produces the ABC2 byte-code as follows, nice and clean from the trace:

function Main():void	/* disp_id -1*/
{
	// local_count=1 max_scope=1 max_stack=1 code_len=6
	0       getlocal0     	
	1       pushscope     	
	2       getlocal0     	
	3       constructsuper	(0)
	5       returnvoid    	
}

, , , , , ,

8 Comments

Simple Actionscript 3.0 Flash VideoPlayer in < 40 lines of code

So.. you want a flash videoplayer but don’t want to purchase an expensive player, or use the great multi-i-can-play-everything-player which is 30kb+ in swf size?

Lets check this out how easy it could be to really create a tiny videoplayer, the following code does compile into roughly 1kb swf which should be small enough for everyone to use, let the user spend his bandwidth on downloading the actual video instead of the player itself!
Set the flashvar videoUrl to specify which video to play.

See the player in action here

package 
{
	import flash.display.*;
	import flash.media.*;
	import flash.events.*;
	import flash.net.*;
	/**
	 * @author Erik Karlsson, www.nonobtrusive.com
	 */
	public class Main extends Sprite 
	{
		public function Main() 
		{
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			var connection:NetConnection = new NetConnection();
			connection.connect(null);			
			var stream:NetStream = new NetStream(connection);
			stream.addEventListener(NetStatusEvent.NET_STATUS, onEvent );
			stream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onEvent );
			stream.addEventListener(IOErrorEvent.IO_ERROR, onEvent );
			stream.client = this;     //for onMetaData and onCuePoint
			var video:Video = new Video(stage.stageWidth, stage.stageHeight);
			video.attachNetStream( stream );
			stream.play( stage.loaderInfo.parameters["videoUrl"] );  //pass the url to video as videoUrl flashvar
			addChild(video);
		}
		private function onEvent(event:Event):void {
			trace( event.toString() );		//handle this as you wish
		}
		public function onMetaData(info:Object):void {
			trace( info.duration + " - " + info.width + " - " + info.height + " - " + info.framerate ); //handle this as you wish
		}
		public function onCuePoint(info:Object):void {
			trace( info.time + " - " + info.name + " - " + info.type ); //handle this as you wish
		}
		public function onXMPData(data:Object):void {
                        //used in flash10+
			trace( data ); //handle this as you wish
		}
	}
}

, , ,

71 Comments