[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Lua userdata question
- From: Philipp Janda <siffiejoe@...>
- Date: Sat, 09 Nov 2013 00:28:45 +0100
Am 08.11.2013 22:34 schröbte Geoff Smith:
local a = Foo.new()
a:setx(3) -- this works as per the example
a.fred = 123 <-- how do I get this to work
print(a.fred) <-- how do I get this to work
Any tips please on how I would change the C api code to make this work in the above example. My failed attempt I added a __newindex and __index into the Foo_meta table, and some associated C code.
The __newindex worked but the __index didn't work as I had overlooked the fact it was already pointing at the methods table.
You put a function instead of the methods table into the `__index` field
of the metatable. This function first tries to lookup a given key in the
methods table (which can be passed to the function via an upvalue), and
then compares the given key with the names of the struct fields to
return field values (or the other way around). I use the following code
for situations like this ...
static int dispatch( lua_State* L ) {
lua_CFunction pindex;
/* try method table first */
if( lua_istable( L, lua_upvalueindex( 1 ) ) ) {
lua_pushvalue( L, 2 ); /* duplicate key */
lua_rawget( L, lua_upvalueindex( 1 ) );
if( !lua_isnil( L, -1 ) )
return 1;
lua_pop( L, 1 );
}
pindex = lua_tocfunction( L, lua_upvalueindex( 2 ) );
return pindex( L );
}
void moon_propindex( lua_State* L, luaL_Reg const* methods,
int nups, lua_CFunction pindex ) {
int top = lua_gettop( L );
if( methods != NULL ) {
luaL_checkstack( L, nups + 3, "too many upvalues" );
lua_newtable( L );
for( ; methods->func; ++methods ) {
int i = 0;
for( i = 0; i < nups; ++i )
lua_pushvalue( L, top-nups+i+1 );
lua_pushcclosure( L, methods->func, nups );
lua_setfield( L, top+1, methods->name );
}
if( nups > 0 ) {
lua_replace( L, top-nups+1 );
lua_pop( L, nups-1 );
}
} else {
lua_pop( L, nups );
lua_pushnil( L );
}
if( pindex ) {
lua_pushcfunction( L, pindex );
lua_pushcclosure( L, dispatch, 2 );
}
}
`pindex` is a function that handles the struct fields by doing a series
of string comparisons[1] and pushing the corresponding value. The other
arguments are the same as for `luaL_setfuncs`[2].
[1]: http://lua-users.org/lists/lua-l/2013-03/msg00878.html
[2]: http://www.lua.org/manual/5.2/manual.html#luaL_setfuncs
Thanks for any help
Geoff
Philipp