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
00046 #include "PropertyDecomposition.hpp"
00047 #include "../internal/DataSource.hpp"
00048 #include <vector>
00049 #include <string>
00050 #include <memory>
00051 #include <boost/lexical_cast.hpp>
00052 #include "../Logger.hpp"
00053 #include "TypeInfo.hpp"
00054 #include "../Property.hpp"
00055
00056
00057 using namespace std;
00058 using namespace RTT;
00059 using namespace RTT::detail;
00060
00061 namespace RTT { namespace types {
00062
00063 bool propertyDecomposition( base::PropertyBase* source, PropertyBag& targetbag, bool recurse )
00064 {
00065 if (!source)
00066 return false;
00067 DataSourceBase::shared_ptr dsb = source->getDataSource();
00068 if (!dsb)
00069 return false;
00070 return typeDecomposition( dsb, targetbag, recurse);
00071 }
00072
00073 bool typeDecomposition( base::DataSourceBase::shared_ptr dsb, PropertyBag& targetbag, bool recurse)
00074 {
00075 if (!dsb)
00076 return false;
00077
00078
00079 DataSourceBase::shared_ptr decomposed = dsb->getTypeInfo()->decomposeType(dsb);
00080 if (decomposed) {
00081
00082 internal::AssignableDataSource<PropertyBag>::shared_ptr bag = internal::AssignableDataSource<PropertyBag>::narrow( decomposed.get() );
00083 if ( bag ) {
00084
00085 targetbag = bag->rvalue();
00086 return true;
00087 } else {
00088
00089
00090
00091 return false;
00092 }
00093 }
00094
00095 vector<string> parts = dsb->getMemberNames();
00096 if ( parts.empty() ) {
00097 log(Debug) << "propertyDecomposition: "<< dsb->getTypeName() << " does not have any members." << endlog();
00098 return false;
00099 }
00100
00101 targetbag.setType( dsb->getTypeName() );
00102
00103
00104 auto_ptr< Property<PropertyBag> > recurse_bag( new Property<PropertyBag>("recurse_bag","Part") );
00105
00106 for(vector<string>::iterator it = parts.begin(); it != parts.end(); ++it ) {
00107 DataSourceBase::shared_ptr part = dsb->getMember( *it );
00108 if (!part) {
00109 log(Error) <<"propertyDecomposition: Inconsistent type info for "<< dsb->getTypeName() << ": reported to have part '"<<*it<<"' but failed to return it."<<endlog();
00110 continue;
00111 }
00112 if ( !part->isAssignable() ) {
00113
00114 log(Debug)<<"propertyDecomposition: Part "<< *it << ":"<< part->getTypeName() << " is not changeable."<<endlog();
00115 continue;
00116 }
00117
00118 PropertyBase* newpb = part->getTypeInfo()->buildProperty(*it,"Part",part);
00119 if ( !newpb ) {
00120 log(Error)<< "Decomposition failed because Part '"<<*it<<"' is not known to type system."<<endlog();
00121 continue;
00122 }
00123 if ( !recurse || !propertyDecomposition( newpb, recurse_bag->value(), true) ) {
00124 assert( recurse_bag->value().empty() );
00125 targetbag.ownProperty( newpb );
00126 } else {
00127 recurse_bag->setName(*it);
00128
00129 targetbag.ownProperty( recurse_bag.release() );
00130 recurse_bag.reset( new Property<PropertyBag>("recurse_bag","Part") );
00131 delete newpb;
00132 }
00133 }
00134
00135
00136 recurse_bag->setDescription("Item");
00137
00138
00139 DataSource<int>::shared_ptr size = DataSource<int>::narrow( dsb->getMember("size").get() );
00140 if (size) {
00141 int msize = size->get();
00142 for (int i=0; i < msize; ++i) {
00143 string indx = boost::lexical_cast<string>( i );
00144 DataSourceBase::shared_ptr item = dsb->getMember(indx);
00145 if (item) {
00146 if ( !item->isAssignable() ) {
00147
00148 log(Warning)<<"propertyDecomposition: Item '"<< indx << "' of type "<< dsb->getTypeName() << " is not changeable."<<endlog();
00149 continue;
00150 }
00151
00152 PropertyBase* newpb = item->getTypeInfo()->buildProperty( "Element" + indx,"Sequence Element",item);
00153 if ( !recurse || !propertyDecomposition( newpb, recurse_bag->value()) ) {
00154 targetbag.ownProperty( newpb );
00155 } else {
00156 delete newpb;
00157 recurse_bag->setName( "Element" + indx );
00158
00159 targetbag.ownProperty( recurse_bag.release() );
00160 recurse_bag.reset( new Property<PropertyBag>("recurse_bag","Item") );
00161 }
00162 }
00163 }
00164 }
00165 if (targetbag.empty() )
00166 log(Debug) << "propertyDecomposition: "<< dsb->getTypeName() << " returns an empty property bag." << endlog();
00167 return true;
00168 }
00169
00170 }}