lua-users home
lua-l archive

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


Another log in the fire:

I use a C++ binding, in which every bound class has a static const char * name member (I also use the char * for reflection purposes). The bound class metatable has the const char * (stored as a lightuserdata, not a string for efficiency), as a key, and true as a value. This means that I can support multiple inheritance by pushing each superclass name to the metatable.

Potentially I could store something other than true as the value, perhaps something more useful, but so far I haven't found the need.

The code looks something like this (not complete, but you get the idea):

template <class T>
bool isUsertype(lua_State * L, int idx)
{
	if (lua_isuserdata(L, idx) && lua_getmetatable(L, idx))
	{
lua_pushlightuserdata(L, (void *)T::name); // lightuserdata lookup seems to be a lot faster than string lookup
		lua_rawget(L, -2);
		if (!lua_isnil(L, -1)) {
			lua_pop(L, 2);
			return true;
		} else {
			printf("doesInherit error: %s\n", T::name);
		}
		lua_pop(L, 1);
	}
	return false;
}

// add an inheritance key to a metatable (assumes metatable is on the stack)
template <class T>
void inherit(lua_State * L)
{
	lua_pushlightuserdata(L, (void *)T::name);
	lua_pushboolean(L, true);
	lua_settable(L, -3);
}



// example

class Foo
{
	static const char * name;
};

const char * Foo :: name = "Foo";


// sometime later:

printf("stack top is Foo ? %i\n", isUsertype<Foo>(L, -1) );

On Mar 13, 2007, at 5:41 AM, Mike Pall wrote:

Hi,

Lothar Scholz wrote:
At the moment i'm using an hash table for all my own userdata,
lookup the pointer there and if found i get a verification that this
userdata is really a "Foobar" struct.

No hash lookups required if you do it right:

  http://lua-users.org/lists/lua-l/2004-07/msg00369.html

Bye,
     Mike