feat: fix signaling and implement a ping-pong signal/slot test

This commit is contained in:
AndreaRigoni
2026-02-28 08:58:04 +00:00
parent d56758d0b3
commit 07915295cb
5 changed files with 112 additions and 91 deletions

View File

@@ -50,8 +50,11 @@ using namespace boost::placeholders;
#define SIGNAL(a) BOOST_STRINGIZE(a)
#define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
static BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
sig->operator()(__VA_ARGS__);
do { \
BOOST_AUTO(sig, this->findOrAddSignal(&_name)); \
if (sig) \
sig->operator()(__VA_ARGS__); \
} while (0)
/**
* Utility macro to implement signal emission implementa una delle seguenti:
@@ -84,66 +87,61 @@ template <typename T> struct Signal {
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
reinterpret_cast<SigT *>(sigb)->connect(
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
reinterpret_cast<SigT *>(sigb)->connect(
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,
typename FunctionPointer<FuncT>::Object *receiver) {
typedef
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type
SigT;
typedef typename Signal<SigSignature>::type SigT;
reinterpret_cast<SigT *>(sigb)->connect(
boost::bind(slof, receiver, _1, _2, _3, _4));
}
@@ -152,15 +150,16 @@ template <typename FuncT> struct ConnectSignal<FuncT, 5> {
} // namespace detail
template <typename FuncT> SignalBase *NewSignal(FuncT f) {
// seems to work wow !
return new Signal<void()>::type;
return new
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type;
}
template <typename FuncT>
template <typename SigSignature, typename FuncT>
void ConnectSignal(SignalBase *sigb, FuncT slof,
typename FunctionPointer<FuncT>::Object *receiver) {
detail::ConnectSignal<FuncT, FunctionPointer<FuncT>::arity>::connect(
sigb, slof, receiver);
detail::ConnectSignal<FuncT, SigSignature,
FunctionPointer<FuncT>::arity>::connect(sigb, slof,
receiver);
}
} // namespace uLib