“Multithreading” in ActionScript, PartII - JPEGEncoder Example

June 19th, 2009 Victor Posted in Uncategorized | 3 Comments »

This article is following “Multithreading” in ActionScript

Again, I’m going to start the atricle with:
Multithreading in ActionScript, no such thing!

Yes, they cooked PixelBender, that is very cool. You can do computations in the bender, they run asynchronously and are faster than ActionScript.

But now, let’s come back to our stuff. We are talking about ActionScript and code slicing, so the interface doesn’t get locked while your ActionScript program runs.

Here is one example, maybe this particular one can be better done with Bender, but it can serve as an example of how you can change a double “for” loop into slices for IThread.
We take an image and feed it into the JPGEncoder. The encoder outputs the jpeg file into a BitmapData instance. Then we load the BitmapData using a Loader, just to check the process was completed successfully.
You can see the progressbar advancing only in the threaded version. In the standard one, you can’t even move the browser window while processing. The threaded version takes a bit longer, depending on how much you interact with the interface.

Note: Someone suggested that dispatching events is slower than using function references directly. This example shows that the time penalty for using events is negligible, because events are not sent at each slice execution, but rather only on frame event and ready event, and those are quite few.

Here is the original main loop in Adobe’s JPGEncoder (corelib http://code.google.com/p/as3corelib/)

public function encode(image:BitmapData):ByteArray
{
	// Initialize bit writer
	byteout = new ByteArray();
	bytenew=0;
	bytepos=7;
 
	// Add JPEG headers
	writeWord(0xFFD8); // SOI
	writeAPP0();
	writeDQT();
	writeSOF0(image.width,image.height);
	writeDHT();
	writeSOS();
 
 
	// Encode 8x8 macroblocks
	var DCY:Number=0;
	var DCU:Number=0;
	var DCV:Number=0;
	bytenew=0;
	bytepos=7;
	for (var ypos:int=0; ypos<image.height; ypos+=8) {
	    for (var xpos:int=0; xpos<image.width; xpos+=8) {
	    RGB2YUV(image, xpos, ypos);
	    DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
	    DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
	    DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
	  }
	}
 
	// Do the bit alignment of the EOI marker
	if ( bytepos >= 0 ) {
		var fillbits:BitString = new BitString();
		fillbits.len = bytepos+1;
		fillbits.val = (1<<(bytepos+1))-1;
		writeBits(fillbits);
	}
 
	writeWord(0xFFD9); //EOI
	return byteout;
}

And here is the modified code

//thread job context
private var started:Boolean = false;
private var DCY:Number;
private var DCU:Number;
private var DCV:Number;
private var image:BitmapData;
private var ypos:int;
private var xpos:int;
 
public var progress:Number;
 
public function runSlice():Boolean
{
	if (!started)
	{
		// Initialize bit writer
		byteout = new ByteArray();
		bytenew=0;
		bytepos=7;
 
		DCY=0;
		DCU=0;
		DCV=0;
 
		// Add JPEG headers
		writeWord(0xFFD8); // SOI
		writeAPP0();
		writeDQT();
		writeSOF0(image.width,image.height);
		writeDHT();
		writeSOS();
 
		xpos = 0;
		ypos = 0;
		started = true;
	}
	progress = ypos / image.height;
 
	RGB2YUV(image, xpos, ypos);
	DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);
	DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);
	DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);
 
	xpos += 8;
	if (xpos >= image.width)
	{
		ypos += 8;
		xpos = 0;		
	}
 
	//we are ready
	if (ypos >= image.height)
	{
		// Do the bit alignment of the EOI marker
		if ( bytepos >= 0 ) {
			var fillbits:BitString = new BitString();
			fillbits.len = bytepos+1;
			fillbits.val = (1<<(bytepos+1))-1;
			writeBits(fillbits);
		}
		writeWord(0xFFD9); //EOI
 
		return false;//job finished
	}
	//wait for next slice
	return true;
}

Test the application here: example
You can compare the execution time. Note how the interface is still responsive while processing the threaded version.

Download: ThreadsExample ActionScript project

AddThis Social Bookmark Button

“Multithreading” in Actionscript

June 18th, 2009 Victor Posted in advanced, intermediate | 11 Comments »

Multithreading in FlashPlayer? No such thing…

