/*////////////////////////////////////////////////////////////////////////////// // 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 #include #include #include #include "Function.h" #include 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::type SigT; * if(sig) reinterpret_cast(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 struct Signal { typedef boost::signals2::signal type; }; //////////////////////////////////////////////////////////////////////////////// namespace detail { template struct ConnectSignal {}; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect(slof); } }; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect(boost::bind(slof, receiver)); } }; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect(boost::bind(slof, receiver, _1)); } }; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect( boost::bind(slof, receiver, _1, _2)); } }; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect( boost::bind(slof, receiver, _1, _2, _3)); } }; template struct ConnectSignal { static void connect(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { typedef typename Signal::type SigT; reinterpret_cast(sigb)->connect( boost::bind(slof, receiver, _1, _2, _3, _4)); } }; } // namespace detail template SignalBase *NewSignal(FuncT f) { return new typename Signal::SignalSignature>::type; } template void ConnectSignal(SignalBase *sigb, FuncT slof, typename FunctionPointer::Object *receiver) { detail::ConnectSignal::arity>::connect(sigb, slof, receiver); } } // namespace uLib #endif // SIGNAL_H