2017-05-27 3 views
1

Ich bin neu bei haxe openfl, ich habe mit flash und staring ein Spiel entwickelt, ich bin verwirrt über die Konvertierung von flash zu openfl haxe.Haxe Starling Object Pooling mit dynamischem Objekttyp

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; 
    } 
} 

ist hier ein Star Pool Klasse von Lee Brimelow habe ich frage mich, wie kann ich es Haxe konvertieren,

Ich mag versucht -

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; 
    } 
} 

Aber ich Dosis nicht funktioniert, vielleicht ich bin Gießen es nicht richtig, zum Beispiel -

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

Sie definierten Elemente als 'Array ' und definieren es dann als 'Array >'? Das ist mir eher unsinnig. –

+0

Auch wenn Sie das nicht getan haben, geben Sie ein 'Class'-Objekt buchstäblich an etwas zurück, das an eine Instanz dieser' Class' übergeben wird. Irgendwo in Ihrer Pool-Klasse müssen Sie dieses Objekt instanziieren, wahrscheinlich durch die stdlib 'Type'. –

+0

Beachten Sie die Zeile im ursprünglichen Code, die besagt: items [i] = new type() '. Das ist tatsächlich ein Objekt dieser Klasse instanziieren. Du bist nicht. –

Antwort

1

Besser nicht zu uns e Dynamisch, vor allem, wenn Sie typed object pool Weitere Informationen erstellen könnten Type Parameters

+0

Ok, das ist, was ich gesucht habe, aber im Moment scheint der Code zu funktionieren, 'var pool: StarlingPool ; pool = new StarlingPool (myClass, 15); 'Jetzt muss ich meinen Klassen-Typ 2 mal richtig angeben? kann ich es nicht einmal machen? –

1

Dies ist, was ich tun würde, um es die Haxe Art und Weise funktioniert:

  • einen StarlingPool mit Typ-Parametern vornehmen. Dann ist es generisch, also lassen Sie auch die Funktionsnamen auf getItem und putItem ändern.
  • len und items sind schreibgeschützt (Standardzugriff, kein fester Zugriff).
  • Verwenden Sie kein Array der Klasse, sondern eine Zuweisungsfunktion, die eine Instanz zurückgibt. Das kann schön sein, denn Sie können den neuen Sprite außerhalb der Poolklasse vorbereiten/dekorieren. Was bei verschiedenen Pools hilfreich sein kann.
  • Statt Fehler zu werfen, wenn der Pool leer ist, würde ich nur neue Instanzen mit der allocator-Funktion zurückgeben. Das macht mehr Sinn für mich. Natürlich müssen Sie messen eine anständige Länge für den Pool, um ein gutes Gleichgewicht der Speicherauslastung zu machen, so dass Sie eine Warnung dort für Debugging-Zwecke protokollieren könnten. Hier

ist die StarlingPool Klasse:

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; 
    } 
} 

Nun das ist ein schöner Pool, Sie es wie folgt verwenden können:

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 

Da der Pool generisch Sie ein anderes Objekt erstellen pool mit anderen Objekten darin. (Sie können natürlich nicht mehrere Typen mischen)

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

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

Hoffe, das hilft. Spielen Sie mit sich selbst: https://try.haxe.org/#979E1

+0

Danke ich werde es versuchen. –