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 mports.erase(it);
00179 return;
00180 }
00181 }
00182
00183 void DataFlowInterface::removeLocalPort(const std::string& name) {
00184 for ( Ports::iterator it(mports.begin());
00185 it != mports.end();
00186 ++it)
00187 if ( (*it)->getName() == name ) {
00188 (*it)->disconnect();
00189 mports.erase(it);
00190 return;
00191 }
00192 }
00193
00194 DataFlowInterface::Ports DataFlowInterface::getPorts() const {
00195 return mports;
00196 }
00197
00198 DataFlowInterface::PortNames DataFlowInterface::getPortNames() const {
00199 std::vector<std::string> res;
00200 for ( Ports::const_iterator it(mports.begin());
00201 it != mports.end();
00202 ++it)
00203 res.push_back( (*it)->getName() );
00204 return res;
00205 }
00206
00207 PortInterface* DataFlowInterface::getPort(const std::string& name) const {
00208 for ( Ports::const_iterator it(mports.begin());
00209 it != mports.end();
00210 ++it)
00211 if ( (*it)->getName() == name )
00212 return *it;
00213 return 0;
00214 }
00215
00216 std::string DataFlowInterface::getPortDescription(const std::string& name) const {
00217 for ( Ports::const_iterator it(mports.begin());
00218 it != mports.end();
00219 ++it)
00220 if ( (*it)->getName() == name )
00221 return (*it)->getDescription();
00222 return "";
00223 }
00224
00225 bool DataFlowInterface::setPortDescription(const std::string& name, const std::string description) {
00226 Service::shared_ptr srv = mservice->getService(name);
00227 if (srv) {
00228 srv->doc(description);
00229 return true;
00230 }
00231 return false;
00232 }
00233
00234 Service* DataFlowInterface::createPortObject(const std::string& name) {
00235 PortInterface* p = this->getPort(name);
00236 if ( !p )
00237 return 0;
00238 Service* to = p->createPortObject();
00239 if (to) {
00240 std::string d = this->getPortDescription(name);
00241 if ( !d.empty() )
00242 to->doc( d );
00243 else
00244 to->doc("No description set for this Port. Use .doc() to document it.");
00245 }
00246 return to;
00247 }
00248
00249 void DataFlowInterface::clear()
00250 {
00251
00252 for ( Ports::iterator it(mports.begin());
00253 it != mports.end();
00254 ++it) {
00255 if (mservice)
00256 mservice->removeService( (*it)->getName() );
00257 }
00258 mports.clear();
00259 }
00260
00261 bool DataFlowInterface::chkPtr(const std::string & where, const std::string & name, const void *ptr)
00262 {
00263 if ( ptr == 0) {
00264 log(Error) << "You tried to add a null pointer in '"<< where << "' for the object '" << name << "'. Fix your code !"<< endlog();
00265 return false;
00266 }
00267 return true;
00268 }
00269
00270 }