Go to the documentation of this file.00001 #include "PropertyComposition.hpp"
00002 #include "PropertyDecomposition.hpp"
00003 #include "../Logger.hpp"
00004 #include "../Property.hpp"
00005 #include "types/Types.hpp"
00006
00007 using namespace RTT;
00008 using namespace RTT::detail;
00009
00010 bool RTT::types::composePropertyBag( PropertyBag const& sourcebag, PropertyBag& target )
00011 {
00012 if ( !target.empty() ) {
00013 log(Error) <<"composePropertyBag: target bag must be empty."<< endlog();
00014 return false;
00015 }
00016 bool has_error = false;
00017 PropertyBag::const_iterator sit = sourcebag.begin();
00018 for( ; sit != sourcebag.end(); ++sit) {
00019
00020 Property<PropertyBag> isbag;
00021 isbag = *sit;
00022 if ( isbag.ready() && isbag.value().getType() != "PropertyBag") {
00023
00024 TypeInfo* ti = Types()->type( isbag.value().getType() );
00025 if ( ti == 0) {
00026 log(Error) <<"Could not compose unknown type '" << isbag.value().getType() <<"'." <<endlog();
00027 has_error = true;
00028 continue;
00029 }
00030 PropertyBase* tgtprop = ti->buildProperty(isbag.getName(), isbag.getDescription());
00031 if ( ti->composeType(isbag.getDataSource(), tgtprop->getDataSource()) ) {
00032 log(Debug) << "Used user's composition function for " << tgtprop->getName() <<":"<<tgtprop->getType()<<endlog();
00033 target.ownProperty(tgtprop);
00034 } else {
00035 log(Error) <<"The type '" << isbag.value().getType() <<"' did not provide a type composition function, but I need one to compose it from a PropertyBag." <<endlog();
00036 delete tgtprop;
00037 has_error = true;
00038 continue;
00039 }
00040 } else {
00041 if ( isbag.ready() ) {
00042
00043 Property<PropertyBag>* newbag = new Property<PropertyBag>(isbag.getName(), isbag.getDescription());
00044 if ( composePropertyBag(isbag.value(), newbag->value()) == false) {
00045 delete newbag;
00046 has_error = true;
00047 continue;
00048 }
00049 target.ownProperty( newbag );
00050 } else {
00051
00052 target.ownProperty( (*sit)->clone() );
00053 }
00054 }
00055 }
00056
00057 return !has_error;
00058 }
00059
00060 bool RTT::types::decomposePropertyBag( PropertyBag const& sourcebag, PropertyBag& target)
00061 {
00062 if ( !target.empty() ) {
00063 log(Error) <<"decomposePropertyBag: target bag must be empty."<< endlog();
00064 return false;
00065 }
00066 PropertyBag::const_iterator sit = sourcebag.begin();
00067 while( sit != sourcebag.end()) {
00068
00069 Property<PropertyBag> isbag;
00070 isbag = *sit;
00071 if ( isbag.ready() ) {
00072
00073 Property<PropertyBag>* newtarget = new Property<PropertyBag>(isbag.getName(), isbag.getDescription() );
00074 newtarget->value().setType( isbag.rvalue().getType() );
00075 target.ownProperty( newtarget );
00076 if ( decomposePropertyBag(isbag.value(), newtarget->value() ) == false) {
00077 assert(false && "internal error in decomposePropertyBag.");
00078 }
00079 } else {
00080
00081 log(Debug) << "Checking for decompose "<< (*sit)->getName() <<endlog();
00082
00083
00084 DataSourceBase::shared_ptr dsb = (*sit)->getTypeInfo()->decomposeType( (*sit)->getDataSource() );
00085 if ( dsb ) {
00086
00087 if ( dsb == (*sit)->getDataSource() ) {
00088
00089 target.ownProperty( (*sit)->clone() );
00090 } else {
00091 DataSource<PropertyBag>::shared_ptr bagds = DataSource<PropertyBag>::narrow(dsb.get());
00092 if ( bagds ) {
00093
00094
00095 Property<PropertyBag>* newtarget = new Property<PropertyBag>((*sit)->getName(), (*sit)->getDescription() );
00096 newtarget->value().setType( bagds->rvalue().getType() );
00097 target.ownProperty( newtarget );
00098 if ( decomposePropertyBag(bagds->rvalue(), newtarget->value() ) == false) {
00099 assert(false && "internal error in decomposePropertyBag.");
00100 }
00101 } else {
00102
00103 base::PropertyBase* p = dsb->getTypeInfo()->buildProperty((*sit)->getName(), (*sit)->getDescription(), dsb);
00104 if ( target.ownProperty( p ) == false)
00105 log(Error) <<"Failed to create a property of decomposed data of type "<<(*sit)->getType() <<endlog();
00106 }
00107 }
00108 } else {
00109
00110 Property<PropertyBag> res((*sit)->getName(), (*sit)->getDescription() );
00111
00112 if ( types::propertyDecomposition(*sit, res.value() ) ) {
00113 target.ownProperty( res.clone() );
00114 }
00115 }
00116 }
00117 ++sit;
00118 }
00119 return true;
00120 }