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 target.ownProperty( newtarget );
00075 if ( decomposePropertyBag(isbag.value(), newtarget->value() ) == false) {
00076 assert(false && "internal error in decomposePropertyBag.");
00077 }
00078 } else {
00079
00080 log(Debug) << "Checking for decompose "<< (*sit)->getName() <<endlog();
00081
00082
00083 DataSourceBase::shared_ptr dsb = (*sit)->getTypeInfo()->decomposeType( (*sit)->getDataSource() );
00084 if ( dsb ) {
00085
00086 if ( dsb == (*sit)->getDataSource() ) {
00087
00088 target.ownProperty( (*sit)->clone() );
00089 } else {
00090 DataSource<PropertyBag>::shared_ptr bagds = DataSource<PropertyBag>::narrow(dsb.get());
00091 if ( bagds ) {
00092
00093
00094 Property<PropertyBag>* newtarget = new Property<PropertyBag>((*sit)->getName(), (*sit)->getDescription() );
00095 target.ownProperty( newtarget );
00096 if ( decomposePropertyBag(bagds->rvalue(), newtarget->value() ) == false) {
00097 assert(false && "internal error in decomposePropertyBag.");
00098 }
00099 } else {
00100
00101 base::PropertyBase* p = dsb->getTypeInfo()->buildProperty((*sit)->getName(), (*sit)->getDescription(), dsb);
00102 if ( target.ownProperty( p ) == false)
00103 log(Error) <<"Failed to create a property of decomposed data of type "<<(*sit)->getType() <<endlog();
00104 }
00105 }
00106 } else {
00107
00108 Property<PropertyBag> res((*sit)->getName(), (*sit)->getDescription() );
00109
00110 if ( types::propertyDecomposition(*sit, res.value() ) ) {
00111 target.ownProperty( res.clone() );
00112 }
00113 }
00114 }
00115 ++sit;
00116 }
00117 return true;
00118 }