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