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
00039 #ifndef ORO_SEQUENCE_TYPE_INFO_BASE_HPP
00040 #define ORO_SEQUENCE_TYPE_INFO_BASE_HPP
00041
00042 #include "SequenceConstructor.hpp"
00043 #include "TemplateConstructor.hpp"
00044 #include "PropertyComposition.hpp"
00045 #include "PropertyDecomposition.hpp"
00046 #include "../internal/FusedFunctorDataSource.hpp"
00047 #include "../internal/DataSourceGenerator.hpp"
00048 #include <boost/lexical_cast.hpp>
00049
00050 namespace RTT
00051 {
00052 namespace types
00053 {
00059 template<class T>
00060 int get_capacity(T const& cont)
00061 {
00062 return cont.capacity();
00063 }
00064
00070 template<class T>
00071 int get_size(T const& cont)
00072 {
00073 return cont.size();
00074 }
00075
00083 template<class T>
00084 typename T::reference get_container_item(T & cont, int index)
00085 {
00086 if (index >= (int) (cont.size()) || index < 0)
00087 return internal::NA<typename T::reference>::na();
00088 return cont[index];
00089 }
00090
00098 template<class T>
00099 typename T::value_type get_container_item_copy(const T & cont, int index)
00100 {
00101 if (index >= (int) (cont.size()) || index < 0)
00102 return internal::NA<typename T::value_type>::na();
00103 return cont[index];
00104 }
00105
00114 bool get_container_item(std::vector<bool> & cont, int index);
00115 bool get_container_item_copy(const std::vector<bool> & cont, int index);
00116
00124 template<typename T>
00125 class SequenceTypeInfoBase
00126 {
00127 public:
00128 SequenceTypeInfoBase()
00129 {
00130 }
00131
00132 bool installTypeInfoObject(TypeInfo* ti) {
00133 ti->addConstructor( new SequenceBuilder<T>() );
00134 ti->addConstructor( newConstructor( sequence_ctor<T>() ) );
00135 ti->addConstructor( newConstructor( sequence_ctor2<T>() ) );
00136
00137 return false;
00138 }
00139
00140 ~SequenceTypeInfoBase() {}
00141
00142 base::AttributeBase* buildVariable(std::string name,int size) const
00143 {
00144
00145 T t_init(size, typename T::value_type() );
00146
00147 return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >( t_init ) );
00148 }
00149
00150 bool resize(base::DataSourceBase::shared_ptr arg, int size) const
00151 {
00152 if (arg->isAssignable()) {
00153 typename internal::AssignableDataSource<T>::shared_ptr asarg = internal::AssignableDataSource<T>::narrow( arg.get() );
00154 asarg->set().resize( size );
00155 asarg->updated();
00156 return true;
00157 }
00158 return false;
00159 }
00160
00164 bool composeType( base::DataSourceBase::shared_ptr dssource, base::DataSourceBase::shared_ptr dsresult) const {
00165 const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (dssource.get() );
00166 if ( !pb )
00167 return false;
00168 typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( dsresult );
00169 if ( !ads )
00170 return false;
00171
00172 PropertyBag const& source = pb->rvalue();
00173 typename internal::AssignableDataSource<T>::reference_t result = ads->set();
00174
00175
00176 base::PropertyBase* sz = source.find("Size");
00177 if (!sz)
00178 sz = source.find("size");
00179 if (sz)
00180 {
00181 internal::DataSource<int>::shared_ptr sz_ds = internal::DataSource<int>::narrow(sz->getDataSource().get());
00182 if (sz_ds)
00183 result.resize( sz_ds->get() );
00184 }
00185 else
00186 {
00187
00188 result.resize( source.size() );
00189 }
00190
00191 TypeInfoRepository::shared_ptr tir = Types();
00192 PropertyBag target( source.getType() );
00193 PropertyBag decomp;
00194 internal::ReferenceDataSource<T> rds(result);
00195 rds.ref();
00196
00197
00198
00199 if ( composePropertyBag(source, target) && typeDecomposition( &rds, decomp, false) && ( tir->type( decomp.getType() ) == tir->type( target.getType() ) ) && refreshProperties(decomp, target, true) ) {
00200 assert(result.size() == source.size());
00201 assert(source.size() == target.size());
00202 assert(source.size() == decomp.size());
00203 ads->updated();
00204 Logger::log() <<Logger::Debug<<"Successfuly composed type from "<< source.getType() <<Logger::endl;
00205 return true;
00206 } else
00207 Logger::log() <<Logger::Debug<<"Failed to composed type from "<< source.getType() <<Logger::endl;
00208
00209 return false;
00210 }
00211
00215 base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00216 {
00217 return base::DataSourceBase::shared_ptr();
00218 }
00219
00220
00221 std::vector<std::string> getMemberNames() const {
00222
00223 std::vector<std::string> result;
00224 result.push_back("size");
00225 result.push_back("capacity");
00226 return result;
00227 }
00228
00229 base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item, const std::string& name) const {
00230
00231 try {
00232 unsigned int indx = boost::lexical_cast<unsigned int>(name);
00233
00234 return getMember( item, new internal::ConstantDataSource<int>(indx));
00235 } catch(...) {}
00236
00237 return getMember( item, new internal::ConstantDataSource<std::string>(name) );
00238 }
00239
00240 base::DataSourceBase::shared_ptr getMember(base::DataSourceBase::shared_ptr item,
00241 base::DataSourceBase::shared_ptr id) const {
00242
00243 typename internal::DataSource<int>::shared_ptr id_indx = internal::DataSource<int>::narrow( internal::DataSourceTypeInfo<int>::getTypeInfo()->convert(id).get() );
00244 typename internal::DataSource<std::string>::shared_ptr id_name = internal::DataSource<std::string>::narrow( id.get() );
00245 if ( id_name ) {
00246 if ( id_name->get() == "size" ) {
00247 try {
00248 return internal::newFunctorDataSource(&get_size<T>, internal::GenerateDataSource()(item.get()) );
00249 } catch(...) {}
00250 }
00251 if ( id_name->get() == "capacity" ) {
00252 try {
00253 return internal::newFunctorDataSource(&get_capacity<T>, internal::GenerateDataSource()(item.get()) );
00254 } catch(...) {}
00255 }
00256 }
00257
00258 if ( id_indx ) {
00259 try {
00260 if ( item->isAssignable() )
00261 return internal::newFunctorDataSource(&get_container_item<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00262 else
00263 return internal::newFunctorDataSource(&get_container_item_copy<T>, internal::GenerateDataSource()(item.get(), id_indx.get() ) );
00264 } catch(...) {}
00265 }
00266 if (id_name) {
00267 log(Error) << "SequenceTypeInfo: No such member : " << id_name->get() << endlog();
00268 }
00269 if (id_indx) {
00270 log(Error) << "SequenceTypeInfo: Invalid index : " << id_indx->get() <<":"<< id_indx->getTypeName() << endlog();
00271 }
00272 if ( !id_name && ! id_indx)
00273 log(Error) << "SequenceTypeInfo: Not a member or index : " << id <<":"<< id->getTypeName() << endlog();
00274 return base::DataSourceBase::shared_ptr();
00275 }
00276 };
00277 }
00278 }
00279
00280 #endif