I see the benefit of using object pooling, and I also want to combine it with Vectors. But, reading about Vectors, I see that they can only be defined at compile time, meaning a separate pooler class for each of the pooled classes is required. On the other hand, I would like to have a random class instance of a set (all extending a certain class) to be pulled from a pool at runtime, so that I don't exactly know which object pooler is to be called. And, in order to not multiply the code sequences for pooler classes, I want to combine all pools into a UniversalPooler class, which then can serve requests like var foo:SomeClass=UniversalPool.getFromPool(SomeClass);
. The question is, how can I implement such a universal pooler performance effectively, using Vectors if at all possible, and probably using random subclass selection?
问问题
396 次
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;
}
}
}
它可以用作一个全局池。而且我不认为可以有更有效的实现,一般来说这是一个非常简单的功能。
于 2013-05-30T09:02:58.947 回答