2010-05-06 36 views
1

尽管我正在使用的程序是使用Java,但从C的角度回答这个问题也很好,因为大多数情况是语言不可知的,或者发生在Lua端东西的。将Lua函数作为成员变量嵌入到Java中

在我正在编程的游戏体系结构中,从一个数据文件加载特定类中的各种类型的游戏对象(例如:生物,物品,法术等)。他们的大多数属性都是简单的数据类型,但是我希望其中的一些成员实际上包含简单的脚本,这些脚本定义了例如项目在使用时的功能。这些脚本将非常简单,因为所有基本的游戏动作都将通过来自Java的API公开。 Lua只负责将这些基本功能串在一起,并设置参数。

这个问题很大程度上是存储对作为Java类成员的特定Lua函数的引用的最佳方法。

我明白,如果我将Lua代码存储为一个字符串并调用lua_dostring,则Lua将在每次调用时都编译新的代码。所以需要以某种方式定义该函数,并引用包含在Java函数对象中的此特定函数。

我考虑过的一种可能性是,在数据加载过程中,加载程序在数据文件中遇到脚本定义时,会提取此字符串,使用关联对象的唯一ID装饰函数名称,并调用lua_dostring该字符串包含完整的函数定义,然后将生成的函数名称包装在Java函数对象中。在使用lua_dostring运行的脚本中声明的函数仍应添加到全局函数表中,是否正确?

我只是想知道是否有更好的方法去做这件事。我承认,在这一点上我对Lua的知识是相当肤浅和理论的,所以我可能忽略了一些明显的东西。

回答

2

只是做k = luaL_ref(L, LUA_REGISTRYINDEX);

用你想在栈顶引用的Lua值调用它,它会返回一个整数k。存储此整数,并且当您需要Lua值时,只需执行lua_rawget(L, LUA_REGISTRYINDEX, k);即可将该值再次推送至堆栈顶部。当你想释放对象(即在对象被破坏时),请致电luaL_unref(L, k)

它可以与任何类型的Lua值一起使用,包括函数(或闭包,实际上)和协程。

+0

谢谢。我不熟悉Lua的参考机制。然而,我仍然不确定如何将这些函数推入堆栈,而没有遵循我在我的问题中概述的过程(为函数设计一个临时名称等)。我想这只是一个更高性能的选项而不是调用一个使用其名称的函数。 但是,手动释放引用的需求看起来可能存在问题,因为Java没有析构函数,所以无法保证引用被释放。 – Zarion 2010-05-06 17:25:57

+0

@Zarion:不,你不需要给存储的名称赋值。在大多数情况下,您不必费心推送堆栈上的函数,因为堆栈是Lua和C之间的主要通信。当您第一次加载代码块并编译它时,结果是堆栈上的函数。或者,如果你在一个模块中定义了几个函数,把模块本身(它只是一个表格)放在注册表中。或者,如果您提供了“设置回调”功能,它已经作为参数存在于堆栈中。优点不在于性能,而是存储任意(匿名)值。 – Javier 2010-05-06 20:51:20

+0

关于释放引用,它就像您在Java对象上持有的任何其他资源,必须关闭打开的文件,数据库会话,TCP流等等。在C++中,它很容易释放析构函数;在Java上应该有一些通用的实践来释放资源。 – Javier 2010-05-06 20:53:55

相关问题