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 #include <boost/lambda/bind.hpp>
00047 #include <boost/bind.hpp>
00048 #include <boost/lambda/casts.hpp>
00049 #else
00050 #include "../os/MutexLock.hpp"
00051 #endif
00052 #endif // !OROCOS_SIGNAL_TEMPLATE_HEADER_INCLUDED
00053
00054
00055 #define OROCOS_SIGNAL_N BOOST_JOIN(signal,OROCOS_SIGNATURE_NUM_ARGS)
00056 #define OROCOS_SIGNAL_CONNECTION_N BOOST_JOIN(connection,OROCOS_SIGNATURE_NUM_ARGS)
00057
00058
00059 namespace RTT {
00060
00061 namespace internal {
00062
00063 template<class SlotFunction>
00064 class OROCOS_SIGNAL_CONNECTION_N : public ConnectionBase
00065 {
00066 public:
00067 typedef SlotFunction slot_function;
00068 typedef SlotFunction function_type;
00069 OROCOS_SIGNATURE_TYPEDEFS
00070
00071 OROCOS_SIGNAL_CONNECTION_N(SignalBase* s, const slot_function& f)
00072 : ConnectionBase(s), func(f)
00073 {
00074 }
00075
00076 void emit(OROCOS_SIGNATURE_PARMS)
00077 {
00078 if (this->mconnected)
00079 func(OROCOS_SIGNATURE_ARGS);
00080 }
00081 private:
00082 slot_function func;
00083 };
00084
00085 template<typename R, OROCOS_SIGNATURE_TEMPLATE_PARMS OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS
00086 class SlotFunctionT = OROCOS_SIGNATURE_FUNCTION_N< R OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS OROCOS_SIGNATURE_TEMPLATE_ARGS> >
00087 class OROCOS_SIGNAL_N
00088 : public SignalBase
00089 {
00090 OROCOS_SIGNAL_N(const OROCOS_SIGNAL_N< R, OROCOS_SIGNATURE_TEMPLATE_ARGS OROCOS_SIGNATURE_COMMA_IF_NONZERO_ARGS SlotFunctionT>& s);
00091
00092 public:
00093 typedef SlotFunctionT slot_function_type;
00094 typedef OROCOS_SIGNAL_CONNECTION_N<SlotFunctionT> connection_impl;
00095
00096 typedef R result_type;
00097 OROCOS_SIGNATURE_ARG_TYPES
00098
00099 #if OROCOS_SIGNATURE_NUM_ARGS == 1
00100 typedef arg1_type first_argument_type;
00101 #endif
00102 #if OROCOS_SIGNATURE_NUM_ARGS == 2
00103 typedef arg1_type first_argument_type;
00104 typedef arg2_type second_argument_type;
00105 #endif
00106 private:
00107 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE
00108
00109 static connection_impl* applyEmit( connection_t c ) {
00110 return static_cast<connection_impl*> (c.get() );
00111 }
00112 #endif
00113 public:
00114 OROCOS_SIGNAL_N()
00115 {
00116 }
00117
00118 Handle connect(const slot_function_type& f )
00119 {
00120 Handle h = this->setup(f);
00121 h.connect();
00122 return h;
00123 }
00124
00125 Handle setup(const slot_function_type& f )
00126 {
00127 connection_t conn(
00128 new connection_impl(this, f) );
00129 this->conn_setup( conn );
00130 return Handle(conn);
00131 }
00132
00133 R emit(OROCOS_SIGNATURE_PARMS)
00134 {
00135 #ifdef ORO_SIGNAL_USE_LIST_LOCK_FREE
00136 this->emitting = true;
00137
00138
00139
00140
00141 mconnections.apply( boost::lambda::bind(&connection_impl::emit,
00142 boost::lambda::bind( &applyEmit, boost::lambda::_1)
00143
00144 #if OROCOS_SIGNATURE_NUM_ARGS != 0
00145 ,OROCOS_SIGNATURE_ARGS
00146 #endif
00147 ) );
00148 this->emitting = false;
00149 #else
00150 os::MutexLock lock(m);
00151 if (this->emitting)
00152 return NA<R>::na();
00153 this->emitting = true;
00154 iterator it = mconnections.begin();
00155 const_iterator end = mconnections.end();
00156 for (; it != end; ++it ) {
00157 connection_impl* ci = static_cast<connection_impl*>( it->get() );
00158 if (ci)
00159 ci->emit(OROCOS_SIGNATURE_ARGS);
00160 }
00161 this->emitting = false;
00162 this->cleanup();
00163 #endif
00164 return NA<R>::na();
00165 }
00166
00167 R operator()(OROCOS_SIGNATURE_PARMS)
00168 {
00169 return this->emit(OROCOS_SIGNATURE_ARGS);
00170 }
00171
00172 R fire(OROCOS_SIGNATURE_PARMS)
00173 {
00174 return this->emit(OROCOS_SIGNATURE_ARGS);
00175 }
00176
00177 virtual int arity() const { return OROCOS_SIGNATURE_NUM_ARGS; }
00178 };
00179
00180 }}
00181
00182
00183 #undef OROCOS_SIGNAL_N
00184 #undef OROCOS_SIGNAL_CONNECTION_N
00185