/** * Returns the last written value written to this port, in case it is * kept by this port, otherwise, returns a default T(). * @return The last written value or T(). */ T getLastWrittenValue() const { typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (written && last_written_value) return last_written_value->get(); else return T(); }
virtual bool connectionAdded( base::ChannelElementBase::shared_ptr channel_input, ConnPolicy const& policy ) { // Initialize the new channel with last written data if requested // (and available) // This this the input channel element of the whole connection typename base::ChannelElement<T>::shared_ptr channel_el_input = static_cast< base::ChannelElement<T>* >(channel_input.get()); if (written) { typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (last_written_value) { T sample = last_written_value->get(); if ( channel_el_input->data_sample(sample) ) { if ( policy.init ) return channel_el_input->write(sample); return true; } else { Logger::In in("OutputPort"); log(Error) << "Failed to pass data sample to data channel. Aborting connection."<<endlog(); return false; } } } // even if we're not written, test the connection with a default sample. return channel_el_input->data_sample( T() ); }
virtual bool updateFromBlob(const void* blob, int size, base::DataSourceBase::shared_ptr target) const { typename internal::AssignableDataSource<T>::shared_ptr ad = internal::AssignableDataSource<T>::narrow( target.get() ); assert( size == sizeof(T) ); if ( ad ) { ad->set( *(T*)(blob) ); return true; } return false; }
/** * Reads the last written value written to this port, in case it is * kept by this port, otherwise, returns false. * @param sample The data sample to store the value into. * @return true if it could be retrieved, false otherwise. */ bool getLastWrittenValue(T& sample) const { typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (written && last_written_value) { sample = last_written_value->get(); return true; } return false; }
bool resize(base::DataSourceBase::shared_ptr arg, int size_rows, int size_columns) const { if (arg->isAssignable()) { typename internal::AssignableDataSource<T>::shared_ptr asarg = internal::AssignableDataSource<T>::narrow( arg.get() ); asarg->set().resize( size_rows, size_columns ); asarg->updated(); return true; } return false; }
/** * Writes a new sample to all receivers (if any). * @param sample The new sample to send out. */ void write(const T& sample) { typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (last_written_value) last_written_value->set(sample); written = true; cmanager.delete_if( boost::bind( &OutputPort<T>::do_write, this, boost::ref(sample), boost::lambda::_1) ); }
FlowStatus read(base::DataSourceBase::shared_ptr source, bool copy_old_data) { typename internal::AssignableDataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >(source); if (! ds) { log(Error) << "trying to read to an incompatible data source" << endlog(); return NoData; } return read(ds->set(), copy_old_data); }
/** * Provides this port a data sample that is representative for the * samples being used in write(). The sample will not be delivered * to receivers, and only passed on to the underlying communication channel * to allow it to allocate enough memory to hold the sample. You * only need to call this in case you want to transfer dynamically * sized objects in real-time over this OutputPort. * @param sample */ void setDataSample(const T& sample) { keepLastWrittenValue(true); typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (last_written_value) last_written_value->set(sample); written = true; cmanager.delete_if( boost::bind( &OutputPort<T>::do_init, this, boost::ref(sample), _1) ); }
void write(base::DataSourceBase::shared_ptr source) { typename internal::AssignableDataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >(source); if (ds) write(ds->rvalue()); else { typename internal::DataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<T> >(source); if (ds) write(ds->get()); else log(Error) << "trying to write from an incompatible data source" << endlog(); } }
virtual bool getMember(internal::Reference* ref, base::DataSourceBase::shared_ptr item, const std::string& name) const { typename internal::AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( item ); // Use a copy in case our parent is not assignable: if ( !adata ) { // is it non-assignable ? typename internal::DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< internal::DataSource<T> >( item ); if ( data ) { // create a copy -> this is the only place & case where we allocate -> how to fix ? adata = new internal::ValueDataSource<T>( data->get() ); } } if (adata) { type_discovery in( adata ); return in.referenceMember( ref, adata->set(), name ); } log(Error) << "Wrong call to type info function " + this->getTypeName() << "'s getMember() can not process "<< item->getTypeName() <<endlog(); return false; }
virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const { typename internal::AssignableDataSource<T>::shared_ptr adata = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( item ); // Use a copy in case our parent is not assignable: if ( !adata ) { // is it non-assignable ? typename internal::DataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< internal::DataSource<T> >( item ); if ( data ) { // create a copy adata = new internal::ValueDataSource<T>( data->get() ); } } if (adata) { type_discovery in( adata ); return in.discoverMember( adata->set(), name ); } log(Error) << "Wrong call to type info function " + this->getTypeName() << "'s getMember() can not process "<< item->getTypeName() <<endlog(); return base::DataSourceBase::shared_ptr(); }
virtual bool composeType( base::DataSourceBase::shared_ptr source, base::DataSourceBase::shared_ptr result) const { const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (source.get() ); if ( !pb ) return false; typename internal::AssignableDataSource<UserType>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<UserType> >( result ); if ( !ads ) return false; // last fall-back: use user supplied function: if ( composeTypeImpl( pb->rvalue(), ads->set() ) ) ads->updated(); else { Logger::log() <<Logger::Debug<<"Failed to compose from "<< source->getTypeName() <<Logger::endl; return false; } Logger::log() <<Logger::Debug<<"Successfuly composed type from "<< source->getTypeName() <<Logger::endl; return true; }
/** * Update \a target with the contents of \a any which is an object of a \a protocol. */ virtual bool updateFromAny(const CORBA::Any* any, base::DataSourceBase::shared_ptr target) const { typename internal::ReferenceDataSource<T>::shared_ptr ad_ref = boost::dynamic_pointer_cast< internal::ReferenceDataSource<T> >( target ); if ( ad_ref ) { if (AnyConversion<PropertyType>::update(*any, ad_ref->set() ) ) { return true; } return false; } typename internal::AssignableDataSource<T>::shared_ptr ad = internal::AssignableDataSource<T>::narrow( target.get() ); if ( ad ) { PropertyType value = PropertyType(); if (AnyConversion<PropertyType>::update(*any, value ) ) { ad->set( value ); return true; } return false; } return false; }
/** * Specialize to resize \a result given the size of \a source. */ virtual bool composeTypeImpl(const PropertyBag& bag, typename internal::AssignableDataSource<T>::reference_t result) const { if ( bag.getType() == "Matrix" ) { unsigned int rows = bag.size(); unsigned int cols = 0; // Get values for (unsigned int i = 1; i <= rows ; i++) { std::stringstream out; out << i; Property<PropertyBag>* row_bag = bag.getProperty<PropertyBag>(out.str()); if(row_bag==NULL){ log(Error)<<"Could not read row "<<i<<endlog(); return false; } Property<RowVector> row_p(row_bag->getName(),row_bag->getDescription()); if(!(row_p.getDataSource()->composeType(row_bag->getDataSource()))){ log(Error)<<"Could not decompose row "<<i<<endlog(); return false; } if(row_p.ready()){ if(i==1){ cols = row_p.get().size(); result.resize(rows,cols); } else if(row_p.get().size()!=cols){ log(Error)<<"Row "<<i+1<<" size does not match matrix columns"<<endlog(); return false; } for ( unsigned int j=1; j <= row_p.get().size() ; j++){ result(i,j)=row_p.get()(j); } }else{ log(Error)<<"Property of Row "<<i<<"was not ready for use"<<endlog(); return false; } } }else { log(Error) << "Composing Property< Matrix > :" << " type mismatch, got type '"<< bag.getType() << "', expected type "<<"Matrix."<<endlog(); return false; } return true; }