2008/11/20 Michael Bauroth <Michael.Bauroth@falcom.de>:
Hi,
I've implemented a working simple callback system between Lua and C++ (Lunar
based). But now I have problems to implement some more sophisticated
features. Google didn't help so far, but eventually can someone can give me
some short hints, links or samples for the following
features ...
My code looks like this at the moment (Questions are located below):
Lua:
function onmousemove( comp )
comp:doSomthing()
end
btn = Button:new()
btn.Callback = { onmousemove, 1 }; // will call SetCallback(L)
C++:
LRESULT FComponent::OnMouseMove( int x, int y )
{
if ( m_CbOnMouseMove )
{
// Call lua function by stored Reference
lua_State* L = GetLuaInstance();
lua_pushvalue(L, 1);
// push function
lua_rawgeti( L, LUA_REGISTRYINDEX, m_CbOnMouseMove );
// push parameter(s)
pushLuaObject( L );
// call function
lua_pcall( L, 1, LUA_MULTRET, 0 )
return 0;
}
return 1L;
}
int FComponent::SetCallback( lua_State *L )
{
luaL_checktype( L, 1, LUA_TTABLE );
lua_rawgeti( L, 1, 1 );
int tType = lua_tonumber( L, -1 );
lua_pop(L, 1);
lua_rawgeti(L, 1, 2);
int tCb = luaL_ref( L, LUA_REGISTRYINDEX );
lua_pop(L, 1);
switch ( tType )
{
case 1:
m_CbOnMouseMove = tCb;
break;
...
}
lua_pop( L, lua_gettop( L ) );
return 0;
}
Question 1:
How can I register a callback with a optional parameter, e.g., if Button 3
is pressed, call onmousedown with value 3.
sample:
function onmousedown( number )
print( number )
end
btn1 = Button:new()
btn1.Callback = { onmousedown( 1 ), 1 }
btn2 = Button:new()
btn2.Callback = { onmousedown( 2 ), 1 }
Try this:
btn1.Callback = { function() onmousedown( 1 ) end, 1 }
btn2.Callback = { function() onmousedown( 2 ) end, 1 }
Lua has closures, use them.
Question2:
How can I pass more than one parameter (e.g. table based) from C++ side to
Lua for callbacks (see above FComponent::OnMouseMove )
sample:
function onmousedown( event )
print( event[ "x" ] )
print( event[ "y" ] )
print( event[ "component" ] )
end
Try this (note that the lua_pushvalue(L, 1) is unnecessary, you can remove it):
LRESULT FComponent::OnMouseMove( int x, int y )
{
if ( m_CbOnMouseMove )
{
// Call lua function by stored Reference
lua_State* L = GetLuaInstance();
//lua_pushvalue(L, 1); // this line is unnecessary
// push function
lua_rawgeti( L, LUA_REGISTRYINDEX, m_CbOnMouseMove );
// push parameter(s)
lua_createtable(L, 0, 3);
lua_pushnumber(L, x); lua_setfield(L, -2, "x");
lua_pushnumber(L, y); lua_setfield(L, -2, "y");
pushLuaObject( L ); lua_setfield(L, -2, "component");
// call function
lua_pcall( L, 1, LUA_MULTRET, 0 )
return 0;
}
}