lua-users home
lua-l archive

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


Shea Martin wrote:

> Sorry to be dense, but I am still not following.
> lua_pushstring( vm, "Event:log" );
> lua_pushcclosure( vm, l_event_log, 0 );
> lua_settable( vm, -3 );
> lua_pushstring( vm, "Event:name" );
> lua_pushstring( vm, eventname );
> lua_settable( vm, -3 );

The code above is the same as saying

mt["Event:log"] = l_event_log
mt["Event:name"] = event_name

Note that luaL_newmetatable() places the table's name in the registry,
not in the global table, so 'mt' above is really just the anonymous
table that's left on the top of the stack.

These are understandable newbie mistakes. Just (re)read the sections of
PiL that contain C examples - chapters 25 and 26 in particular. Also,
you may want to (re)read the section on methods (the ':' syntactical
sugar), chapter 16. Note that ':' only works for function calls.

What you really want is a function with key "log", and a string with key
"name" to hold the name field. I suspect that what you *really* want is
the 'name' field to be present in an instance of an event, not in the
class (table "Event" plus its metatable).

// Untested...
// Create global table to hold "Event".
lua_newtable( vm);

// Create metatable.
luaL_newmetatable( vm, "Event.mt");
lua_pushstring( vm, "log" );
lua_pushcclosure( vm, l_event_log, 0 );  // Need a closure?
lua_settable( vm, -3 );

lua_pushvalue( vm, -2);    // Get copy of table Event to top.
lua_setfield( vm, -2, "__index");  // mt.__index = Event

lua_setmetatable( vm, -2);  // Attach metatable.

lua_pushcfunction( vm, l_event_new);  // Sample below.
lua_setfield( vm, -2, "new");
lua_setglobal( vm, "Event");   // Put main table in module.

Most likely you will also need some sort of mechanism for creating
objects of that type. I called that 'new' above. In that function you
will use luaL_getmetatable() to retrieve the metatable by name from the
registry, then you'll attach that to a new table, possibly like this
(untested):

int l_event_new(lua_State* L, const char* event_name)
{
  lua_newtable(L);                    // local obj = {}
  luaL_getmetatable(L, "Event.mt");   // setmetatable(obj, mt)
  lua_setmetatable(L, -2);
  lua_pushstring(L, event_name);     // obj.name = event_name
  lua_settable(L, -2, "name");
  return 1;                           // return obj
}

-- In Lua:
ev = Event.new('attack')
ev:log()

Those are some untested hints. You may want to invest the time (it's not
too long) to understand what is happening in the Lua-only version of
this, then see how it is implemented using the C API. It may be that
'log' should be a global function rather than an object method.

Good luck!

Doug

-- 
Innovative Concepts, Inc. www.innocon.com 703-893-2007 x220