Posts Tagged: AS3


24
Jan 12

SmoothBitmap – How to enforce pixel smoothing on a Bitmap

A common oversight when using Bitmaps with loaded content is that Flash will revert a Bitmap’s smoothing parameter to false when you replace its bitmapData. It’s simple enough to fix, but since you may not know if someone is going to replace the bitmapData of a Bitmap you have created – then it’s often better to code defensively around it.

This little SmoothBitmap class is for just such an occassion. Instantiate it like a regular Bitmap and, no matter what another developer does with it, smooth pixels when scaling/rotating will be ensured.


14
Jan 12

CODING WRONGS – Where do I start with the bad?

It gets scary out there sometimes. During my freelance career I've worked a lot of different companies and have seen such coding horrors as you cannot imagine. So I thought I'd start immortalising some of them - so that we can all learn better coding practices, by looking at the bad.

Starter for 10 - What's wrong with this picture?

public function set someProperty(value:String):void
{
    var newPixels:BitmapData = new BitmapData(someUint, someUint, true, 0);
    someBlitUtil.blitStuffTo(newPixels, value);
    someBitmap.bitmapData = newPixels;
}

If it's not immediately obvious, the fubar here is the potential replacement of a Bitmap's BitmapData, without explictly disposing any existing BitmapData. I see this kind of thing quite often and it's the source of many a memory leak. AVM2 isn't that great and dealing with this kind of situation and there's a crucial difference between GC cleaning up out-of-scope objects for you and things like BitmapData: GC will reclaim the memory associated with objects 'when it feels like it', whereas explicitly calling the 'dispose' method of a BitmapData will immediately give you back that memory. In the case of hardware accelerated setups, the memory associated with the pixel data itself (video memory) will be reclaimed immediately. You shouldn't make more work for GC when you can avoid it - defensive programming is always best!


10
Jan 12

Object pooling utility updated

Having just got back from an awesome break in Thailand and Taiwan, I just updated my object pooling utility. Thanks to Ostra Ceruzka for raising an issue with its strict mode functionality with me - all fixed now! Serves me right for not writing enough tests, huh?


31
Aug 11

TextField.getRawText() what it does

I was recently creating an API that required extending TextField and happened across the getRawText() method. I assumed this returned the text from the field without formatting or something - so I looked up the AS3 docs for flash.text.TextField.

Nothing there - gee thanks Adobe. A quick search turned up this which, it turns out, isn't quite accurate.

So, with a tad of testing, it appears that getRawText() returns the text, stripped of any HTML tags (if you had set htmlText). I now wonder if this is faster than using a RegEx to strip the tags and why Adobe didn't document it?


29
Aug 11

Loan Shark – fast object pooling

Loan Shark AS3 object pooling utilityA couple of years ago, I created an AS3 object pooling utility for a games project I was building. Since then, I've used it quite a few times, in order to speed up apps and improve resource management, easing the load on the garbage collector by reusing objects instead of recreating them.

While object pooling isn't a magic bullet to speed up every use case, it works especially well with custom classes that are heavy to continually contruct and destroy. A good example is my History of the World project, which uses an object pool for item renderers, instead of creating and destroying them as you navigate around - press ALT+CTRL to bring up the resource debugger, which shows a little information on its usage.

I recently updated the utility, improving its performance, adding features and putting loads of unit tests around it. It's now hosted it over at GoogleCode. Using it is a simple as:

import org.kissmyas.utils.loanshark.LoanShark;

var pool:LoanShark = new LoanShark(SomeClass);
var someInstance:SomeClass = pool.borrowObject();
someInstance.doStuff();

// Instead of nullifying an object, check it back into the pool
pool.returnObject(someInstance);


7
Aug 11

Fastest way to add multiple elements to an Array / Vector

In a simple situation, where you wish to add many elements to an Array or Vector, you might just do:

var input:Array;
var output:Array;
while (input.length)
    output.push(input.shift());

However, the sizes of both Arrays are manipulated for each loop, which will have an adverse impact on speed and memory usage. So, we could cache the length of the input Array and not manipulate it:

var input:Array;
var output:Array;
var inputLength:uint = input.length;
for (var i:int = 0; i <inputLength; i++)
    output.push(input[i]);

But we're still growing the size of the output Array incrementally, which is very bad. Since we know input.length in advance, we could grow the output Array to its new size just once, before the loop:

var input:Array;
var inputLength:uint = input.length;
var output:Array;
var outputLength:uint = output.length;
var newOutputLength:uint = outputLength + inputLength;
output.length = newOutputLength;
for (var i:int = 0; i <inputLength; i++)
    output[i + outputLength] = input[i]);

