Friday, 2 March 2012

Tuesday, 23 February 2010

Micro Threads in ActionScript3 with open source Thrash

One of the major drawbacks of Flash Player is its lack of multithreading. In today’s market, when every new laptop comes with at least two processor cores and the cores aren’t getting faster this is a serious caveat. However, there is one other situation which also would benefit from threads. If you are doing any heavy data processing in your Flash/Flex app you know this; namely that the Flex GUI blocks while executing ActionScript.

While trying to make eXplorer perform better by using callLater() to delay some execution to the next frame and let the GUI update, I realized that I could abstract a pattern from this. But little did I know that pseudo threading in Flash has been covered in several places before, so I wrote a couple of classes to simplify the creation of what I called Micro Threads (however, I realize that Pseudo Threads might be a better name).

A MicroThread simply implements the interface IMicroThread:


package org.ncva.thrash
{
public interface IMicroThread
{
function worker(): Boolean;
function get name(): String;
}
}

The idea is that the method “worker” is executed as many times as possible during one frame after which the thread is paused to allow rendering and other AS3 execution only to be resumed again the next frame. The thread will indicate that it is finished by returning true after a call to “worker”.

My pseudo threads in contrast to those mentioned above make use of a scheduler that is responsible of calculating how many times a task can execute per frame. I’m also planning to add priority to the threads so that more important operations are given more processor time than others. Right now each task is executed at least once per frame, which can be too much if you have several heavy threads running at once. The threads should instead take turns and execute only when there is frame time available.

Task

I created a class named Task which implements the IMicroThread interface and takes as parameter a function to be used as “worker”. You can use task like this:

var x: uint = 0;

MicroThreadScheduler.scheduler.addThread(new Task(function (): Boolean {
x++;
var done: Boolean = x >= 10;
return done;
}));

Since x is in scope for the thread and the function passed to the Task is a closure, the same x will be available each time the thread is awakened, and whenever this code is reached and you create a new thread, you also create a new x, so there won’t be a conflict in the access of the variable x.

AsyncLoop

To further simplify the porting of existing code you can use the class AsyncLoop which contains some methods imitating the behavior of our beloved loop-constructs:

//  doWhile imitates "do ... while (condition)"
var x: uint = 0;
var control: uint = 0;

do {
control++;
} while (control < 10);

AsyncLoop.doWhile(function (): Boolean {
x++;
return x < 10;
});

assertEquals(control, x);

// forRange imitates the common "for (var i=0; i<L; i++)" construct
var A: Array = [1,2,3,4,5,6,7,8,9,10];
var control: uint = 0;
var sum: uint = 0;

for (var i:uint=0; i<A.length; i++)
control += A[i];

AsyncLoop.forRange(0, A.length, function (i: uint): void {
sum += A[i];
});

assertEquals(control, sum);

// forEach imitates "for each":
var A: Array = [1,2,3,4,5,6,7,8,9,10];
var control: uint = 0;
var sum: uint = 0;

for each (var x: uint in A)
control += x;

AsyncLoop.forEach(A, function (a: uint): void {
sum += a;
});
assertEquals(control, sum);

// forEach works with Object too:
var O: Object = getMyObjectFromSomeWhere();

for each (var a: Object in O)
doSomeThing(a);

AsyncLoop.forEach(O, function (a:Object): void {
doSomeThing(a);
});

The first iteration of the loop will be scheduled the next frame and following iterations will be scheduled as many times as possible the coming frames.

Thrash 0.1 0.2 is available here: [source, binary] and can be used under the terms of GNU LGPL.

FlashPlayer 10 playerglobals and Flex Builder 3 projects

Recently I wanted to use the Flash Player 10 only type Vector.<T>, so I added the playerglobals.swc from FlashPlayer 10 to my AS Library project's libs path like I feel I have done a zillion times before. However, this time Flex Builder gave me errors for each type I used from the player:


The error I made was that I did not change the Link Type to "External". So just click the small arrow and double-click "Link Type" and change the value to "External":


Moreover, if you get an error about "inconsistant linkage":
Inconsistant linkage
Then you have probably forgot to remove the playerglobals.swc from the Flex framework link:

