Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef OROCOS_SIGNAL_TEMPLATE_HEADER_INCLUDED
00041 #define OROCOS_SIGNAL_TEMPLATE_HEADER_INCLUDED
00042 #include "SignalBase.hpp"
00043 #include "NA.hpp"
00044
00045 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE
00046 #ifndef USE_CPP11
00047 #include <boost/lambda/bind.hpp>
00048 #include <boost/bind.hpp>
00049 #include <boost/lambda/casts.hpp>
00050 #endif
00051 #else
00052 #include "../os/MutexLock.hpp"
00053 #endif
00054 #endif // !OROCOS_SIGNAL_TEMPLATE_HEADER_INCLUDED
00055
00056
00057 #define OROCOS_SIGNAL_N BOOST_JOIN(signal,OROCOS_SIGNATURE_NUM_ARGS)
00058 #define OROCOS_SIGNAL_CONNECTION_N BOOST_JOIN(connection,OROCOS_SIGNATURE_NUM_ARGS)
00059
00060
00061 namespace RTT {
00062
00063 namespace internal {
00064
00065 template<class SlotFunction>
00066 class OROCOS_SIGNAL_CONNECTION_N : public ConnectionBase
00067 {
00068 public:
00069 typedef SlotFunction slot_function;
00070 typedef SlotFunction function_type;
00071 OROCOS_SIGNATURE_TYPEDEFS
00072
00073 OROCOS_SIGNAL_CONNECTION_N(SignalBase* s, const slot_function& f)
00074 : ConnectionBase(s), func(f)
00075 {
00076 }
00077
00078 void emit(OROCOS_SIGNATURE_PARMS)
00079 {
00080 if (this->mconnected)
00081 func(OROCOS_SIGNATURE_ARGS);
00082 }
00083 private:
00084 slot_function func;
00085 };
00086
00087 template<typename R, OROCOS_SIGNATURE_TEMPLATE_PARMS OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS
00088 class SlotFunctionT = OROCOS_SIGNATURE_FUNCTION_N< R OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS OROCOS_SIGNATURE_TEMPLATE_ARGS> >
00089 class OROCOS_SIGNAL_N
00090 : public SignalBase
00091 {
00092 OROCOS_SIGNAL_N(const OROCOS_SIGNAL_N< R, OROCOS_SIGNATURE_TEMPLATE_ARGS OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS SlotFunctionT>& s);
00093
00094 public:
00095 typedef SlotFunctionT slot_function_type;
00096 typedef OROCOS_SIGNAL_CONNECTION_N<SlotFunctionT> connection_impl;
00097
00098 typedef R result_type;
00099 OROCOS_SIGNATURE_ARG_TYPES
00100
00101 #if OROCOS_SIGNATURE_NUM_ARGS == 1
00102 typedef arg1_type first_argument_type;
00103 #endif
00104 #if OROCOS_SIGNATURE_NUM_ARGS == 2
00105 typedef arg1_type first_argument_type;
00106 typedef arg2_type second_argument_type;
00107 #endif
00108 private:
00109 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE
00110
00111 static connection_impl* applyEmit( connection_t c ) {
00112 return static_cast<connection_impl*> (c.get() );
00113 }
00114 #endif
00115 public:
00116 OROCOS_SIGNAL_N()
00117 {
00118 }
00119
00120 Handle connect(const slot_function_type& f )
00121 {
00122 Handle h = this->setup(f);
00123 h.connect();
00124 return h;
00125 }
00126
00127 Handle setup(const slot_function_type& f )
00128 {
00129 connection_t conn(
00130 new connection_impl(this, f) );
00131 this->conn_setup( conn );
00132 return Handle(conn);
00133 }
00134
00135 R emit(OROCOS_SIGNATURE_PARMS)
00136 {
00137 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE
00138 this->emitting = true;
00139
00140
00141
00142
00143 #ifdef USE_CPP11
00144 mconnections.apply( bind(&connection_impl::emit,
00145 bind( &applyEmit, _1)
00146 #else
00147 mconnections.apply( boost::lambda::bind(&connection_impl::emit,
00148 boost::lambda::bind( &applyEmit, boost::lambda::_1)
00149
00150 #endif
00151 #if OROCOS_SIGNATURE_NUM_ARGS != 0
00152 ,OROCOS_SIGNATURE_ARGS
00153 #endif
00154 ) );
00155 this->emitting = false;
00156 #else
00157 os::MutexLock lock(m);
00158 if (this->emitting)
00159 return NA<R>::na();
00160 this->emitting = true;
00161 iterator it = mconnections.begin();
00162 const_iterator end = mconnections.end();
00163 for (; it != end; ++it ) {
00164 connection_impl* ci = static_cast<connection_impl*>( it->get() );
00165 if (ci)
00166 ci->emit(OROCOS_SIGNATURE_ARGS);
00167 }
00168 this->emitting = false;
00169 this->cleanup();
00170 #endif
00171 return NA<R>::na();
00172 }
00173
00174 R operator()(OROCOS_SIGNATURE_PARMS)
00175 {
00176 return this->emit(OROCOS_SIGNATURE_ARGS);
00177 }
00178
00179 R fire(OROCOS_SIGNATURE_PARMS)
00180 {
00181 return this->emit(OROCOS_SIGNATURE_ARGS);
00182 }
00183
00184 virtual int arity() const { return OROCOS_SIGNATURE_NUM_ARGS; }
00185 };
00186
00187 }}
00188
00189
00190 #undef OROCOS_SIGNAL_N
00191 #undef OROCOS_SIGNAL_CONNECTION_N
00192