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 #include "DataFlowInterface.hpp"
00040 #include "Logger.hpp"
00041 #include "Service.hpp"
00042 #include "TaskContext.hpp"
00043
00044 namespace RTT
00045 {
00046 using namespace detail;
00047
00048 DataFlowInterface::DataFlowInterface(Service* parent )
00049 : mservice(parent)
00050 {}
00051
00052 DataFlowInterface::~DataFlowInterface() {
00053 }
00054
00055 TaskContext* DataFlowInterface::getOwner() const {
00056 return mservice ? mservice->getOwner() : 0;
00057 }
00058
00059 PortInterface& DataFlowInterface::addPort(PortInterface& port) {
00060 if ( !chkPtr("addPort", "PortInterface", &port) ) return port;
00061 this->addLocalPort(port);
00062 Service::shared_ptr mservice_ref;
00063 if (mservice && mservice->hasService( port.getName()) ) {
00064
00065
00066 mservice_ref = mservice->provides();
00067 log(Warning) <<"'addPort' "<< port.getName() << ": name already in use as Service. Replacing previous service with new one." <<endlog();
00068 mservice->removeService(port.getName());
00069 }
00070
00071 if (!mservice) {
00072 log(Warning) <<"'addPort' "<< port.getName() << ": DataFlowInterface not given to parent. Not adding Service." <<endlog();
00073 return port;
00074 }
00075 Service::shared_ptr ms( this->createPortObject( port.getName()) );
00076 if ( ms )
00077 mservice->addService( ms );
00078
00079 return port;
00080 }
00081
00082 PortInterface& DataFlowInterface::addLocalPort(PortInterface& port) {
00083 for ( Ports::iterator it(mports.begin());
00084 it != mports.end();
00085 ++it)
00086 if ( (*it)->getName() == port.getName() ) {
00087 log(Warning) <<"'addPort' "<< port.getName() << ": name already in use. Disconnecting and replacing previous port with new one." <<endlog();
00088 removeLocalPort( port.getName() );
00089 break;
00090 }
00091
00092 mports.push_back( &port );
00093 port.setInterface( this );
00094 return port;
00095 }
00096
00097 InputPortInterface& DataFlowInterface::addEventPort(InputPortInterface& port, SlotFunction callback) {
00098 if ( !chkPtr("addEventPort", "PortInterface", &port) ) return port;
00099 this->addLocalEventPort(port, callback);
00100 Service::shared_ptr mservice_ref;
00101 if (mservice && mservice->hasService( port.getName()) ) {
00102
00103
00104 mservice_ref = mservice->provides();
00105 log(Warning) <<"'addPort' "<< port.getName() << ": name already in use as Service. Replacing previous service with new one." <<endlog();
00106 mservice->removeService(port.getName());
00107 }
00108
00109 if (!mservice) {
00110 log(Warning) <<"'addPort' "<< port.getName() << ": DataFlowInterface not given to parent. Not adding Service." <<endlog();
00111 return port;
00112 }
00113 Service::shared_ptr ms( this->createPortObject( port.getName()) );
00114 if ( ms )
00115 mservice->addService( ms );
00116 return port;
00117 }
00118
00119 #ifdef ORO_SIGNALLING_PORTS
00120 void DataFlowInterface::setupHandles() {
00121 for_each(handles.begin(), handles.end(), boost::bind(&Handle::connect, _1));
00122 }
00123
00124 void DataFlowInterface::cleanupHandles() {
00125 for_each(handles.begin(), handles.end(), boost::bind(&Handle::disconnect, _1));
00126 }
00127 #else
00128 void DataFlowInterface::dataOnPort(base::PortInterface* port)
00129 {
00130 if ( mservice && mservice->getOwner() )
00131 mservice->getOwner()->dataOnPort(port);
00132 }
00133 #endif
00134
00135 InputPortInterface& DataFlowInterface::addLocalEventPort(InputPortInterface& port, SlotFunction callback) {
00136 this->addLocalPort(port);
00137
00138 if (mservice == 0 || mservice->getOwner() == 0) {
00139 log(Error) << "addLocalEventPort "<< port.getName() <<": DataFlowInterface not part of a TaskContext. Will not trigger any TaskContext nor register callback." <<endlog();
00140 return port;
00141 }
00142
00143 #ifdef ORO_SIGNALLING_PORTS
00144
00145 Handle h = port.getNewDataOnPortEvent()->connect(boost::bind(&TaskContext::dataOnPort, mservice->getOwner(), _1) );
00146 if (h) {
00147 log(Info) << mservice->getName() << " will be triggered when new data is available on InputPort " << port.getName() << endlog();
00148 handles.push_back(h);
00149 } else {
00150 log(Error) << mservice->getName() << " can't connect to event of InputPort " << port.getName() << endlog();
00151 return port;
00152 }
00153 #endif
00154 if (callback)
00155 mservice->getOwner()->dataOnPortCallback(&port,callback);
00156
00157 #ifndef ORO_SIGNALLING_PORTS
00158 port.signalInterface(true);
00159 #endif
00160 return port;
00161 }
00162
00163 void DataFlowInterface::removePort(const std::string& name) {
00164 for ( Ports::iterator it(mports.begin());
00165 it != mports.end();
00166 ++it)
00167 if ( (*it)->getName() == name ) {
00168 Service::shared_ptr mservice_ref;
00169 if (mservice && mservice->hasService(name) ) {
00170
00171
00172 mservice_ref = mservice->provides();
00173 mservice->removeService( name );
00174 if (mservice->getOwner())
00175 mservice->getOwner()->dataOnPortRemoved( *it );
00176 }
00177 (*it)->disconnect();
00178 (*it)->setInterface(0);
00179 mports.erase(it);
00180 return;
00181 }
00182 }
00183
00184 void DataFlowInterface::removeLocalPort(const std::string& name) {
00185 for ( Ports::iterator it(mports.begin());
00186 it != mports.end();
00187 ++it)
00188 if ( (*it)->getName() == name ) {
00189 (*it)->disconnect();
00190 (*it)->setInterface(0);
00191 mports.erase(it);
00192 return;
00193 }
00194 }
00195
00196 DataFlowInterface::Ports DataFlowInterface::getPorts() const {
00197 return mports;
00198 }
00199
00200 DataFlowInterface::PortNames DataFlowInterface::getPortNames() const {
00201 std::vector<std::string> res;
00202 for ( Ports::const_iterator it(mports.begin());
00203 it != mports.end();
00204 ++it)
00205 res.push_back( (*it)->getName() );
00206 return res;
00207 }
00208
00209 PortInterface* DataFlowInterface::getPort(const std::string& name) const {
00210 for ( Ports::const_iterator it(mports.begin());
00211 it != mports.end();
00212 ++it)
00213 if ( (*it)->getName() == name )
00214 return *it;
00215 return 0;
00216 }
00217
00218 std::string DataFlowInterface::getPortDescription(const std::string& name) const {
00219 for ( Ports::const_iterator it(mports.begin());
00220 it != mports.end();
00221 ++it)
00222 if ( (*it)->getName() == name )
00223 return (*it)->getDescription();
00224 return "";
00225 }
00226
00227 bool DataFlowInterface::setPortDescription(const std::string& name, const std::string description) {
00228 Service::shared_ptr srv = mservice->getService(name);
00229 if (srv) {
00230 srv->doc(description);
00231 return true;
00232 }
00233 return false;
00234 }
00235
00236 Service* DataFlowInterface::createPortObject(const std::string& name) {
00237 PortInterface* p = this->getPort(name);
00238 if ( !p )
00239 return 0;
00240 Service* to = p->createPortObject();
00241 if (to) {
00242 std::string d = this->getPortDescription(name);
00243 if ( !d.empty() )
00244 to->doc( d );
00245 else
00246 to->doc("No description set for this Port. Use .doc() to document it.");
00247 }
00248 return to;
00249 }
00250
00251 void DataFlowInterface::clear()
00252 {
00253
00254 for ( Ports::iterator it(mports.begin());
00255 it != mports.end();
00256 ++it) {
00257 if (mservice)
00258 mservice->removeService( (*it)->getName() );
00259 }
00260 mports.clear();
00261 }
00262
00263 bool DataFlowInterface::chkPtr(const std::string & where, const std::string & name, const void *ptr)
00264 {
00265 if ( ptr == 0) {
00266 log(Error) << "You tried to add a null pointer in '"<< where << "' for the object '" << name << "'. Fix your code !"<< endlog();
00267 return false;
00268 }
00269 return true;
00270 }
00271
00272 }