andrea-dev #1
@@ -116,16 +116,15 @@ public:
|
|||||||
connect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf,
|
connect(typename FunctionPointer<Func1>::Object *sender, Func1 sigf,
|
||||||
typename FunctionPointer<Func2>::Object *receiver, Func2 slof) {
|
typename FunctionPointer<Func2>::Object *receiver, Func2 slof) {
|
||||||
SignalBase *sigb = sender->findOrAddSignal(sigf);
|
SignalBase *sigb = sender->findOrAddSignal(sigf);
|
||||||
typedef boost::signals2::signal<
|
ConnectSignal<typename FunctionPointer<Func1>::SignalSignature>(sigb, slof,
|
||||||
typename FunctionPointer<Func2>::SignalSignature>
|
receiver);
|
||||||
SigT;
|
|
||||||
ConnectSignal(sigb, slof, receiver);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FuncT>
|
template <typename FuncT>
|
||||||
static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) {
|
static inline bool connect(SignalBase *sigb, FuncT slof, Object *receiver) {
|
||||||
ConnectSignal(sigb, slof, receiver);
|
ConnectSignal<typename FunctionPointer<FuncT>::SignalSignature>(sigb, slof,
|
||||||
|
receiver);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,11 @@ using namespace boost::placeholders;
|
|||||||
#define SIGNAL(a) BOOST_STRINGIZE(a)
|
#define SIGNAL(a) BOOST_STRINGIZE(a)
|
||||||
|
|
||||||
#define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
|
#define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
|
||||||
static BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
|
do { \
|
||||||
sig->operator()(__VA_ARGS__);
|
BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
|
||||||
|
if (sig) \
|
||||||
|
sig->operator()(__VA_ARGS__); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility macro to implement signal emission implementa una delle seguenti:
|
* Utility macro to implement signal emission implementa una delle seguenti:
|
||||||
@@ -84,66 +87,61 @@ template <typename T> struct Signal {
|
|||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <typename FuncT, int arity> struct ConnectSignal {};
|
template <typename FuncT, typename SigSignature, int arity>
|
||||||
|
struct ConnectSignal {};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 0> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 0> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(slof);
|
reinterpret_cast<SigT *>(sigb)->connect(slof);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 1> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 1> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver));
|
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 2> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 2> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver, _1));
|
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver, _1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 3> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 3> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(
|
reinterpret_cast<SigT *>(sigb)->connect(
|
||||||
boost::bind(slof, receiver, _1, _2));
|
boost::bind(slof, receiver, _1, _2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 4> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 4> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(
|
reinterpret_cast<SigT *>(sigb)->connect(
|
||||||
boost::bind(slof, receiver, _1, _2, _3));
|
boost::bind(slof, receiver, _1, _2, _3));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename FuncT> struct ConnectSignal<FuncT, 5> {
|
template <typename FuncT, typename SigSignature>
|
||||||
|
struct ConnectSignal<FuncT, SigSignature, 5> {
|
||||||
static void connect(SignalBase *sigb, FuncT slof,
|
static void connect(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
typedef
|
typedef typename Signal<SigSignature>::type SigT;
|
||||||
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
|
|
||||||
SigT;
|
|
||||||
reinterpret_cast<SigT *>(sigb)->connect(
|
reinterpret_cast<SigT *>(sigb)->connect(
|
||||||
boost::bind(slof, receiver, _1, _2, _3, _4));
|
boost::bind(slof, receiver, _1, _2, _3, _4));
|
||||||
}
|
}
|
||||||
@@ -152,15 +150,16 @@ template <typename FuncT> struct ConnectSignal<FuncT, 5> {
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <typename FuncT> SignalBase *NewSignal(FuncT f) {
|
template <typename FuncT> SignalBase *NewSignal(FuncT f) {
|
||||||
// seems to work wow !
|
return new
|
||||||
return new Signal<void()>::type;
|
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename FuncT>
|
template <typename SigSignature, typename FuncT>
|
||||||
void ConnectSignal(SignalBase *sigb, FuncT slof,
|
void ConnectSignal(SignalBase *sigb, FuncT slof,
|
||||||
typename FunctionPointer<FuncT>::Object *receiver) {
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
||||||
detail::ConnectSignal<FuncT, FunctionPointer<FuncT>::arity>::connect(
|
detail::ConnectSignal<FuncT, SigSignature,
|
||||||
sigb, slof, receiver);
|
FunctionPointer<FuncT>::arity>::connect(sigb, slof,
|
||||||
|
receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace uLib
|
} // namespace uLib
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ set( TESTS
|
|||||||
UuidTest
|
UuidTest
|
||||||
TypeIntrospectionTraversal
|
TypeIntrospectionTraversal
|
||||||
OptionsTest
|
OptionsTest
|
||||||
|
PingPongTest
|
||||||
)
|
)
|
||||||
|
|
||||||
set(LIBRARIES
|
set(LIBRARIES
|
||||||
|
|||||||
52
src/Core/testing/PingPongTest.cpp
Normal file
52
src/Core/testing/PingPongTest.cpp
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
#include "Core/Object.h"
|
||||||
|
#include "Core/Signal.h"
|
||||||
|
#include "testing-prototype.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace uLib;
|
||||||
|
|
||||||
|
class Ping : public Object {
|
||||||
|
public:
|
||||||
|
signals:
|
||||||
|
void PingSignal(int count);
|
||||||
|
public slots:
|
||||||
|
void OnPong(int count) {
|
||||||
|
std::cout << "Ping received Pong " << count << std::endl;
|
||||||
|
if (count > 0)
|
||||||
|
ULIB_SIGNAL_EMIT(Ping::PingSignal, count - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Ping::PingSignal(int count) { ULIB_SIGNAL_EMIT(Ping::PingSignal, count); }
|
||||||
|
|
||||||
|
class Pong : public Object {
|
||||||
|
public:
|
||||||
|
signals:
|
||||||
|
void PongSignal(int count);
|
||||||
|
public slots:
|
||||||
|
void OnPing(int count) {
|
||||||
|
std::cout << "Pong received Ping " << count << std::endl;
|
||||||
|
if (count > 0)
|
||||||
|
ULIB_SIGNAL_EMIT(Pong::PongSignal, count - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void Pong::PongSignal(int count) { ULIB_SIGNAL_EMIT(Pong::PongSignal, count); }
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
BEGIN_TESTING(PingPong);
|
||||||
|
Ping ping;
|
||||||
|
Pong pong;
|
||||||
|
|
||||||
|
std::cout << "Connecting ping to pong" << std::endl;
|
||||||
|
Object::connect(&ping, &Ping::PingSignal, &pong, &Pong::OnPing);
|
||||||
|
|
||||||
|
std::cout << "Connecting pong to ping" << std::endl;
|
||||||
|
Object::connect(&pong, &Pong::PongSignal, &ping, &Ping::OnPong);
|
||||||
|
|
||||||
|
std::cout << "Emitting PingSignal(5)" << std::endl;
|
||||||
|
ping.PingSignal(5);
|
||||||
|
|
||||||
|
END_TESTING;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
@@ -23,93 +23,63 @@
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////*/
|
//////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
|
||||||
|
|
||||||
#include "testing-prototype.h"
|
|
||||||
#include "Core/Types.h"
|
|
||||||
#include "Core/Object.h"
|
#include "Core/Object.h"
|
||||||
#include "Core/Signal.h"
|
#include "Core/Signal.h"
|
||||||
|
#include "Core/Types.h"
|
||||||
|
#include "testing-prototype.h"
|
||||||
|
|
||||||
using namespace uLib;
|
using namespace uLib;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Ob1 : public Object {
|
class Ob1 : public Object {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void V0();
|
void V0();
|
||||||
|
|
||||||
int V1(int a);
|
|
||||||
|
|
||||||
|
void V1(int a);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// should be done by moc //
|
// should be done by moc //
|
||||||
void Ob1::V0() {
|
void Ob1::V0() { ULIB_SIGNAL_EMIT(Ob1::V0); }
|
||||||
ULIB_SIGNAL_EMIT(Ob1::V0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int Ob1::V1(int a) {
|
|
||||||
ULIB_SIGNAL_EMIT(Ob1::V1,a);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Ob1::V1(int a) { ULIB_SIGNAL_EMIT(Ob1::V1, a); }
|
||||||
|
|
||||||
class Ob2 : public Object {
|
class Ob2 : public Object {
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void PrintV0() {
|
void PrintV0() { std::cout << "Ob2 prints V0\n" << std::flush; }
|
||||||
std::cout << "Ob2 prints V0\n" << std::flush;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Ob3 : public Object {
|
class Ob3 : public Object {
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void PrintV0() {
|
void PrintV0() { std::cout << "Ob3 prints V0\n" << std::flush; }
|
||||||
std::cout << "Ob3 prints V0\n" << std::flush;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintNumber(int n) {
|
void PrintNumber(int n) {
|
||||||
std::cout << "Ob3 is printing number: " << n << "\n";
|
std::cout << "Ob3 is printing number: " << n << "\n";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
BEGIN_TESTING(Signals);
|
BEGIN_TESTING(Signals);
|
||||||
|
|
||||||
Ob1 ob1;
|
Ob1 ob1;
|
||||||
Ob2 ob2;
|
Ob2 ob2;
|
||||||
Ob3 ob3;
|
Ob3 ob3;
|
||||||
|
|
||||||
Object::connect(&ob1,&Ob1::V0,&ob2,&Ob2::PrintV0);
|
Object::connect(&ob1, &Ob1::V0, &ob2, &Ob2::PrintV0);
|
||||||
Object::connect(&ob1,&Ob1::V0,&ob3,&Ob3::PrintV0);
|
Object::connect(&ob1, &Ob1::V0, &ob3, &Ob3::PrintV0);
|
||||||
Object::connect(&ob1,&Ob1::V1,&ob3,&Ob3::PrintNumber);
|
Object::connect(&ob1, &Ob1::V1, &ob3, &Ob3::PrintNumber);
|
||||||
|
|
||||||
// not working yet
|
// not working yet
|
||||||
// Object::connect(&ob1,SIGNAL(V0(),&ob2,SLOT(PrintV0())
|
// Object::connect(&ob1,SIGNAL(V0(),&ob2,SLOT(PrintV0())
|
||||||
|
|
||||||
ob1.PrintSelf(std::cout);
|
ob1.PrintSelf(std::cout);
|
||||||
|
|
||||||
emit ob1.V0();
|
emit ob1.V0();
|
||||||
emit ob1.V1(5552368);
|
emit ob1.V1(5552368);
|
||||||
|
|
||||||
END_TESTING;
|
END_TESTING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user