从 Haxe 代码调用 Lua 静态函数

简要版

我如何编写 Haxe 代码来生成 Lua 代码,以便使用静态函数调用而不是使用实例方法调用语法?

详细版

我有一个生成 Lua 代码的 Haxe 程序。我在 LÖVE 上运行这个 Lua 代码,运行时会使用 Lua 表作为命名空间来暴露各种函数。这些函数 mostly 所用的都是静态方式调用,比如:

love.graphics.setColor(r, g, b)

不幸的是,Haxe 的 Lua 代码生成好像假定所有 Lua 函数调用都是调用实例方法,因此它生成的代码使用 Lua 的方法调用语法,如下所示:

love.graphics:setColor(r, g, b)

我尝试过各种调用这个函数的方式。我只找到了一种可行的方式:

class Love {
  static public var graphics: Graphics = new Graphics();
}

class Graphics {
  public function new() {}
  public function setColor(r: Int, g: Int, b: Int) {
    var fn = untyped love.graphics.setColor;
    fn(r, g, b);
  }
}

我可以像这样在 Haxe 中调用它:

Love.graphics.setColor(r, g, b);

这样做很好,但不够优雅,所以我想知道是否有更好的方法。我怀疑这可能也有一些微小的性能成本,虽然我不是特别担心这个问题,而且 LuaJIT 可能足够聪明,在任何情况下都会将中间变量优化掉。我最想要的是一种更清晰的编写包装器代码的方法。

似乎 Haxe 的外部功能可能是这里的答案,但目前没有针对 Lua 的特定文档说明如何使用它,我也无法解决如何在这里应用它。

这里有一些未能工作的代码示例(它们生成了实例方法调用而不是静态调用):

public function setColor(r: Int, g: Int, b: Int) {
    (untyped love.graphics.setColor)(r, g, b);
}

var _setColor = untyped love.graphics.setColor;
public function setColor(r: Int, g: Int, b: Int) {
    _setColor (r, g, b);
}
点赞
用户2631715
用户2631715

确实,您可以在 extern 上使用@:luaDotMethod元数据来完成此操作。来自haxe --help-metas:

表示给定的 extern 类型实例应该对方法进行点样式调用,而不是冒号。

这是一个例子:

class Main {
    public static function main() {
        Love.graphics.setColor(0, 0, 0);
    }
}

@:native("love")
extern class Love {
    static var graphics(default, null):Graphics;
}

@:luaDotMethod
extern class Graphics {
    function setColor(r:Int, g:Int, b:Int):Void;
}

这将生成以下 Lua 代码:

Main.main = function()
  love.graphics.setColor(0, 0, 0);
end

或者,您可以通过声明 setColor()static 函数来完成相同的操作,这可能更符合 Haxe 的思维方式:

class Main {
    public static function main() {
        love.Graphics.setColor(0, 0, 0);
    }
}
package love;

@:native("love.graphics")
extern class Graphics {
    static function setColor(r:Int, g:Int, b:Int):Void;
}

此外,已经有一个名为hx-love2d的 Love2D externs 库可以在 Haxelib 上找到。不过我不确定它有多新或完整。在这里,setColor() 是以 GraphicsModule.setColor()(在 love.graphics 包中)的形式被定义。

2019-01-02 15:51:04