MatrixTypeInfo.hpp
Go to the documentation of this file.
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


rtt
Author(s): RTT Developers
autogenerated on Thu Jan 2 2014 11:35:22