Just select the playerglobals.swc item under Flex and hit Remove.

Tuesday, 26 January 2010

Glyph performance testing and glyph model

Hi,

I put my slides (Glyph.pptx) and data file (GlyphTest.xls) of performance testing for the meeting on Jan 26, 2010 on my web folder http://webstaff.itn.liu.se/~hova/

/Quan

Friday, 20 November 2009

Unit testing with Flex Unit 4

Why?

Unit testing should be done for several purposes:

  • If you write your tests before the actual class code, you design the public interface of the class to be conveniently callable
  • The class you create is by definition testable
  • Unit tests shortens the code-debug-fix-cycle because you won’t have to load your application and click around to test stuff
  • When you refactor the code you will know directly if something breaks, but only if you run all the tests in the suite.

How?

Flex Unit is an open source project lead by Adobe. It will be integrated with Flash Builder 4, but as it is an ActionScript3 project it can be used with Flex Builder. It has a graphical test runner based on Flex. You can create either a separate application for the test runner or you could integrate it into your application. The FlexUnit project consists of a couple of swc-files which you put in your test project.

You write tests in ActionScript for all your code by extending the class TestCase. Below is an example of a test for one of the methods in the GAV Flash class ArrayHelper:


package gavtests.utils
{
import flexunit.framework.TestCase;
import gav.utils.ArrayHelper;

public class ArrayHelperTest extends TestCase
{
public function testCreateArray(): void
{
function filler(i:uint, arr:Array): * {
return i*i;
}
assertObjectEquals([0,1,4,9,16,25],
ArrayHelper.createArray(6, filler));
}
}
}

The TestCase class provides several methods named assertXXX which are used to do the actual testing. In this case two objects are compared using the assertObjectEquals, one is the return value from createArray and the other is what we would expect it to be. Whenever an assertion fails, the test is stopped.The ArrayHelperTest class is added to a test suite, which is added to the test runner. Below is a simple testing application which features a graphical test runner and runs the test class above:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="onCreationComplete()"
layout="absolute"
xmlns:flexui="flexunit.flexui.*">
<mx:Script>
<![CDATA[
import mx.binding.utils.BindingUtils;
import flexunit.framework.TestSuite;
import gavtests.utils.ArrayHelperTest;

private function onCreationComplete(): void
{
testRunner.test = createTestSuite();
testRunner.startTest();
}

private function createTestSuite(): TestSuite
{
var testSuite:TestSuite = new TestSuite();
// Add your test cases here:
testSuite.addTestSuite(ArrayHelperTest);
return testSuite;
}
]]>
</mx:Script>
<flexui:TestRunnerBase id="testRunner" width="100%" height="100%"/>
</mx:Application>

What should be tested?

Test as much as possible. But here are some examples:

  • All public functions - this should actually exercise all private functions as well. What you should aim for is to cover every single path through your code.
  • Invalid arguments – define how your square root function should behave if you hand it a negative number and assert that it behaves that way
  • Boundary conditions – how should your array manipulating algorithm behave when you pass it an empty array?
  • Properties – You might find it unnecessary to test that a property actually has the value you assign to it, but if you at some point mess up a property setter it might take a long while for you to debug that. If you have a test case for it you will find out directly. What if you assign null? I’ve seen code that keeps the old value in this case, which is probably incorrect.
  • That event listeners are removed from the old property value if you assign a new one
  • Bugs. Whenever you find a bug reproducible by code, add a test case for it and fix it. That way the bug won’t reappear.

GAV Flash tests

I’ve created a new project on SVN called GavFlashTests where I will try to add tests whenever I write new code for GAV Flash. We probably will never cover all of the current code with unit tests, but then again we probably won't use the current code forever.

Resources

Friday, 6 November 2009

GAV Code Meeting #1

Today the GAV development team had our first of many bi-weekly code meetings.

There was much rejoicing! and cake.

Issues discussed:

- Microthreads, new tool developed by Markus
- Optimizing Performance
- Invalidation
- Strict Array typing
- New flash drawing API, applied to map shapes