Galib Imtiaz
Galib Imtiaz

Reputation: 106

Haxe Starling Object Pooling with Dynamic Object Type

I am very new to haxe openfl, I used to develop game with flash and starling , I am confused about the conversion from flash to openfl haxe.

public class StarlingPool
{
public var items:Array;
private var counter:int;

    public function StarlingPool(type:Class, len:int)
    {
        items = new Array();
        counter = len;

        var i:int = len;
        while(--i > -1)
            items[i] = new type();
    }

    public function getSprite():DisplayObject
    {
        if(counter > 0)
            return items[--counter];
        else
            throw new Error("You exhausted the pool!");
    }

    public function returnSprite(s:DisplayObject):void
    {
        items[counter++] = s;
    }

    public function destroy():void
    {
        items = null;
    }
}

Here is a Starling Pool Class created by Lee Brimelow I was wondering how can I convert it to Haxe,

I tried like -

 class StarlingPool
{
    public var items:Array<Class>;
    private var counter:Int;

    public function new(type:Class<Dynamic>, len:Int)
    {
        items = new Array<Class<Dynamic>>();
        counter = len;

        var i:Int = len;
        while (--i > -1)
            items[i] = type;
    }

    public function getSprite():Class<Dynamic>
    {
        if (counter > 0)
            return items[--counter];
        else
            throw new Error("You exhausted the pool!");
            return null;
    }

    public function returnSprite(s:Dynamic):Void
    {
        items[counter++] = s;
    }

    public function destroy():Void
    {
        items = null;
    }
}

But I dose not work ,maybe I am not casting it properly ?, for example -

pool = new StarlingPool(Bullet, 100);
var b:Bullet = cast(pool.getSprite()); //or 
var b:Bullet = cast(pool.getSprite(),Bullet)

Upvotes: 1

Views: 287

Answers (2)

Mark Knol
Mark Knol

Reputation: 10143

This is what I would do to make it work the Haxe way:

  • make a StarlingPool with type parameters. Then it is generic, so also lets change the function names to getItem and putItem.
  • len and items are read-only (default get access, no set access).
  • Don't use an array of Class but provide an allocator-function that returns an instance. This can be nice, because you can prepare/decorate the new Sprite outside of the pool class. Which can be handy when having different pools.
  • Instead of throwing errors when pool is empty, I would just return new instances using the allocator-function. That makes more sense for me. Of course you have to measure a decent length for the pool to make good balance of memory usage, so you could log a warning there for debugging purposes.

Here is the StarlingPool class:

class StarlingPool<T>
{
    public var items(default, null):Array<T>;
    public var len(default, null):Int;

    private var _allocator:Void->T;

    public function new(len:Int, allocator:Void->T)
    {
        this.len = len;
        _allocator = allocator;

        // create array full of instances using comprehension syntax
        items = [for(i in 0...len) allocator()];
    }

    public function getItem():T
    {
        if (items.length > 0)
            return items.pop();
        else
            // instead of returning null, why not just provide new objects.
            return _allocator();
    }

    public function putItem(item:T):Void
    {
        if(items.length < len)
        {
            items.push(item);
        }
    }

    public function destroy():Void
    {
        _allocator = null;
        items = null;
    }
}

Now thats a nice pool, You can use it like this:

var pool = new StarlingPool(50, function() return new Sprite());

trace(pool.items.length); // actual items in pool: 50
var item = pool.getItem();
trace(pool.items.length); // actual items in pool: 49
pool.putItem(item); // give item back
trace(pool.items.length); // actual items in pool: 50

$type(item); // type of this item is: Sprite

Since the pool is generic you can create a different object pool with other objects in it. (You can't mix multiple types, of course)

var pool2 = new StarlingPool(50, function() return new OtherObject());

var item2 = pool2.getItem();
$type(item2); // type of this item is: OtherObject

Hope this helps. Play with it yourself: https://try.haxe.org/#979E1

Upvotes: 1

Andrew
Andrew

Reputation: 1282

Better not to use Dynamic, especially if you could create typed object pool More information about Type Parameters

Upvotes: 1

Related Questions