Aidez moi à alléger ce code plz :\ (variadic templ, macros)
Plop !
Voici le code:
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| #include <iostream>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <vector>
template< typename ret, typename... Args >
class Slot
{
typedef boost::function< ret( Args... ) > SlotFunc;
public:
Slot( SlotFunc& f ) :
cb(f)
{
}
ret operator()( const Args&... args ) const
{
return cb( args... );
}
SlotFunc& cb;
};
template< typename ret, typename... Args >
class Signal
{
typedef Slot< ret, Args... > ConnectableSlot;
typedef std::vector< ConnectableSlot* > SlotVector;
public:
void operator()( const Args&... args ) const
{
for( typename SlotVector::const_iterator it = m_Listeners.begin(); it != m_Listeners.end(); ++it )
{
(*(*it))( args... );
}
}
void Connect( ConnectableSlot& slot )
{
m_Listeners.push_back(&slot);
}
SlotVector m_Listeners;
};
class A
{
public:
A()
{
}
void SayHello()
{
SayHelloSignal( "Hello from A" );
}
Signal< void, const std::string& > SayHelloSignal;
};
class B
{
public:
B( int id ) :
OnHelloFct( boost::bind( &B::OnHello, this, _1 ) ),
OnHelloSlot( OnHelloFct ),
id_(id)
{
}
void OnHello( const std::string& str )
{
std::cout << id_ << " Received OnHello signal : " << str << std::endl;
}
boost::function< void( const std::string& ) > OnHelloFct;
Slot< void, const std::string& > OnHelloSlot;
int id_;
};
int main()
{
A a;
B b(1);
B c(2);
a.SayHelloSignal.Connect( b.OnHelloSlot );
a.SayHelloSignal.Connect( c.OnHelloSlot );
a.SayHello();
return 0;
} |
Comme vous le voyez, pour les signals, ça va, mais pour les slots, je dois me farcir 3 déclarations par slot !
- La fonction qui est appelée par le slot
- Un boost::function pour réunir la fonction et le slot
- Le slot
Le truc qui m'embête, c'est qu'ils sont très sensiblement pareil et ça va carrément me rendre malade de me tapper à chaque fois 5 lignes par création de slot ( 3 pour les déclarations, 2 pour l'initialisation ).
Or, comme vous le voyez, j'utilise les variadic templates, et boost::mpl ne supporte pas, en tout cas j'arrive pas à trouver comment faire :\
J'ai tenté avec des #define, mais le problème sur lequel je tombe sur le problème des déclarations différentes...
Code:
1 2 3
| boost::function< ret( args...) >
slot< ret, args... >
ret func( args... ) |
J'aimerais également pouvoir initialiser automatiquement le slot et le boost::function, vu que c'est un code très redondant, ça doit être possible. Je ne vois absolument pas comment faire pour m'en sortir avec les variadic templates et le _1, _2, _3 de boost::function pour les paramètres...
Je vois pas trop comment faire :\
Merci d'avance :)