Anyway, if you reached this article, you probalbly know a few things about Flash. Or you know  less than you think you know. Or the other way around. I’m lost…

On short, some processes you write take too much time to complete in just one frame’s time. Your animation locks, interface becomes unresponsive, not so nice. One solution, apart from not doing the task at all :D, is to slice the long task into small pieces of work and have them handled by a so called threads controller until the job is done. If the controller is smart enough, you can even concurrently run several tasks and not lock the player.

But 1000 words  are less then 2 lines of code, so, let’s dive in:

// the ThreadsController it will add some events to stage,
// so let's give it the stage reference
var tc:ThreadsController = new ThreadsController(stage);
 
//your SomeTask has to implement IThread
var task:IThread = new SomeTask;
 
// in this example i choose to end the task
// if it was not finished at the time we want
// to start another
if (tc.isRunning(task))
{
	tc.kill(task);
}
tc.run(task);
 
tc.addEventListener(ThreadEvent.THREAD_READY,
	function(e:ThreadEvent):void {
	if (e.thread != task) return;
	// do something after the task is done
});
 
tc.addEventListener(ThreadEvent.PROGRESS, function(e:ThreadEvent):void
{
	if (e.thread != task) return;
	// update the status of your task in progress,
	// like update a progress bar indication
});

Download: threads.rar

Next: Part II, JPEG Encoder Example

AddThis Social Bookmark Button

Pure Actionscript AIR Project in Flex Builder

June 14th, 2009 Victor Posted in beginner, intermediate | 3 Comments »

Sometimes you want to create a small application and not bother with all flex/mxml stuff. Either it’s pure ActionScript, or it uses other framework than flex (yes, such thing exists!, for example ASwing or just V3 Components from CS3/CS4), you might want to set up an AIR project that starts from a simeple .as file.

Currently, there is no obvious option in the Flex Builder interface. But, as a matter of fact, it is quite simple. Create a FlexProject, select AIR - Desktop Application in the first screen and change Main application file from <ProjectName>.mxml to <ProjectName>.as

Then, add some code in the constructor of your main class:

public function ProjectName()
{
	var win:NativeWindow =
		new NativeWindow(new NativeWindowInitOptions());
	win.activate();
	win.addEventListener(Event.CLOSE, function():void {
		NativeApplication.nativeApplication.exit(0);
	});
 
	win.stage.addChild(this);
 
	stage.scaleMode = StageScaleMode.NO_SCALE;
	stage.align = StageAlign.TOP_LEFT;
 
	graphics.lineStyle(1, 0, 1);
	graphics.drawCircle(100, 100, 80);
}

If you already have a web application and want to create an AIR version of it, extend the main class with one that only adds the AIR hooks.

If you also think this feature would be useful, vote it on Adobe Bug System
https://bugs.adobe.com/jira/browse/FB-9303

AddThis Social Bookmark Button

E4X, CDATA and XHTML <script> tag

April 16th, 2009 Victor Posted in intermediate | No Comments »

One of these days, while working on my Tamarin VM server side module, I was considering several template markup formats to use for outputting XHTML from ActionScript. The first obvious option is the native E4X.
Another candidate is TAL, which is XML based, so it should be easy to parse using E4X.

Verry soon I noticed a little problem.
While correct escaping of text content interpolated in the tags is a very nice feature, for example

var title:String = "some <unescaped> content"
var title:XML = <title>{title}</title>
//this works ok

- in other situations we would like to keep content unescaped.
Fortunately, there is a solution, in fact the only standard XHTML valid solution:

var script:XML = 
	<script type="text/javascript">//<![CDATA[
		alert(100);
	//]]></script>
 
//notice the comment mark "//" at the start/end of javascript tags
//whithout them, you'll get a JavasCrypt parse error :D

and this syntax is also E4X valid and recognised by Flex Builder as such.

AddThis Social Bookmark Button

Debugger Console Window with ActionScript parsing

September 23rd, 2008 Victor Posted in advanced, intermediate | No Comments »

Hi folks,
Been very busy lately but eventually I got the time to write again here. This one, I’m sure, will help some of you quite allot.
Tracing is a very common need for any application developer. It’s so frustrating when you can’t just quickly start a debugging session for the production version of your flash program. There are lots of solutions out there, but each has it’s limitations.

