bool DataPool::Connection::addPort(RTT::base::PortInterface *port) { RTT::base::InputPortInterface *inputPort = dynamic_cast<RTT::base::InputPortInterface *>(port); RTT::base::OutputPortInterface *outputPort = dynamic_cast<RTT::base::OutputPortInterface *>(port); if (inputPort) { if (readers.count(inputPort)) { RTT::log(RTT::Error) << "InputPort " << inputPort->getName() << " is already a member of this connection" << RTT::endlog(); return false; } readers.insert(inputPort); this->internalOutputPort->connectTo(inputPort); for(std::set<RTT::base::OutputPortInterface *>::iterator it = writers.begin(); it != writers.end(); ++it) (*it)->connectTo(inputPort); return true; } if (outputPort) { if (writers.count(outputPort)) { RTT::log(RTT::Error) << "OutputPort " << outputPort->getName() << " is already a member of this connection" << RTT::endlog(); return false; } writers.insert(outputPort); outputPort->connectTo(this->internalInputPort); for(std::set<RTT::base::InputPortInterface *>::iterator it = readers.begin(); it != readers.end(); ++it) outputPort->connectTo(*it); return true; } return false; }
// report a specific connection. bool Logger::reportPort(const std::string& component, const std::string& port ) { TaskContext* comp = this->getPeer(component); if ( !comp ) { log(Error) << "no such component " << component << endlog(); return false; } RTT::base::OutputPortInterface* writer = dynamic_cast<RTT::base::OutputPortInterface*>(comp->ports()->getPort(port)); if ( !writer ) { log(Error) << "component " << component << " does not have a port named " << port << ", or it is a read port" << endlog(); return false; } std::string portname(component + "." + port); RTT::base::PortInterface *pi = ports()->getPort(portname); if(pi) // we are already reporting this port { log(Info) << "port " << port << " of component " << component << " is already logged" << endlog(); return true; } // Create the corresponding read port RTT::base::InputPortInterface* reader = static_cast<RTT::base::InputPortInterface*>(writer->antiClone()); reader->setName(portname); writer->createBufferConnection(*reader, 25); return addLoggingPort(reader, portname); }
void DataPool::Connection::removePort(RTT::base::PortInterface *port) { RTT::base::InputPortInterface *inputPort = dynamic_cast<RTT::base::InputPortInterface *>(port); RTT::base::OutputPortInterface *outputPort = dynamic_cast<RTT::base::OutputPortInterface *>(port); if (inputPort) { this->internalOutputPort->disconnect(inputPort); inputPort->disconnect(); readers.erase(inputPort); } if (outputPort) { this->internalInputPort->disconnect(outputPort); outputPort->disconnect(); writers.erase(outputPort); } }
RTT::InputPort<T> &getReader(RTT::ConnPolicy const& policy) { if(!reader) { reader = dynamic_cast<RTT::InputPort<T> *>(port->antiClone()); RTT::TaskContext *clientTask = getClientTask(); clientTask->addPort(*reader); reader->connectTo(port, policy); } return *reader; };
~OutputProxyPort() { deleteReader(); port->disconnect(); }
bool connectTo(InputProxyPort<T> &inputPort) { return port->connectTo(inputPort.port); };
RTT::base::ChannelElementBase::shared_ptr RemoteInputPort::buildRemoteChannelOutput( RTT::base::OutputPortInterface& output_port, RTT::types::TypeInfo const* type, RTT::base::InputPortInterface& reader_, RTT::ConnPolicy const& policy) { // This is called by the createConnection()->createRemoteConnection() code of the ConnFactory. Logger::In in("RemoteInputPort::buildRemoteChannelOutput"); // First we delegate this call to the remote side, which will create a corba channel element, // buffers and channel output and attach this to the real input port. CRemoteChannelElement_var remote; RTT::base::ChannelElementBase::shared_ptr buf; try { CConnPolicy cpolicy = toCORBA(policy); CChannelElement_var ret = dataflow->buildChannelOutput(getName().c_str(), cpolicy); if ( CORBA::is_nil(ret) ) { return 0; } remote = CRemoteChannelElement::_narrow( ret.in() ); policy.name_id = toRTT(cpolicy).name_id; } catch(CORBA::Exception& e) { log(Error) << "Caught CORBA exception while creating a remote channel output:" << endlog(); log(Error) << CORBA_EXCEPTION_INFO( e ) <<endlog(); return NULL; } // Input side is now ok and waiting for us to complete. We build our corba channel element too // and connect it to the remote side and vice versa. CRemoteChannelElement_i* local = static_cast<CorbaTypeTransporter*>(type->getProtocol(ORO_CORBA_PROTOCOL_ID)) ->createChannelElement_i(output_port.getInterface(), mpoa, policy.pull); CRemoteChannelElement_var proxy = local->_this(); local->setRemoteSide(remote); remote->setRemoteSide(proxy.in()); local->_remove_ref(); RTT::base::ChannelElementBase::shared_ptr corba_ceb = dynamic_cast<RTT::base::ChannelElementBase*>(local); // Note: this probably needs to factored out, see also DataFlowI.cpp:buildChannelOutput() for the counterpart of this code. // If the user specified OOB, we prepend the prefered transport. // This inserts a channel element before our corba channel element. // The remote input side will have done this too in the above step. if ( policy.transport != 0 && policy.transport != ORO_CORBA_PROTOCOL_ID ) { // create alternative path / out of band transport. string name = policy.name_id ; if ( type->getProtocol(policy.transport) == 0 ) { log(Error) << "Could not create out-of-band transport for port "<< name << " with transport id " << policy.transport <<endlog(); log(Error) << "No such transport registered. Check your policy.transport settings or add the transport for type "<< type->getTypeName() <<endlog(); } RTT::base::ChannelElementBase* ceb = type->getProtocol(policy.transport)->createStream(this, policy, true); if (ceb) { // insertion before corba. ceb->setOutput( corba_ceb ); corba_ceb = ceb; log(Info) <<"Redirecting data for port "<<name << " to out-of-band protocol "<< policy.transport << endlog(); } else { log(Error) << "The type transporter for type "<<type->getTypeName()<< " failed to create a dual channel for port " << name<<endlog(); } } else { // if no oob present, create a buffer at output port to guarantee RT delivery of data. (is always present in push&pull). buf = type->buildDataStorage(policy); assert(buf); buf->setOutput( corba_ceb ); corba_ceb = buf; } // store the object reference in a map, for future lookup in channelReady(). // this is coupled with the use of channelReady(). We assume the caller will always pass // chan->getOutputEndPoint() in that function. channel_map[ corba_ceb->getOutputEndPoint().get() ] = CChannelElement::_duplicate( remote ); // The ChannelElementBase object that represents reader_half on this side return corba_ceb; }