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 #ifndef ORO_MATRIX_TYPE_INFO_HPP
00040 #define ORO_MATRIX_TYPE_INFO_HPP
00041
00042 #include "types/TemplateTypeInfo.hpp"
00043 #include "types/MemberFactory.hpp"
00044 #include "types/type_discovery.hpp"
00045 #include "internal/DataSourceGenerator.hpp"
00046 #include <boost/lexical_cast.hpp>
00047
00048 namespace RTT
00049 {
00050 namespace types
00051 {
00057 template<class T>
00058 int get_rows(T const& cont)
00059 {
00060 return cont.rows();
00061 }
00062
00068 template<class T>
00069 int get_columns(T const& cont)
00070 {
00071 return cont.columns();
00072 }
00073
00081 template<class T>
00082 typename T::reference get_container_item(T & cont, int index_row, int index_column)
00083 {
00084 if (index_row >= (int) (cont.rows()) || index_row < 0 || index_column >= (int) (cont.columns()) || index_column < 0)
00085 return internal::NA<typename T::reference>::na();
00086 return cont[index_row,index_column];
00087 }
00088
00089
00099 template<typename T, bool has_ostream = false>
00100 class MatrixTypeInfo: public TemplateTypeInfo<T, has_ostream>, public MemberFactory
00101 {
00102 public:
00103 MatrixTypeInfo(std::string name) :
00104 TemplateTypeInfo<T, has_ostream> (name)
00105 {
00106 }
00107
00108 bool installTypeInfoObject(TypeInfo* ti) {
00109
00110 boost::shared_ptr< MatrixTypeInfo<T> > mthis = boost::dynamic_pointer_cast<MatrixTypeInfo<T> >( this->getSharedPtr() );
00111
00112 TemplateTypeInfo<T,has_ostream>::installTypeInfoObject(ti);
00113
00114 ti->setMemberFactory( mthis );
00115
00116
00117 return false;
00118 }
00119
00120 base::AttributeBase* buildVariable(std::string name,int size) const
00121 {
00122
00123 T t_init(size_rows, size_columns, typename T::value_type() );
00124
00125 log(Debug) << "Building variable '"<<name <<"' of type " << this->getTypeName() <<" and number of rows "<< size << " and number of columns " << size <<Logger::endl;
00126 return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >( t_init ) );
00127 }
00128
00129 bool resize(base::DataSourceBase::shared_ptr arg, int size_rows, int size_columns) const
00130 {
00131 if (arg->isAssignable()) {
00132 typename internal::AssignableDataSource<T>::shared_ptr asarg = internal::AssignableDataSource<T>::narrow( arg.get() );
00133 asarg->set().resize( size_rows, size_columns );
00134 asarg->updated();
00135 return true;
00136 }
00137 return false;
00138 }
00139
00143 virtual bool composeTypeImpl(const PropertyBag& bag, typename internal::AssignableDataSource<T>::reference_t result) const
00144 {
00145 if ( bag.getType() == "Matrix" ) {
00146 unsigned int rows = bag.size();
00147 unsigned int cols = 0;
00148
00149 for (unsigned int i = 1; i <= rows ; i++) {
00150 std::stringstream out;
00151 out << i;
00152 Property<PropertyBag>* row_bag = bag.getProperty<PropertyBag>(out.str());
00153 if(row_bag==NULL){
00154 log(Error)<<"Could not read row "<<i<<endlog();
00155 return false;
00156 }
00157 Property<RowVector> row_p(row_bag->getName(),row_bag->getDescription());
00158 if(!(row_p.getDataSource()->composeType(row_bag->getDataSource()))){
00159 log(Error)<<"Could not decompose row "<<i<<endlog();
00160 return false;
00161 }
00162 if(row_p.ready()){
00163 if(i==1){
00164 cols = row_p.get().size();
00165 result.resize(rows,cols);
00166 } else
00167 if(row_p.get().size()!=cols){
00168 log(Error)<<"Row "<<i+1<<" size does not match matrix columns"<<endlog();
00169 return false;
00170 }
00171 for ( unsigned int j=1; j <= row_p.get().size() ; j++){
00172 result(i,j)=row_p.get()(j);
00173 }
00174 }else{
00175 log(Error)<<"Property of Row "<<i<<"was not ready for use"<<endlog();
00176 return false;
00177 }
00178 }
00179 }else {
00180 log(Error) << "Composing Property< Matrix > :"
00181 << " type mismatch, got type '"<< bag.getType()
00182 << "', expected type "<<"Matrix."<<endlog();
00183 return false;
00184 }
00185 return true;
00186 }
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00218
00219 try {
00220 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00221
00222 return getMember( item, new internal::ConstantDataSource<int>(indx));
00223 } catch(...) {}
00224
00225 return getMember( item, new internal::ConstantDataSource<std::string>(name) );
00226 }
00227
00228 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00229 base::DataSourceBase::shared_ptr id) const {
00230 typename internal::AssignableDataSource<T>::shared_ptr data = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( item );
00231 if ( !data ) {
00232 if ( !item->isAssignable() )
00233 log(Error) << "Can't return reference to members of type "<< this->getTypeName() <<" since given object is not assignable." <<endlog();
00234 else
00235 log(Error) << "Consistency error: TypeInfo of type "<< this->getTypeName() <<" can't handle types of type "<< item->getType() <<endlog();
00236 return base::DataSourceBase::shared_ptr();
00237 }
00238
00239
00240 typename internal::DataSource<int>::shared_ptr id_indx = internal::DataSource<int>::narrow( id.get() );
00241 typename internal::DataSource<string>::shared_ptr id_name = internal::DataSource<string>::narrow( id.get() );
00242 if ( id_name ) {
00243 if ( id_name->get() == "size" ) {
00244 try {
00245 return internal::newFunctorDataSource(&get_size<T>, internal::GenerateDataSource()(item.get()) );
00246 } catch(...) {}
00247 }
00248 if ( id_name->get() == "capacity" ) {
00249 try {
00250 return internal::newFunctorDataSource(&get_capacity<T>, internal::GenerateDataSource()(item.get()) );
00251 } catch(...) {}
00252 }
00253 }
00254
00255 if ( id_indx ) {
00256 try {
00257 return internal::newFunctorDataSource(&get_container_item<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00258 } catch(...) {}
00259 }
00260 if (id_name) {
00261 log(Error) << "MatrixTypeInfo: No such part : " << id_name->get() << endlog();
00262 }
00263 if (id_indx) {
00264 log(Error) << "MatrixTypeInfo: Invalid index : " << id_indx->get() <<":"<< id_indx->getTypeName() << endlog();
00265 }
00266 return base::DataSourceBase::shared_ptr();
00267 }
00268 };
00269 }
00270 }
00271
00272 #endif