lua-users home
lua-l archive

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


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;
   }
}