tags:

views:

68

answers:

1

Although the program I'm working on is in Java, answering this from a C perspective is also fine, considering that most of this is either language-agnostic, or happens on the Lua side of things.

In the outline I have for the architecture of a game I'm programming, individual types of game objects within a particular class (eg: creatures, items, spells, etc.) are loaded from a data file. Most of their properties are simple data types, but I'd like a few of these members to actually contain simple scripts that define, for example, what an item does when it's used. The scripts will be extremely simple, since all fundamental game actions will be exposed through an API from Java. The Lua is simply responsible for stringing a couple of these basic functions together, and setting arguments.

The question is largely about the best way to store a reference to a specific Lua function as a member of a Java class.

I understand that if I store the Lua code as a string and call lua_dostring, Lua will compile the code fresh every time it's called. So the function needs to be defined somehow, and a reference to this specific function wrapped in a Java function object.

One possibility that I've considered is, during the data loading process, when the loader encounters a script definition in a data file, it extracts this string, decorates the function name using the associated object's unique ID, calls lua_dostring on the string containing a full function definition, and then wraps the generated function name in a Java function object. A function declared in script run with lua_dostring should still be added to the global function table, correct?

I'm just wondering if there's a better way of going about this. I admit that my knowledge of Lua at this point is rather superficial and theoretical, so it's possible that I'm overlooking something obvious.

+2  A: 

just do k = luaL_ref(L, LUA_REGISTRYINDEX);.

call it with the Lua value you want to refer on the top of the stack and it will return an integer k. Store this integer, and when you need the Lua value just do a lua_rawget(L, LUA_REGISTRYINDEX, k); to push the value again to the top of the stack. When you want to release the object (i.e. at object's destruction), call luaL_unref(L, k)

It works with any kind of Lua value, including functions (or closures, in fact) and coroutines.

Javier
Thanks. I was not familiar with the Lua reference mechanisms. However, I'm still uncertain about how to push these functions onto the stack, without following essentially the procedure I outlined in my question (devising a temporary name for the function, etc.) I guess this is just a more performant option than calling a function using its name.However, the need to manually release references seems potentially problematic, as Java does not have destructors, so there's no way to guarantee that the references are ever released.
Zarion
@Zarion: no, you don't need to give the stored value a name. In most cases you don't have to bother pushing the function on the stack, since the stack is the main communication between Lua and C. When you first load the code chunk and compile it, the result is a function on the stack. Or if you define several functions in a module, put the module itself (it's just a table) in the registry. Or if you provide a 'setup callback' function, it's already in the stack as a parameter. The advantage isn't performance, it's about storing arbitrary (anonymous) values.
Javier
about releasing the reference, it's just like any other resource you hold on Java objects, an open file have to be closed, a database session, a TCP stream, whatever. in C++ it's handy to release on destructors; on Java there should be some common practice to release resources.
Javier