This is OK, but still involves a loop. If only we could push multiple elements into the push method in one go. Well, we can - enter the apply method. Since Array.push accepts multiple arguments (something rarely used) and apply allows us to pass an Array of arguments to any Function, one line and we're done:

var input:Array;
var output:Array;
output.push.apply(null, input);

This works out faster and more memory efficient than the other methods. It works nicely for Vectors, too. If anyone has a faster method of doing this, do let me know.


10
Jul 11

SWFIdle – simple flash idling utility

I created this simple utility, called SWFIdle, to enable the Flash Player to lower its CPU usage while the user is not interacting with it. Since it's possible to have multiple Flash instances embedded in one page (for example, a game and a couple of banners), I recommend that everyone uses this in their projects, so that SWFs needn't fight for CPU and give Flash a bad name.


9
Jul 11

Dependency Injection by Extension pattern

Since I'm not sure whether I have indeed invented a new design pattern here. So, alternative titles for this post include:

  • Dependency Injection without a Dependency Injection framework
  • Why misuse of the default namespace for tests is pure evil
  • How to make your code more testable without completely messing it up

The problem:
You need to use some kind of Dependency Injection (DI for short) to provision some System Under Test (SUT for short) in tests you're writing, but can't or don't want to use a DI framework to do so.

Of course, the simplest form of DI is simply passing things to a constructor. But you probably don't want to code every class to be handed every dependency at construction. And you definitely don't want to expose the private parts of your implementation through some unnecessary interface. No, you really don't!

I've seen scary examples of what I call 'keyhole surgery' on classes, either by abuse of the internal namespace to allow poking into otherwise private implementation, or just by making too many things public. Although the internal namespace (AKA the default namespace) is perceived to retain a sufficient level of encapsulation, it really doesn't. Anything in the same package can jump all over it, so it's somewhat of a loose interface. As such, you should never leave methods unscoped, letting them default to the internal namespace. You should also reserve the internal namespace only for when you are in control of all classes that will exist in the same package, such as when creating utility classes.

Loose interfaces are bad practice for a few reasons:

  • Clarity - anyone using the class will be confused as to the intentions of its interface
  • Stability - a class with such a loose interface is open to misuse and a recipe for failure
  • Cleanliness - code for tests does not belong in your production code
  • Testability - you should test a class through its interface, not its implementation
  • Flexibility - it is hard to refactor classes that leak implementation detail in such a way

The solution:
Well, this is one possible solution and ultimately just my suggestion. It's especially useful when needing to refactor classes with overuse of the internal namespace, since you won't need to change much test or production code. I call it the Dependency Injection by Extension pattern.

How it works:
You provide DI helpers as protected methods in your SUT and subclass it from within your test case, as a script-level class, to expose the DI helpers as public and/or use the constructor to do some of the DI work - allowing you to inject mocked dependencies for your tests. This has the advantage of not allowing anything else to meddle with your SUT, other than through its interface, of course. And, if anything in your production code wishes to extend your SUT, potentially overriding and messing up the interface, then that class should have its own tests anyway.

Example:
The following example shows a very basic class (SystemUnderTest) being extended from within its testcase (SomeTest) to allow injection and access to its dependencies, for the purpose of verifying its behaviour under given conditions.

class SystemUnderTest
{
    protected var someDependency : Dependency;
    private var _someThing : Thing;

    public function SystemUnderTest()
    {
        someDependency = new Dependency();
        _someThing = new Thing();
    }

    public function doSomething() : void
    {
        _someThing.callSomething( someDependency.getSomething() );
    }

    protected function get someThing() : Thing
    {
        return _someThing;
    }
}

package
{
    public class SomeTest
    {
        private var sut : SystemUnderTestWithDI;
        private var someThing : Thing;
        private var mockDependency : Dependency;

        public function setUp()
        {
            mockDependency = mock(Dependency);
            sut = new SystemUnderTestWithDI(mockDependency);
            someThing = sut._someThing;
        }

        [Test]
        public function testSomething():void
        {
            var testValue : String = 'foo';
            given( mockDependency.getSomething() ).willReturn( testValue );

            sut.doSomething();

            verify().that( someThing.callSomething( eq(testValue) ) );
        }
    }
}

class SystemUnderTestWithDI extends SystemUnderTest
{
    public function SystemUnderTestWithDI(dependency : Dependency)
    {
        super();
        someDependency = dependency;
    }

    public function get _someThing() : Thing
    {
        return someThing;
    }
}