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