During the years, I developed and fine-tuned my own solution and now, it’s nearly impossible for me to start a new Flash web-app without it. Here are the features of my Debugger Console:

  • the console can be embedded in the production version, you can activate it using a simple javascript command entered in the browsers’ address bar
  • when the Debugger window is not open, all trace log is stored in memory until you choose to open the console, when you can see all of it in the window
  • you can directly type and execute (limited) custom ActionScript code by entering commands in the console input field. The evaluated value of the output of your expression will be printed out. (printing expressions, running function, passing parameters, instantiating (new), assigning, are the main ActionScript constructs that can be parsed by the console
  • command history. Use Up and Down arrow keys inside the console input field to see last used commands

Usage hints:

first type:

javascript:document.embeds[0].debug()

in your browsers’ address-bar (works in Firefox)

You’ll see the console window with all the previous traces listed. You can scroll using the keys or the mouse wheel.

Type a simple expression in the console input field (bottom of the window). For example, type stage and press Enter. Or type help to see a quick help.

To clear console, press the blue button on the top bar once. If you press it twice, the command history will also be cleared.

To close the console, press the red button. You can show it again using the javascript command above. Typically you would like to have this command stored in your bookmarks toolbar.

To assign a  local variable, use:

myVar = "some text"

then you can use your local variable without “local”. simply type myVar and press Enter
Expressions are parsed with regards of type. For example 100+1 will evaluate as 101 and “100″+1 will be 1001

You can execute functions and pass them parameters. Don’t forget to make the useful methods in your application public to be able to access them from the Debugger Console.

You can even create new instances using “new” keyword. Support for “new” keyword is in early stages but it can already be used with a little extra typing. Example:(type the following commands one by one in the console)

obj = new flash.display.Shape()

obj.graphics.lineStyle(0,0,1)

obj.graphics.lineTo(200,200)

stage.addChild(obj)

listDisplay(stage)

To use the console in your web-app, just make the package com.victordramba.debug visible for your project (either by copying the package inside the project source folder or by sharing it using Project Properties -> ActionScript Build Path -> Source Path)

Known bugs and limitations:

  • parsing for single quote (’) strings is not implemented. Always use double quote (”) to pass strings.
  • succesive binary operators not implemented (you can’t do e.g. 1+2+3)

Security note: Beware, if you embed the console in your production version, it will be available for other people also. Make sure you do not expose sensitive data by your application. Normally, the security wall should be on the server-side, like with any client-server web application. SWF format can be reverse engineered, so all the data inside the flash player can be considered open for the user that received it.

Example: examples/debugger

Download: example.zip

AddThis Social Bookmark Button

ActionScript3 speed test

July 8th, 2008 Victor Posted in advanced, intermediate | 2 Comments »

Just read this article about programming language speeds:

Performance Comparison - C++ / Java / Python / Ruby/ Jython / JRuby / Groovy
by Dhananjay Nene

And of course, my first thought - let’s test ActionScript3 in this (a bit arguable) manner

The results were quite surprising, it beats PHP by far:

AS3 (Activex player 9,0,124,0, nondebug): 50 microseconds
AS3 (Stand-alone player, 9.0.115.0, debug): 150 microseconds
PHP (apache module): 600 microseconds
(on the same machine - Core2 Duo 2.4GHz, php running into vmware/debian. If I run the php version in windows, it gets worse :D)

Here is the AS version of the same program.
I compiled it with Flex Builder3, release mode (not debug, that’s a bit slower).

package 
{
	import flash.display.Sprite;
	import flash.text.TextField;
 
	public class speed_test extends Sprite
	{
		public function speed_test()
		{
			var ITER:int = 10000;
			var start:Number = (new Date).getTime(); 
			for (var i:int = 0 ; i < ITER ; i++)
			{
				var chain:Chain = new Chain(40);
				chain.kill(3);
			}
			var end:Number = (new Date).getTime();
 
			var txt:TextField = new TextField;
			txt.width = 300;
			addChild(txt);
			txt.text = "Time per iteration = " + 
				((end - start) / ITER * 1000) + " us.";
		}
	}
}
 
 
class Chain
{
	private var first:Person = null;
 
 
	public function Chain(size:int)
	{
		var last:Person = null;
		var current:Person = null;
		for (var i:int = 0 ; i < size ; i++)
		{
			current = new Person(i);
			if (!first) first = current; 
			if (last)
			{
				last.setNext(current);
				current.setPrev(last);
			}
			last = current;
		}
		first.setPrev(last);
		last.setNext(first);		
	}
 
	public function kill(nth:int):Person
	{
		var current:Person = first;
		var shout:int = 1;
		while(current.getNext() != current)
		{
			shout = current.shout(shout, nth);
			current = current.getNext();
		}
		first = current;
		return current;
	}
 
	public function getFirst():Person
	{
		return first;
	}	
}
 
class Person
{
	private var count:int;
	private var prev:Person = null;
	private var next:Person = null;
 
	public function Person(count:int)
	{
		this.count = count;
	}
 
	public function shout(shout:int, deadif:int):int
	{
		if (shout < deadif) return (shout + 1);
		this.getPrev().setNext(this.getNext());
		this.getNext().setPrev(this.getPrev());
		return 1;
	}
 
	public function getCount():int
	{
		return this.count;
	}
 
	public function getPrev():Person
	{
		return prev;
	}
 
	public function setPrev(prev:Person):void
	{
		this.prev = prev;
	}
 
	public function getNext():Person
	{
		return next;
	}
 
	public function setNext(next:Person):void
	{
		this.next = next;
	}
}
AddThis Social Bookmark Button

Table icon

March 18th, 2008 Victor Posted in cabanova | No Comments »

A funny one…

Our icon designer was required to do a set for the new insert bar. Insert text, insert image, etc. One of them is insert table.
Of course, you can guess what kind of table should be available for insert in a web page. But, lol, his thought was different. Here is his icon:
table.jpg

AddThis Social Bookmark Button

Links - Coding practices

March 10th, 2008 Victor Posted in advanced | No Comments »

I have to share 2 links with you. Both funny as hell, they would nicely decorate one rainy day at home, with nothing to do.

excerpt:
“Having all your code in one big file may not be the epitome of good OO design but it makes it a darn sight easier to find something if you don’t know where to look for it, and easier to modify too if the alternative is a morass of interdependent files. Perhaps that’s extreme, but never underestimate the power of grep as a software development tool - the best identifiers are the ones you can easily search for!”

How to Write Unmaintainable Code
Tips for maintainable Java code

AddThis Social Bookmark Button

AIR: Share the Clipboard Image

March 9th, 2008 Victor Posted in intermediate | No Comments »

They just released the AIR goodies for CS3. I guess you already noticed, unless you disabled the auto-update feature of your Adobe software. So, I started to play a bit with it and it proved fast enough for a lazy guy like me. You should know, although I’m completely and hopelessly coder (as opposed to graphic designer) , I’m the type of guy that would never create a Flex project to do a banner. Even if it’s a data driven one. Therefore, I think this CS3 plug-in for AIR is really useful. Add a few buttons, write a few lines (they have to be few, because code completion in Flash sucks) and click the right button. You have your mini desktop application in half an hour. Like this one, that I decided to share with you. It’s my (almost) first. Let’s see what it does:

If you use chat allot, you surely know what I mean. You want to send a screenshot or any image, but you don’t have the file, you just have the bitmap in your Clipboard. Of course, most new chat clients know about file transfer. But you have to open your favourite image editor, paste the image, save the file, browse for it and send. 80% of the cases, I bet you’ll find that your want-to-be-sent-image will just stay at home. Here comes my little program. It displays a tray icon. You click the icon, your Clipboard data is converted to an image format, uploaded on a website and replaced right in the Clipboard with the URL text of your uploaded image, ready to be pasted in the chat. All this in one click. In this example, only the Windows version (trayicon). If you need it, take your time write the mac version.

I used this for uploading, corelib for encoding image and.., no, that’s all.

Ah, almost forgot: the serverside. I used a small PHP script. In real-life, you should limit the usage per IP or use a login system.

here it is: air-shareimage.rar

Note: did not include the corelib files, you should download the lib yourself: corelib

AddThis Social Bookmark Button

Five3D in AS3

February 16th, 2008 Victor Posted in advanced | 4 Comments »

I played a bit with Mathieu Badimon’s vectorial 3D engine Five3D
http://five3d.mathieu-badimon.com/
First, bulk translate it into AS3 and then addapt it a bit
Here is the result, not very well brushed up. Ill probably get back over this post and update the download with a more polished one.

Download -> five3dexample.rar

See it -> five3dexample.swf

AddThis Social Bookmark Button