【问题标题】:Embedding Lua functions as member variables in Java在 Java 中嵌入 Lua 函数作为成员变量
【发布时间】:2011-02-16 04:43:27
【问题描述】:

虽然我正在开发的程序是用 Java 编写的,但从 C 的角度回答这个问题也很好,考虑到其中大部分与语言无关,或者发生在 Lua 方面。

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

问题主要是关于将特定 Lua 函数的引用存储为 Java 类成员的最佳方式。

我知道如果我将 Lua 代码存储为字符串并调用 lua_dostring,Lua 将在每次调用时重新编译代码。所以需要以某种方式定义函数,并将对这个特定函数的引用包装在 Java 函数对象中。

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

我只是想知道是否有更好的方法来解决这个问题。我承认我在这一点上对 Lua 的了解是相当肤浅和理论的,所以我可能忽略了一些明显的东西。

【问题讨论】:

    标签: java lua


    【解决方案1】:

    只要k = luaL_ref(L, LUA_REGISTRYINDEX);

    用你想在栈顶引用的 Lua 值调用它,它会返回一个整数k。存储这个整数,当你需要 Lua 值时,只需执行 lua_rawget(L, LUA_REGISTRYINDEX, k); 将值再次推送到堆栈顶部。当你想释放对象时(即在对象被销毁时),调用luaL_unref(L, k)

    它适用于任何类型的 Lua 值,包括函数(实际上是闭包)和协程。

    【讨论】:

    • 谢谢。我不熟悉 Lua 引用机制。但是,我仍然不确定如何将这些函数推入堆栈,而基本上没有遵循我在问题中概述的过程(为函数设计一个临时名称等)。我想这只是一个比调用更高效的选项使用其名称的函数。但是,手动释放引用的需求似乎存在潜在问题,因为 Java 没有析构函数,因此无法保证引用会被释放。
    • @Zarion:不,您不需要为存储的值命名。在大多数情况下,您不必费心将函数压入堆栈,因为堆栈是 Lua 和 C 之间的主要通信。当您第一次加载代码块并编译它时,结果是堆栈上的函数。或者,如果您在一个模块中定义了多个函数,请将模块本身(它只是一个表)放入注册表中。或者,如果您提供“设置回调”函数,它已经作为参数在堆栈中。优点不是性能,而是存储任意(匿名)值。
    • 关于释放引用,它就像您在 Java 对象上持有的任何其他资源一样,必须关闭打开的文件、数据库会话、TCP 流等等。在 C++ 中,释放析构函数很方便;在 Java 上应该有一些常见的做法来释放资源。
    猜你喜欢
    • 1970-01-01
    • 2017-01-15
    • 2013-10-17
    • 2018-12-11
    • 2018-09-23
    • 1970-01-01
    • 2012-07-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多