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
00041
00042
00043
00044
00045
00046 #ifndef CONNECTIONMANAGER_HPP_
00047 #define CONNECTIONMANAGER_HPP_
00048
00049
00050 #include "ConnID.hpp"
00051 #include "List.hpp"
00052 #include "../ConnPolicy.hpp"
00053 #include "../os/Mutex.hpp"
00054 #include "../base/rtt-base-fwd.hpp"
00055 #include "../base/ChannelElementBase.hpp"
00056 #include <boost/tuple/tuple.hpp>
00057 #include <boost/bind.hpp>
00058 #include <boost/shared_ptr.hpp>
00059 #include <boost/lambda/lambda.hpp>
00060
00061 #include <rtt/os/Mutex.hpp>
00062 #include <rtt/os/MutexLock.hpp>
00063 #include <list>
00064
00065
00066 namespace RTT
00067 {
00068
00069 namespace internal
00070 {
00077 class RTT_API ConnectionManager
00078 {
00079 public:
00086 typedef boost::tuple<boost::shared_ptr<ConnID>, base::ChannelElementBase::shared_ptr, ConnPolicy> ChannelDescriptor;
00087
00093 ConnectionManager(base::PortInterface* port);
00094 ~ConnectionManager();
00095
00101 void addConnection(ConnID* port_id, base::ChannelElementBase::shared_ptr channel_input, ConnPolicy policy);
00102
00103 bool removeConnection(ConnID* port_id);
00104
00108 void disconnect();
00109
00113 bool connected() const;
00114
00116 bool disconnect(base::PortInterface* port);
00117
00118 template<typename Pred>
00119 bool delete_if(Pred pred) {
00120 RTT::os::MutexLock lock(connection_lock);
00121 bool result = false;
00122 std::list<ChannelDescriptor>::iterator it = connections.begin();
00123 while (it != connections.end())
00124 {
00125 if (pred(*it))
00126 {
00127 result = true;
00128 it = connections.erase(it);
00129 }
00130 else ++it;
00131 }
00132 return result;
00133 }
00134
00143 template<typename Pred>
00144 void select_reader_channel(Pred pred) {
00145 RTT::os::MutexLock lock(connection_lock);
00146 std::pair<bool, ChannelDescriptor> new_channel =
00147 find_if(pred);
00148 if (new_channel.first)
00149 {
00150
00151
00152 if (cur_channel.get<1>() != new_channel.second.get<1>())
00153 cur_channel.get<1>()->clear();
00154 cur_channel = new_channel.second;
00155 }
00156 }
00157
00158 template<typename Pred>
00159 std::pair<bool, ChannelDescriptor> find_if(Pred pred) {
00160 ChannelDescriptor channel = cur_channel;
00161 if ( channel.get<1>() )
00162 if ( pred( channel ) )
00163 return std::make_pair(true, channel);
00164
00165 #ifdef MSVC
00166 std::list<ChannelDescriptor>::iterator result =
00167 std::find_if(connections.begin(), connections.end(), pred);
00168 #else
00169 std::list<ChannelDescriptor>::iterator result =
00170 std::find_if(connections.begin(), connections.end(), pred);
00171 #endif
00172 if (result == connections.end())
00173 return std::make_pair(false, ChannelDescriptor());
00174 else
00175 return std::make_pair(true, *result);
00176 }
00177
00182 bool isSingleConnection() const { return connections.size() == 1; }
00183
00189 base::ChannelElementBase* getCurrentChannel() const {
00190 return cur_channel.get<1>().get();
00191 }
00192
00196 std::list<ChannelDescriptor> getChannels() const {
00197 return connections;
00198 }
00199
00205 void clear();
00206
00207 protected:
00208
00209 void updateCurrentChannel(bool reset_current);
00210
00219 bool findMatchingPort(ConnID const* conn_id, ChannelDescriptor const& descriptor);
00220
00225 bool eraseConnection(ChannelDescriptor& descriptor);
00226
00228 os::Mutex connection_resize_mtx;
00229
00233 base::PortInterface* mport;
00234
00239 std::list< ChannelDescriptor > connections;
00240
00244 ChannelDescriptor cur_channel;
00245
00250 RTT::os::Mutex connection_lock;
00251 };
00252
00253 }
00254
00255 }
00256
00257 #endif