1 #ifndef AWFUL_LUA_SIGNALCONNECT_H
2 #define AWFUL_LUA_SIGNALCONNECT_H
6 // TODO: be able to delete a signal connection (connect() should return a bundle of a signalref + slot handle
7 // wrapped in a userdata object with a disconnect method - or just a handle to the slot and
8 // then use object.FuckingSignal::disconnect(handle) - it would bring symmetry and harmony to the world
11 namespace awful
{ namespace LuaImpl
13 struct LuaSlotCallContext
15 LuaSlotCallContext() :
24 lua_pushlightuserdata( m_pLS
, this );
25 lua_gettable( m_pLS
, LUA_REGISTRYINDEX
);
28 template< typename category
, typename T
> void addParam( const T
& Param_
)
30 //std::cout << "lol add param: " << Param_ << std::endl;
31 TypeConverter
< category
, T
> tc( m_pLS
);
32 tc
.ConvertToLua( Param_
);
38 //std::cout << "lol call\n";
39 lua_call( m_pLS
, m_ParamCount
, 0 );
46 template< class C
, typename SigTag
> struct LuaSignalConnectWrapper
48 static int LuaCFunc( lua_State
* pLS
)
52 typedef typename signal_traits
< C
, SigTag
>::type signal_type
;
57 TypeConverter
< NormalType
, signal_type
> tc( pLS
);
58 tc
.template ConvertFromLua
< C
>( 1, pSignal
);
60 catch( const Error::TypeMismatch
& error
)
62 throw Error::BadMethodCall();
65 luaL_checktype( pLS
, 2, LUA_TFUNCTION
);
68 signal_traits
< C
, SigTag
>::template SlotWrapper
< LuaSlotCallContext
>
71 Pointer
< wrapper_type
> pWrapper
= new wrapper_type
;
72 pWrapper
->m_CallContext
.m_pLS
= pLS
;
74 // Copy the lua function in the lua registry so we can retrieve it
75 // when the signal is triggered.
76 lua_pushlightuserdata( pLS
, &pWrapper
->m_CallContext
);
77 lua_pushvalue( pLS
, 2 );
78 lua_settable( pLS
, LUA_REGISTRYINDEX
);
80 pSignal
->connect( static_cast< wrapper_type
*>( pWrapper
), &wrapper_type::Call
);
82 //std::cout << "lol connect\n";
84 catch( Error::Base
& error
)
86 error
.ConvertToLua( pLS
);