lua-users home
lua-l archive

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


If I understand well you have a C++ object that own a table. To keep a reference to the table, you put in the registry and keep the numerical index in the C++ object. And now from the table you want to find the C++ object that own it.
 
The way you do it is ok; but you only retrieve the numerical index (ref), not the C++ object. Instead you could put in the registry a pointer to your C++ object as a light userdata:

class Foo
{
public:
   Foo() : ref(0) { }
   int SetTable(lua_State* L, int index);
   int GetTable(lua_State* L);
   static Foo* GetObject(lua_State* L);
private:
   int ref;
};

// Take associated table from stack
int Foo::SetTable(lua_State* L)
{
   // Put table in registry
   lua_pushvalue(L, 1); // Duplicate table ref, use it as value
   this->ref = luaL_ref(L, LUA_REGISTRYINDEX);
   // Associate the table to this
   lua_pushvalue(L, 1); // Duplicate table ref, use it as key
   lua_pushlightuserdata(L, (void*)this); // Push this, us it as value
   lua_settable(L, LUA_REGISTRYINDEX);
   return 0;
}

// Push associated table on stack
int Foo::GetTable(lua_State* L)
{
   if (this->ref!=0)
   {
      // Get table from registry
      lua_pushvalue(L, this->ref);
      lua_gettable(L, LUA_REGISTRYINDEX);
      return 1;
   }
   else
   {
      return 0;
   }
}

// Find which object is associated to table on stack
Foo* Foo::GetObject(lua_State* L)
{
   // Get object from registry
   lua_pushvalue(L, 1); // Duplicate table ref, use it as key
   lua_gettable(L, LUA_REGISTRYINDEX);
   // gettable returned the light userdata corresponding to the C++ object
   return (Foo*)lua_touserdata(L, -1);
}

 
________________________________

De : lua-bounces@bazar2.conectiva.com.br [mailto:lua-bounces@bazar2.conectiva.com.br] De la part de Grellier, Thierry
Envoyé : 19 septembre 2006 06:31
À : Lua list
Objet : a luaL_mapref with a map semantic ?



Hello,

 

I've been using lua_ref as it is recommended to keep a reference to a table.

But my problem is that I'd like to find the C++ holder of the ref from another call. That is find which ref matches the table. I've been using this code: 

 

// find table

  lua_pushvalue(L, 1);

  lua_gettable(L, LUA_REGISTRYINDEX);

  int ref;

if lua_isnil(L, -1) {

// not found, create ref

    lua_pop(L, 1);

    lua_pushvalue(L, 1);

    ref = luaL_ref(L, LUA_REGISTRYINDEX);

// LUA_REGISTRYINDEX.table = ref

    lua_pushvalue(L, 1);

    lua_pushnumber(L, ref);

    lua_settable(L, LUA_REGISTRYINDEX);

} else {

// found : retrieve ref

    ref = (int) lua_tonumber(L, -1);

    lua_pop(L, 1);

}

 

But could it some better mechanisms ? And by the way does LUA_REGISTRYINDEX behaves as a weak table?