lua-users home
lua-l archive

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


Hi,

this must be something frustratingly simple, but neither googling nor reading the docs nor stupid trial-and-error seems to make this work. Maybe any of you can help? I'm trying to create an object (full userdata containing a pointer to a C++ object) that has instance methods defined in C (using a metatable in __index), automatically deletes the associated C++ object (using __gc) and prints something sensible when tostring() is used on it. Trouble is, neither tostring () nor the destructor call work. Anybody know what the mistake in my library init method is?

// "Room" class methods:
static const struct luaL_reg gRoomMethodTable[] =
{
    { "new", UKAdventureNewRoom },
    { NULL, NULL }  /* sentinel */
};


// "Room" instance methods:
static const struct luaL_reg gRoomMetaTable[] =
{
    { "__tostring", UKAdventureRoomToString },
    { "__gc", UKAdventureDeleteRoom },
    { NULL, NULL }  /* sentinel */
};


int        PACEmaker_luaopen( lua_State *pLuaState )
{
    // Init the "adventure" class:
    luaL_openlib( pLuaState, "Adventure", gAdventureTable, 0 );

    // Init the "room" class:
luaL_openlib( pLuaState, "Room", gRoomMethodTable, 0 ); // Install class methods and define "Room" main class.

    luaL_newmetatable( pLuaState, "PACEmaker.Room" );

// Install an index table that provides the array.something methods:
    lua_pushstring( pLuaState, "__index" );
    lua_pushvalue( pLuaState, -2 );            // pushes the metatable.
lua_settable( pLuaState, -3 ); // metatable.__index = metatable.

luaL_openlib( pLuaState, NULL, gRoomMetaTable, 0 ); // Install instance methods.

    luaL_getmetatable( pLuaState, "PACEmaker.Room" );
    lua_pushstring( pLuaState, "__gc" );
    lua_pushcfunction( pLuaState, UKAdventureDeleteRoom );
    lua_settable( pLuaState, -3 );

    luaL_getmetatable( pLuaState, "PACEmaker.Room" );
    lua_pushstring( pLuaState, "__tostring" );
    lua_pushcfunction( pLuaState, UKAdventureRoomToString );
    lua_settable( pLuaState, -3 );

    return 0;
}

When it didn't work, I tried adding those luaL_getmetatable calls, but it still didn't work. Even when I allocate and nil 100 objects, they never get deleted, and whenever I tostring() a "Room" subclass, it gives an error about concatenating a table :-( I tried some permutations of the code in the docs, but there's only separate examples of __index and __gc, and I seem to fail when it comes to combining them.

 Thanks for any clues, pointers to docs, sample code etc.

Cheers,
-- M. Uli Kusterer
http://www.zathras.de