lua-users home
lua-l archive

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


John Dunn wrote:
> It appears to be working but since this is my first attempt at
> embedding lua I wanted to make sure I'm not doing something stupid.
> I'm sure I'm missing some error handling and whatnot but is the
> approach I'm taking the right one? Is there a better way? I've pasted
> my code below.    

The general principle of your code is ok. Some remarks below.

> #include <iostream>
> #include <lua/lauxlib.h>
> #include <lua/lualib.h>
> #include <lua/lua.h>
> 
> const char* MyObjectID = "Test.Object";
> const char* MyObjectClass = "Object";
> 
> static lua_State* L;
> 
> struct MyObject
> {
>   double value;
>   int handler;
>   int obj_id;

Rather than storing the object in the registry with an integer, you can simply use the object address as a lightuserdata as a key.

>   MyObject() : handler( 0 ), value( 23 ), obj_id(0)
>   {
>   }
>   void trigger()
>   {
>     lua_rawgeti(L, LUA_REGISTRYINDEX, handler );
>     lua_rawgeti(L, LUA_REGISTRYINDEX, obj_id );
>     lua_call( L, 1, 0 );
>   }

This function would become:

  void trigger()
  {
    lua_rawgeti(L, LUA_REGISTRYINDEX, handler);
    lua_pushlightuserdata(L, this);
    lua_rawget(L, LUA_REGISTRYINDEX);
    lua_call( L, 1, 0 );
  }

The add_object functions has to be modified accordingly, using lua_rawset instead of luaL_ref.

> };
> 
> [...]
> 
> static int add_handler( lua_State* lua ) {
>   MyObject* obj = objGet(lua);
>   if( lua_isfunction(lua,2))
>   {
>     //
>     lua_pushvalue( lua, 2 ); // dup the function and place it in the
>     registry obj->handler = luaL_ref(lua, LUA_REGISTRYINDEX);
>   }
>   else
>   {
>     std::cout << "NOT A FUNCTION!" << std::endl;
>   }
>   return 1;
> }

Rather than storing the handler in the registry, you could put it in the userdata environment table. This allows for more flexibility to have several named handlers.