简报版本
我该如何编写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);
}
答案 0 :(得分:2)
实际上,您可以在外部使用@: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;
}
顺便说一句,Haxelib上已经有一个包含Love2D externs的库,名为hx-love2d。虽然不确定如何更新或完成。在这里,setColor()
似乎定义为GraphicsModule.setColor()
(在love.graphics
包中)。