[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Working with Lua callbacks and more than one parameter in both directions
- From: "Jerome Vuarand" <jerome.vuarand@...>
- Date: Thu, 20 Nov 2008 10:46:31 +0100
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;
}
}