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 #ifndef ORO_TEMPLATE_TYPEINFO_HPP
00039 #define ORO_TEMPLATE_TYPEINFO_HPP
00040
00041 #include "Types.hpp"
00042 #include "../Property.hpp"
00043 #include "../Attribute.hpp"
00044 #include "../Logger.hpp"
00045 #include "../InputPort.hpp"
00046 #include "../OutputPort.hpp"
00047 #include <ostream>
00048 #include "../internal/FusedFunctorDataSource.hpp"
00049 #include "../internal/CreateSequence.hpp"
00050 #include "PropertyDecomposition.hpp"
00051
00052 #include <boost/type_traits/function_traits.hpp>
00053 #include <boost/type_traits/remove_const.hpp>
00054 #include <boost/type_traits/remove_reference.hpp>
00055
00056 #include "../rtt-config.h"
00057
00058 namespace RTT
00059 {
00060 namespace types {
00061 template<typename T, bool b_value>
00062 struct TypeStreamSelector;
00063 template<typename T>
00064 struct TypeStreamSelector<T,true>
00065 {
00066 static std::ostream& write(std::ostream& os, T const& t)
00067 {
00068 #ifdef OS_HAVE_STREAMS
00069 os << t;
00070 #endif
00071 return os;
00072 }
00073 static std::istream& read(std::istream& os, T& t)
00074 {
00075 #ifdef OS_HAVE_STREAMS
00076 os >> t;
00077 #endif
00078 return os;
00079 }
00080 };
00081 template<typename T>
00082 struct TypeStreamSelector<T,false>
00083 {
00084 static std::ostream& write(std::ostream& os, T)
00085 {
00086 return os;
00087 }
00088 static std::istream& read(std::istream& os, T& )
00089 {
00090 return os;
00091 }
00092 };
00093
00110 template<typename T, bool use_ostream = false>
00111 class TemplateTypeInfo
00112 : public TypeInfo
00113 {
00114 const std::string tname;
00115 public:
00116 using TypeInfo::buildConstant;
00117 using TypeInfo::buildVariable;
00118
00122 typedef T UserType;
00126 typedef typename Property<T>::DataSourceType PropertyType;
00127
00135 TemplateTypeInfo(std::string name)
00136 : tname(name)
00137 {
00138 }
00139
00140 virtual ~TemplateTypeInfo()
00141 {
00142 if ( internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject == this)
00143 internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject = 0;
00144 }
00145
00146 bool installTypeInfoObject() {
00147
00148 TypeInfo* orig = internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject;
00149 if ( orig != 0) {
00150 string oname = orig->getTypeName();
00151 if ( oname != tname ) {
00152 log(Info) << "TypeInfo for type '" << tname << "' already exists as '"
00153 << oname
00154 << "': I'll alias the original and install the new instance." << endlog();
00155 this->migrateProtocols( orig );
00156 Types()->aliasType( oname, this);
00157 }
00158 } else {
00159
00160 if ( Types()->type(tname) ) {
00161 log(Error) << "You attemted to register type name "<< tname << " which is already "
00162 << "in use for a different C++ type." <<endlog();
00163 return false;
00164 }
00165 }
00166
00167 internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject = this;
00168 return true;
00169 }
00170
00171 base::AttributeBase* buildConstant(std::string name, base::DataSourceBase::shared_ptr dsb) const
00172 {
00173 typename internal::DataSource<PropertyType>::shared_ptr res =
00174 boost::dynamic_pointer_cast< internal::DataSource<PropertyType> >( internal::DataSourceTypeInfo<PropertyType>::getTypeInfo()->convert(dsb));
00175 if ( res ) {
00176 res->get();
00177 Logger::log() << Logger::Info << "Building "<<tname<<" Constant '"<<name<<"' with value "<< dsb->getTypeInfo()->toString(dsb) <<Logger::endl;
00178 return new Constant<PropertyType>( name, res->rvalue() );
00179 }
00180 else
00181 return 0;
00182 }
00183
00184 base::AttributeBase* buildVariable(std::string name) const
00185 {
00186
00187 Logger::log() << Logger::Debug << "Building variable '"<<name <<"' of type " << tname <<Logger::endl;
00188 return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >() );
00189 }
00190
00191 base::AttributeBase* buildAttribute( std::string name, base::DataSourceBase::shared_ptr in) const
00192 {
00193 typename internal::AssignableDataSource<PropertyType>::shared_ptr ds;
00194 if ( !in )
00195 ds = new internal::ValueDataSource<PropertyType>();
00196 else
00197 ds = internal::AssignableDataSource<PropertyType>::narrow( in.get() );
00198 if (!ds)
00199 return 0;
00200
00201 Logger::log() << Logger::Debug << "Building Attribute '"<< name <<"' of type " << tname <<Logger::endl;
00202 return new Attribute<PropertyType>( name, ds.get() );
00203 }
00204
00205 base::AttributeBase* buildAlias(std::string name, base::DataSourceBase::shared_ptr in ) const
00206 {
00207 typename internal::DataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<T> >( internal::DataSourceTypeInfo<T>::getTypeInfo()->convert(in) );
00208 if ( ! ds )
00209 return 0;
00210 return new Alias( name, ds );
00211 }
00212
00213 base::DataSourceBase::shared_ptr buildActionAlias(base::ActionInterface* action, base::DataSourceBase::shared_ptr in) const
00214 {
00215 typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( in );
00216 if ( ads )
00217 return new internal::ActionAliasAssignableDataSource<T>(action, ads.get());
00218
00219 typename internal::DataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<T> >( in );
00220 if ( ! ds )
00221 return 0;
00222 return new internal::ActionAliasDataSource<T>(action, ds.get());
00223 }
00224
00225 virtual const std::string& getTypeName() const { return tname; }
00226
00227 virtual base::PropertyBase* buildProperty(const std::string& name, const std::string& desc, base::DataSourceBase::shared_ptr source = 0) const {
00228 if (source) {
00229 typename internal::AssignableDataSource<PropertyType>::shared_ptr ad
00230 = boost::dynamic_pointer_cast< internal::AssignableDataSource<PropertyType> >( source );
00231 if (ad)
00232 return new Property<PropertyType>(name, desc, ad );
00233 else {
00234 log(Error) <<"Failed to build 'Property<"<< this->tname <<"> "<<name<<"' from given DataSourceBase. Returning default."<<endlog();
00235 }
00236 }
00237 return new Property<PropertyType>(name, desc, PropertyType());
00238 }
00239
00240 virtual base::DataSourceBase::shared_ptr buildValue() const {
00241 return new internal::ValueDataSource<PropertyType>();
00242 }
00243 virtual base::DataSourceBase::shared_ptr buildReference(void* ptr) const {
00244 return new internal::ReferenceDataSource<PropertyType>(*static_cast<PropertyType*>(ptr));
00245 }
00246
00247 virtual std::ostream& write( std::ostream& os, base::DataSourceBase::shared_ptr in ) const {
00248 typename internal::DataSource<T>::shared_ptr d = boost::dynamic_pointer_cast< internal::DataSource<T> >( in );
00249 if ( d && use_ostream )
00250 types::TypeStreamSelector<T, use_ostream>::write( os, d->rvalue() );
00251 else {
00252 #ifdef OS_HAVE_STREAMS
00253 std::string output = std::string("(")+ in->getTypeName() +")";
00254 os << output;
00255 #endif
00256 }
00257 return os;
00258
00259 }
00260
00261 virtual std::istream& read( std::istream& os, base::DataSourceBase::shared_ptr out ) const {
00262 typename internal::AssignableDataSource<T>::shared_ptr d = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( out );
00263 if ( d && use_ostream ) {
00264 types::TypeStreamSelector<T, use_ostream>::read( os, d->set() );
00265 d->updated();
00266 }
00267 return os;
00268 }
00269
00270 virtual bool isStreamable() const {
00271 return use_ostream;
00272 }
00273
00274 virtual bool composeType( base::DataSourceBase::shared_ptr source, base::DataSourceBase::shared_ptr result) const {
00275
00276 if ( result->update( source.get() ) )
00277 return true;
00278
00279
00280 const internal::DataSource<PropertyBag>* pb = dynamic_cast< const internal::DataSource<PropertyBag>* > (source.get() );
00281 if ( !pb )
00282 return false;
00283 typename internal::AssignableDataSource<PropertyType>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<PropertyType> >( result );
00284 if ( !ads )
00285 return false;
00286
00287
00288 if ( composeTypeImpl( pb->rvalue(), ads->set() ) )
00289 ads->updated();
00290 else {
00291 Logger::log() <<Logger::Debug<<"Failed to compose from "<< source->getTypeName() <<Logger::endl;
00292 return false;
00293 }
00294 Logger::log() <<Logger::Debug<<"Successfuly composed type from "<< source->getTypeName() <<Logger::endl;
00295 return true;
00296 }
00297
00304 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00305 {
00306
00307
00308 base::DataSourceBase::shared_ptr bc_convert = convertType(source);
00309 typename internal::DataSource<PropertyBag>::shared_ptr bc_ds = boost::dynamic_pointer_cast< internal::DataSource<PropertyBag> >( bc_convert );
00310 if ( bc_ds )
00311 return bc_ds;
00312
00313
00314 typename internal::DataSource<PropertyType>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<PropertyType> >( source );
00315 if ( !ds )
00316 return base::DataSourceBase::shared_ptr();
00317 Property<PropertyBag> targetbag_p("targetbag");
00318 if (decomposeTypeImpl( ds->rvalue(), targetbag_p.value() ))
00319 return targetbag_p.getDataSource();
00320 return base::DataSourceBase::shared_ptr();
00321 }
00322
00323 virtual bool decomposeType( base::DataSourceBase::shared_ptr source, PropertyBag& targetbag ) const {
00324
00325 typename internal::DataSource<PropertyType>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<PropertyType> >( source );
00326 if ( !ds )
00327 return false;
00328
00329 return decomposeTypeImpl( ds->rvalue(), targetbag );
00330 }
00331
00335 virtual bool composeTypeImpl(const PropertyBag& source, typename internal::AssignableDataSource<T>::reference_t result) const {
00336 return false;
00337 }
00338
00343 virtual bool decomposeTypeImpl( typename internal::AssignableDataSource<T>::const_reference_t source, PropertyBag& targetbag ) const {
00344 return false;
00345 }
00346
00347 std::string getTypeIdName() const { return typeid(T).name(); }
00348
00349
00350 base::InputPortInterface* inputPort(std::string const& name) const { return new InputPort<T>(name); }
00351 base::OutputPortInterface* outputPort(std::string const& name) const { return new OutputPort<T>(name); }
00352
00353 base::ChannelElementBase::shared_ptr buildDataStorage(ConnPolicy const& policy) const {
00354 return internal::ConnFactory::buildDataStorage<T>(policy);
00355 }
00356
00357 base::ChannelElementBase::shared_ptr buildChannelOutput(base::InputPortInterface& port) const
00358 {
00359 return internal::ConnFactory::buildChannelOutput(
00360 static_cast<RTT::InputPort<T>&>(port), new internal::SimpleConnID());
00361 }
00362
00363 base::ChannelElementBase::shared_ptr buildChannelInput(base::OutputPortInterface& port) const
00364 {
00365 return internal::ConnFactory::buildChannelInput(
00366 static_cast<RTT::OutputPort<T>&>(port), new internal::SimpleConnID(), 0 );
00367 }
00368 };
00369 }}
00370
00371 #endif