2016-07-12 13 views
3

Angenommen, ich möchte eine generische Inline-Funktion in Haxe erstellen, die den Flash ByteArray und einen Array übernimmt.Unterschiedliche Codepfade innerhalb von Haxe generischen Funktionen

@:generic public static inline function WriteArray<T:(UInt, Int, Float)>(ba:ByteArray, array:Array<T>):Void 
{ 
    if (array == null) 
    { 
     ba.writeInt(-1); 
    } 
    else 
    { 
     ba.writeInt(array.length); 
     for (i in 0...array.length) 
     { 
      // here is where I have a problem 
      // ba.writeUnsignedInt(array[i]); if T is UInt 
      // ba.writeDouble(array[i]); if T is Float 
      // ba.writeInt(array[i]); if T is Int 
     } 
    } 
} 

Also, ich brauche einen Weg, um jede der generierten Funktionen zu erhalten, eine andere Zeile dort zu verwenden. Dieser Code muss performant sein, daher ist die Laufzeitprüfung auf Typ keine Option. Ich kann auch nicht übergeben, welche Schreibfunktion als Parameter zu verwenden ist (writeFunc:T->Void) b/c wir kompilieren derzeit zu Flash, und Flash erstellt ein MethodClosure Objekt jedes Mal, wenn Sie einen Verweis auf eine Funktion machen, und der Garbage Collector doesn ' t handle sie gut (das passiert, ob die Funktion inline ist oder nicht). Ich habe auch versucht, Makros zu verwenden, aber Sie können nichts aus der Flash-Bibliothek innerhalb eines Makros verwenden (ich habe eine ähnliche Funktion zum Schreiben von Flash-Vektoren, und wir verwenden immer noch die ByteArray-Implementierung von Flash). Ich hoffe, dass es einen Weg gibt, T zur Kompilierzeit zu bekommen, aber alles, was ich gefunden habe, ist ${type} und ich glaube nicht, dass Sie das bedingt verwenden können.

Gibt es also eine Möglichkeit, diese Funktion zum Aufrufen der korrekten Schreibmethode auf ByteArray zu bekommen, ohne einen Verweis auf diese Funktion zu erstellen? Es muss nicht notwendigerweise @:generic verwenden, aber ich denke, die Einschränkungen wären hilfreich. Andere Implementierungsideen wären ebenfalls willkommen. Gerade jetzt habe ich gerade 3 Versionen der gleichen Funktion, und c/p'd Code nur über mich bringt mich in den Mund.

Antwort

4

Ich habe auch versucht, Makros zu verwenden, aber man kann nichts aus der Flash-Bibliothek in einem Makro

verwenden, das nicht ganz richtig ist: Sie können nicht wirklich Verwendung Flash-API in einem Makro, aber Sie können Code generieren, der es verwendet. Sie müssen nur sicherstellen, dass Sie es nicht als import -Statement am Anfang der Datei hinzufügen und stattdessen den vollständig qualifizierten Namen (flash.utils.ByteArray) verwenden.

Hier ist ein einfaches Beispiel:

import haxe.macro.Context; 
import haxe.macro.Expr.Access; 
import haxe.macro.Expr.FieldType; 

class Macro { 
    public static function build() { 
     var fields = Context.getBuildFields(); 
     fields.push({ 
      name: "byteArray", 
      access: [Access.APublic, Access.AStatic], 
      kind: FieldType.FVar(macro:flash.utils.ByteArray, null), 
      pos: Context.currentPos(), 
     }); 
     return fields; 
    } 
} 

..., die erzeugt:

public static var byteArray:flash.utils.ByteArray;