Jump to content
  • Advertisement
Sign in to follow this  
SeiryuEnder

Using C++-Allocated Objects in Lua

This topic is 2331 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Right now I'm using Luna to expose my C++ classes to Lua. The problem I'm having is that I want to allocated and manage my objects in C++, only using Lua to potentially create or manipulate them.

I'm not particularly familiar with Lua. My (rather naive) first attempt was to set up a class as per some Luna tutorials, create that class using a factory, pass that class to Lua using lua_pushlightuserdata, and create an object reference in lua to the pointer in the stack.

As it turns out, Lua doesn't know how to interpret that pointer as it defines 'objects' by metatables which a raw memory address won't have. After giving it some thought, I'm currently considering creating an interface class which contains all of my Lua functions. The constructor will accept a parameter to its target class. Because it is only an interface and doesn't contain any actual data, it doesn't cost much to instantiate it whenever a script is run and let the GC clean it up.

However, not only does this seem inefficient but I completely lose type-safety. The script could theoretically pass anything into the lua interface which can crash the program (or worse). Does anyone more experienced with C++-Lua binding know how I can achieve my original goal of handing a C++ object to lua, or have any more elegant solutions? I'll add some pseudo-code below to make my problem a bit more clear.

Current Attempt:

std::vector<GameObject*> objList;

class GameObject
{
public:
void DoThing() {}
int Do( lua_State* _state ) { DoThing(); }

... insert Luna binding code
}

int CreateObject( lua_State* _state )
{
GameObject* obj = new GameObject();
objList.push_back( obj );
lua_pushlightuserdata( _state, (void*)obj );
return 1;
}


int main()
{
lua_State* state = luaL_newstate();
lua_register( state, "CreateObject", CreateObject );
luaL_loadfile( m_State, "DoSomething.lua" );
lua_pcall( state, 0, LUA_MULTRET, 0 );
lua_close( state );

return 0;
}

DoSomething.lua:
local obj = CreateObject( "LuaScript" )
obj.Do()


...This won't work because Lua doesn't know how to interpret that (void*), I incorrectly thought that it would maintain some sort of VFT-esque behavior.

The method I talked about as a potential solution would be something akin to:

class GameObject
{
public:
void DoThing() {}
};

class LIGameObject
{
public:
LIGameObject( GameObject* _target ) : m_Target(_target) {}
int Do( lua_State* _state ) { m_Target->DoThing(); }
... insert Luna binding code
private:
GameObject* m_Target;
};

int CreateObject( lua_State* _state )...
int main()...

DoSomething.lua:
obj = LIGameObject( CreateObject( "LuaScript" ) )
obj.Do()
Edited by SeiryuEnder

Share this post


Link to post
Share on other sites
Advertisement
I personally use tolua++. In C++, I will implement a factory class, something like this:


class Object
{
public:
// Don't bind constructor/destructor since we want objects to be managed by a factory

void foo();
static void bar();
};

class ObjectFactory
{
public:
ObjectFactory();
~ObjectFactory();

Object *createObject();
void destroyObject(Object *o);
};


Per the usage of tolua++, I'll process this header to generate the binding code. In Lua code, then, it is as simple to use as this:


factory=ObjectFactory();
object=factory:createObject();

object:foo()
object.bar()

factory:destroyObject(object)
object=nil

Share this post


Link to post
Share on other sites

I personally use tolua++. In C++, I will implement a factory class, something like this:


I started out trying ToLua++ and Luabind until I found out they both use the Boost libs. Because of the bulkiness I've tried to stay away from Boost but unfortunately I may have to bite the bullet on that one... I much prefer Boost+Type Safety to no Boost+Bad Design. Your implementation looks exactly like what I wanted to do in the first place, I guess I'll back up/revert my Luna code and start working on ToLua++ Edited by SeiryuEnder

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!