lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


Hi Jose,

On Monday 21 February 2005 09:32 am, Jose Marin wrote:
> My actors have a struct like this:
>
> struct Actor{
>   ... Some fields ...
>   Function OnCollide;
>   ... Other events
> };
>
> monsterOgre.OnCollide = ogreCollide
>
> How do I create a header for tolua handle this?
> I've read the docs, but couldn't find how...

is OnCollide *always* a Lua function, for any class and any instance? If yes, 
then the simplest way is to do something like this (untested):

int C_set_collision_function(lua_State *L)
{
  Actor *a = (Actor *) lua_touserdata(L, 1);
  lua_pushvalue(L, 2);
  a->function_ref = lua_ref(L, 1); 
  return 0;
}

lua_register(L, "set_collision_function", C_set_collision_function);

and to call the collision function from C++, you do something like this:

void call_collision_function(lua_State *L, Actor *a)
{
  lua_getref(L, a->function_ref);
  lua_pcall(L, 0, 0, 0);
}

Then you set the collision function from Lua like this:

set_collision_function(monsterOgre, orgeCollide)

You need to release the reference when the actor is destroyed, so you also put 
something like this in the destructor:

Actor::~Actor()
{
  lua_unref(L, function_ref);
}


Now, if onCollide also must be permitted to be a C function, things get a lot 
more complicated. In this case your best bet is to write an abstract base 
class that wraps a collision function:

class Wrapper {
public:
 ...
 virtual call() = 0;
};

 Make two subclasses, one that calls a Lua function, and another that calls a 
C++ function. For the Lua subclass, you proceed like in the example above. 
For the C++ subclass, just have call() forward to the appropriate function.

Hope this helps
- Christian