Reputation: 68043
I'm trying to use Lua Metatables to make a prettier interface to some internal C++ functions.
Here's my code that's working so far. (my.get
and my.set
are implemented in C++)
function setDefault(t)
local mt = {
__index = function(tab,k) return my.get(t,k) end,
__newindex = function(tab,k,v) return my.set(t,k,v) end
}
_G[t] = {}
setmetatable(_G[t],mt)
end
setDefault("LABEL")
LABEL.Text = "wibble" -- evaluates as my.set("LABEL","Text","wibble")
foo = LABEL.Text -- foo = my.get("LABEL","Text")
Fine so far. The next bit I want to make work is function calls on the table, like this:
LABEL.Flash(500) --must evaluate my.execute("LABEL","Flash", 500)
I know this invokes my.get("LABEL","Flash")
— and I can make that return a C++ function (using lua_pushcfunction
), but when the C++ function is called, it's missing the LABEL and Flash parameters.
Here's the C++ snippet of my.get
.
static int myGet(lua_State * l)
{
std::string p1(luaGetString(l, 1)); // table
std::string p2(luaGetString(l, 2)); // 'method'
if (isMethod(p1,p2))
{
lua_pushcfunction(l, myExec);
lua_pushvalue(l, 1); // re-push table
lua_pushvalue(l, 2); // re-push method
return 3;
}
else
{
// do my.get stuff here.
}
}
Upvotes: 1
Views: 451
Reputation: 68043
With a small change, I've got something that works: Push a C closure instead of a C function.
if (isMethod(p1,p2))
{
lua_pushvalue(l, 1); // re-push table
lua_pushvalue(l, 2); // re-push method
lua_pushcclosure(l, myExecClosure,2);
return 1;
}
myExecClosure
is like myExec
, but it reads the first two parameters via upvalues (e.g. luaupvaluindex(1)
) rather than from stack indexes 1 and 2.
Upvotes: 2