从Haxe代码调用Lua静态函数



简要版本

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

长版本

我有一个生成Lua代码的Haxe程序。我在LÖVE上运行这个Lua代码,运行时公开了使用Lua表作为名称空间的各种函数。这些函数大多是以静态方式调用的,比如:

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

事实上,您可以在extern上使用@:luaDotMethod元数据来实现这一点。来自haxe --help-metas:

指示给定的外部类型实例应具有点样式的方法调用,而不是冒号。

这里有一个例子:

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

顺便说一句,在Haxelib上已经有一个名为hx-Love2D的带有Love2D外部的库。但不确定它的更新或完整程度。这里,setColor()似乎被定义为GraphicsModule.setColor()(在love.graphics封装中)。

最新更新