1

オブジェクト プーリングを使用する利点がわかりました。また、それを Vector と組み合わせたいと考えています。しかし、ベクトルについて読んでみると、それらはコンパイル時にしか定義できないことがわかりました。つまり、プールされたクラスごとに個別のプーラー クラスが必要です。一方で、どのオブジェクト プーラーが呼び出されるか正確にわからないように、セットのランダムなクラス インスタンス (すべて特定のクラスを拡張する) を実行時にプールから取得したいと考えています。そして、プーラー クラスのコード シーケンスを増やさないようにするために、すべてのプールを UniversalPooler クラスに結合して、var foo:SomeClass=UniversalPool.getFromPool(SomeClass);. 問題は、可能であればベクトルを使用し、おそらくランダムなサブクラス選択を使用して、このようなユニバーサル プーラーのパフォーマンスを効果的に実装するにはどうすればよいかということです。

4

1 に答える 1

1

はい、残念ながら を使用することはできませんVectors。AS3 ではジェネリックの実装が非常に貧弱です。Dictionaryクラス マップとArraysオブジェクト ストレージに基づいて、次のプーリングを使用します。

package util.pool
{
import flash.utils.Dictionary;

public class ObjectPool
{
    private var storage:Dictionary = new Dictionary();

    public function ObjectPool()
    {
    }

    private function createNew(constructor:Class, ...args):Object
    {
        //as3 - (facepalm), why there isn't API to path array of params to constructor
        switch (args.length) {
            case 0:return new constructor();
            case 1:return new constructor(args[0]);
            case 2:return new constructor(args[0], args[1]);
            case 3:return new constructor(args[0], args[1], args[2]);
            case 4:return new constructor(args[0], args[1], args[2], args[3]);
            case 5:return new constructor(args[0], args[1], args[2], args[3], args[4]);
            case 6:return new constructor(args[0], args[1], args[2], args[3], args[4], args[5]);
            case 7:return new constructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]);
            case 8:return new constructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]);
            case 9:return new constructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]);
            case 10:return new constructor(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]);
            default: throw new Error("too much arguments for constructor, add more switch cases :))");
        }       
    }

    public function create(constructor:Class, ...args):Object
    {
        var pool:Array = getOrCreatePool(constructor);

        var res:*;
        if(pool.length > 0)
        {
            res = pool.pop();
        }else
        {
            args.unshift(constructor);
            res = createNew.apply(null, args);
        }

        return res;
    }

    public function destroy(obj:Object):void
    {
        if(!obj) return;
        if(!(obj is Object)) return;

        var constructor:Class = obj["constructor"];
        var pool:Array = getOrCreatePool(constructor);
        pool[pool.length] = obj;
    }

    public function destroyArr(objs:Object):void
    {
        for each(var obj:Object in objs)
            destroy(obj);
    }

    private function getOrCreatePool(constructor:Class):Array
    {
        var pool:Array = storage[constructor];
        if(!pool)
        {
            pool = [];
            storage[constructor] = pool;
        }

        return pool;
    }
}
}

1 つのグローバル プールとして使用できます。そして、これ以上効果的な実装はないと思います。一般的に非常に単純な機能です。

于 2013-05-30T09:02:58.947 に答える