$search
00001 /*************************************************************************** 00002 tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 MatrixTypeInfo.hpp 00003 00004 MatrixTypeInfo.hpp - description 00005 ------------------- 00006 begin : Tue September 07 2010 00007 copyright : (C) 2010 The SourceWorks 00008 email : peter@thesourceworks.com 00009 00010 *************************************************************************** 00011 * This library is free software; you can redistribute it and/or * 00012 * modify it under the terms of the GNU General Public * 00013 * License as published by the Free Software Foundation; * 00014 * version 2 of the License. * 00015 * * 00016 * As a special exception, you may use this file as part of a free * 00017 * software library without restriction. Specifically, if other files * 00018 * instantiate templates or use macros or inline functions from this * 00019 * file, or you compile this file and link it with other files to * 00020 * produce an executable, this file does not by itself cause the * 00021 * resulting executable to be covered by the GNU General Public * 00022 * License. This exception does not however invalidate any other * 00023 * reasons why the executable file might be covered by the GNU General * 00024 * Public License. * 00025 * * 00026 * This library is distributed in the hope that it will be useful, * 00027 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00028 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * 00029 * Lesser General Public License for more details. * 00030 * * 00031 * You should have received a copy of the GNU General Public * 00032 * License along with this library; if not, write to the Free Software * 00033 * Foundation, Inc., 59 Temple Place, * 00034 * Suite 330, Boston, MA 02111-1307 USA * 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 // aquire a shared reference to the this object 00110 boost::shared_ptr< MatrixTypeInfo<T> > mthis = boost::dynamic_pointer_cast<MatrixTypeInfo<T> >( this->getSharedPtr() ); 00111 // Allow base to install first 00112 TemplateTypeInfo<T,has_ostream>::installTypeInfoObject(ti); 00113 // Install the factories for primitive types 00114 ti->setMemberFactory( mthis ); 00115 00116 // Don't delete us, we're memory-managed. 00117 return false; 00118 } 00119 00120 base::AttributeBase* buildVariable(std::string name,int size) const 00121 { 00122 // if a sizehint is given 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 // Get values 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 // take into account sequences: 00189 base::PropertyBase* sz = source.find("Rows"); 00190 if (!sz) 00191 sz = source.find("rows"); 00192 if (sz) 00193 { 00194 internal::DataSource<int>::shared_ptr sz_ds = internal::DataSource<int>::narrow(sz->getDataSource().get()); 00195 if (sz_ds) 00196 result.resize( sz_ds->get(), sz_ds->get() ); 00197 } 00198 else 00199 { 00200 // no size found, inform parent of number of elements to come: 00201 result.resize( source.size() ); 00202 } 00203 return TemplateTypeInfo<T,has_ostream>::composeTypeImpl(source,result); 00204 } 00205 */ 00206 00207 /* 00208 virtual std::vector<std::string> getMemberNames() const { 00209 // only discover the parts of this struct: 00210 std::vector<std::string> result; 00211 result.push_back("size"); 00212 result.push_back("capacity"); 00213 return result; 00214 } 00215 */ 00216 00217 virtual base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const { 00218 // the only thing we do is to check for an integer in name, otherwise, assume a part (size/capacity) is accessed: 00219 try { 00220 unsigned int indx = boost::lexical_cast<unsigned int>(name); 00221 // @todo could also return a direct reference to item indx using another DS type that respects updated(). 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 // discover if user gave us a part name or index: 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