168 lines
6.0 KiB
C++
168 lines
6.0 KiB
C++
/*//////////////////////////////////////////////////////////////////////////////
|
|
// CMT Cosmic Muon Tomography project //////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
Copyright (c) 2014, Universita' degli Studi di Padova, INFN sez. di Padova
|
|
All rights reserved
|
|
|
|
Authors: Andrea Rigoni Garola < andrea.rigoni@pd.infn.it >
|
|
|
|
------------------------------------------------------------------
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 3.0 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library.
|
|
|
|
//////////////////////////////////////////////////////////////////////////////*/
|
|
|
|
#ifndef U_CORE_SIGNAL_H
|
|
#define U_CORE_SIGNAL_H
|
|
|
|
#include <boost/typeof/typeof.hpp>
|
|
|
|
#include <boost/signals2/signal.hpp>
|
|
#include <boost/signals2/signal_type.hpp>
|
|
#include <boost/signals2/slot.hpp>
|
|
|
|
#include "Function.h"
|
|
#include <boost/bind/bind.hpp>
|
|
|
|
using namespace boost::placeholders;
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// Signals macro //
|
|
|
|
#define default(vlaue)
|
|
#define slots
|
|
#define signals /*virtual void init_signals();*/ public
|
|
#define emit
|
|
#define SLOT(a) BOOST_STRINGIZE(a)
|
|
#define SIGNAL(a) BOOST_STRINGIZE(a)
|
|
|
|
#define _ULIB_DETAIL_SIGNAL_EMIT(_name, ...) \
|
|
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:
|
|
*
|
|
* // metodo standard con cast //
|
|
* SignalBase * sig = this->findSignal((void (Ob1::*)(void))&Ob1::V0);
|
|
* typedef Signal<void()>::type SigT;
|
|
* if(sig) reinterpret_cast<SigT*>(sig)->operator()();
|
|
*
|
|
* // cast automatico //
|
|
* static BOOST_AUTO(sig,this->findOrAddSignal(&Ob1::V0));
|
|
* sig->operator()();
|
|
*/
|
|
#define ULIB_SIGNAL_EMIT(_name, ...) \
|
|
_ULIB_DETAIL_SIGNAL_EMIT(_name, __VA_ARGS__)
|
|
|
|
namespace uLib {
|
|
|
|
// A boost::signal wrapper structure ///////////////////////////////////////////
|
|
|
|
// TODO ...
|
|
|
|
typedef boost::signals2::signal_base SignalBase;
|
|
|
|
template <typename T> struct Signal {
|
|
typedef boost::signals2::signal<T> type;
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace detail {
|
|
|
|
template <typename FuncT, typename SigSignature, int arity>
|
|
struct ConnectSignal {};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(slof);
|
|
}
|
|
};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver));
|
|
}
|
|
};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(boost::bind(slof, receiver, _1));
|
|
}
|
|
};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(
|
|
boost::bind(slof, receiver, _1, _2));
|
|
}
|
|
};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(
|
|
boost::bind(slof, receiver, _1, _2, _3));
|
|
}
|
|
};
|
|
|
|
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<SigSignature>::type SigT;
|
|
reinterpret_cast<SigT *>(sigb)->connect(
|
|
boost::bind(slof, receiver, _1, _2, _3, _4));
|
|
}
|
|
};
|
|
|
|
} // namespace detail
|
|
|
|
template <typename FuncT> SignalBase *NewSignal(FuncT f) {
|
|
return new
|
|
typename Signal<typename FunctionPointer<FuncT>::SignalSignature>::type;
|
|
}
|
|
|
|
template <typename SigSignature, typename FuncT>
|
|
void ConnectSignal(SignalBase *sigb, FuncT slof,
|
|
typename FunctionPointer<FuncT>::Object *receiver) {
|
|
detail::ConnectSignal<FuncT, SigSignature,
|
|
FunctionPointer<FuncT>::arity>::connect(sigb, slof,
|
|
receiver);
|
|
}
|
|
|
|
} // namespace uLib
|
|
|
|
#endif // SIGNAL_H
|