Orocos Real-Time Toolkit  2.5.0
PrimitiveTypeInfo.hpp
00001 #ifndef ORO_PRIMITIVE_TYPEINFO_HPP
00002 #define ORO_PRIMITIVE_TYPEINFO_HPP
00003 
00004 #include "Types.hpp"
00005 #include "../Property.hpp"
00006 #include "../Attribute.hpp"
00007 #include "../Logger.hpp"
00008 #include "TypeStreamSelector.hpp"
00009 
00010 #include "../rtt-config.h"
00011 
00012 namespace RTT
00013 {
00014     namespace types {
00015 
00029     template<typename T, bool use_ostream = false>
00030     class PrimitiveTypeInfo
00031         : public TypeInfo
00032     {
00033     protected:
00034         const std::string tname;
00035     public:
00036         using TypeInfo::buildConstant;
00037         using TypeInfo::buildVariable;
00038 
00042         typedef T DataType;
00043 
00051         PrimitiveTypeInfo(std::string name)
00052             : tname(name)
00053         {
00054         }
00055 
00056         virtual ~PrimitiveTypeInfo()
00057         {
00058             if ( internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject == this)
00059                 internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject = 0;
00060         }
00061 
00062         bool installTypeInfoObject() {
00063             // Install the type info object for T.
00064             TypeInfo* orig = internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject;
00065             if ( orig != 0) {
00066                 std::string oname = orig->getTypeName();
00067                 if ( oname != tname ) {
00068                     log(Info) << "TypeInfo for type '" << tname << "' already exists as '"
00069                               << oname
00070                               << "': I'll alias the original and install the new instance." << endlog();
00071                     this->migrateProtocols( orig );
00072                     Types()->aliasType( oname, this); // deletes orig !
00073                 }
00074             } else {
00075                 // check for type name conflict (ie "string" for "std::string" and "Foo::Bar"
00076                 if ( Types()->type(tname) ) {
00077                     log(Error) << "You attemted to register type name "<< tname << " which is already "
00078                                << "in use for a different C++ type." <<endlog();
00079                     return false;
00080                 }
00081             }
00082             // finally install it:
00083             internal::DataSourceTypeInfo<T>::value_type_info::TypeInfoObject = this;
00084             return true;
00085         }
00086 
00087         base::AttributeBase* buildConstant(std::string name, base::DataSourceBase::shared_ptr dsb) const
00088         {
00089             typename internal::DataSource<DataType>::shared_ptr res =
00090                 boost::dynamic_pointer_cast< internal::DataSource<DataType> >( internal::DataSourceTypeInfo<DataType>::getTypeInfo()->convert(dsb));
00091             if ( res ) {
00092                 res->get();
00093                 Logger::log() << Logger::Info << "Building "<<tname<<" Constant '"<<name<<"' with value "<< dsb->getTypeInfo()->toString(dsb) <<Logger::endl;
00094                 return new Constant<DataType>( name, res->rvalue() );
00095             }
00096             else
00097                 return 0;
00098         }
00099 
00100         base::AttributeBase* buildVariable(std::string name) const
00101         {
00102             // A variable starts its life as unbounded.
00103             Logger::log() << Logger::Debug << "Building variable '"<<name <<"' of type " << tname <<Logger::endl;
00104             return new Attribute<T>( name, new internal::UnboundDataSource<internal::ValueDataSource<T> >() );
00105         }
00106 
00107         base::AttributeBase* buildAttribute( std::string name, base::DataSourceBase::shared_ptr in) const
00108         {
00109             typename internal::AssignableDataSource<DataType>::shared_ptr ds;
00110             if ( !in )
00111                 ds = new internal::ValueDataSource<DataType>();
00112             else
00113                 ds = internal::AssignableDataSource<DataType>::narrow( in.get() );
00114             if (!ds)
00115                 return 0;
00116             // An attribute is always bounded.
00117             Logger::log() << Logger::Debug << "Building Attribute '"<< name <<"' of type " << tname <<Logger::endl;
00118             return new Attribute<DataType>( name, ds.get() );
00119         }
00120 
00121         base::AttributeBase* buildAlias(std::string name, base::DataSourceBase::shared_ptr in ) const
00122         {
00123             typename internal::DataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<T> >( internal::DataSourceTypeInfo<T>::getTypeInfo()->convert(in) );
00124             if ( ! ds )
00125                 return 0;
00126             return new Alias( name, ds );
00127         }
00128 
00129         base::DataSourceBase::shared_ptr buildActionAlias(base::ActionInterface* action, base::DataSourceBase::shared_ptr in) const
00130         {
00131             typename internal::AssignableDataSource<T>::shared_ptr ads = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( in ); // no type conversion is done.
00132             if ( ads )
00133                 return new internal::ActionAliasAssignableDataSource<T>(action, ads.get());
00134 
00135             typename internal::DataSource<T>::shared_ptr ds = boost::dynamic_pointer_cast< internal::DataSource<T> >( in ); // no type conversion is done.
00136             if ( ! ds )
00137                 return 0;
00138             return new internal::ActionAliasDataSource<T>(action, ds.get());
00139         }
00140 
00141         virtual const std::string& getTypeName() const { return tname; }
00142 
00143         virtual base::PropertyBase* buildProperty(const std::string& name, const std::string& desc, base::DataSourceBase::shared_ptr source = 0) const {
00144             if (source) {
00145                typename internal::AssignableDataSource<DataType>::shared_ptr ad
00146                     = boost::dynamic_pointer_cast< internal::AssignableDataSource<DataType> >( source );
00147                 if (ad)
00148                     return new Property<DataType>(name, desc, ad );
00149                 else {
00150                     log(Error) <<"Failed to build 'Property<"<< this->tname <<"> "<<name<<"' from given DataSourceBase. Returning default."<<endlog();
00151                 }
00152             }
00153             return new Property<DataType>(name, desc, DataType());
00154         }
00155 
00156         virtual base::DataSourceBase::shared_ptr buildValue() const {
00157             return new internal::ValueDataSource<DataType>();
00158         }
00159         virtual base::DataSourceBase::shared_ptr buildReference(void* ptr) const {
00160             return new internal::ReferenceDataSource<DataType>(*static_cast<DataType*>(ptr));
00161         }
00162 
00163         virtual std::ostream& write( std::ostream& os, base::DataSourceBase::shared_ptr in ) const {
00164             typename internal::DataSource<T>::shared_ptr d = boost::dynamic_pointer_cast< internal::DataSource<T> >( in );
00165             if ( d && use_ostream )
00166                 types::TypeStreamSelector<T, use_ostream>::write( os, d->rvalue() );
00167             else {
00168 #ifdef OS_HAVE_STREAMS
00169                 std::string output = std::string("(")+ in->getTypeName() +")";
00170                 os << output;
00171 #endif
00172             }
00173             return os;
00174             //return os << "("<< tname <<")"
00175         }
00176 
00177         virtual std::istream& read( std::istream& os, base::DataSourceBase::shared_ptr out ) const {
00178             typename internal::AssignableDataSource<T>::shared_ptr d = boost::dynamic_pointer_cast< internal::AssignableDataSource<T> >( out );
00179             if ( d && use_ostream ) {
00180                 types::TypeStreamSelector<T, use_ostream>::read( os, d->set() );
00181                 d->updated(); // because use of set().
00182             }
00183             return os;
00184         }
00185 
00186         virtual bool isStreamable() const {
00187             return use_ostream;
00188         }
00189 
00190         virtual bool composeType( base::DataSourceBase::shared_ptr source, base::DataSourceBase::shared_ptr result) const {
00191             return false;
00192         }
00193 
00197         virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00198         {
00199             return source;
00200         }
00201 
00202         virtual bool decomposeType( base::DataSourceBase::shared_ptr source, PropertyBag& targetbag ) const {
00203             return false;
00204         }
00205 
00206         TypeInfo::TypeId getTypeId() const { return &typeid(T); }
00207         const char * getTypeIdName() const { return typeid(T).name(); }
00208 
00209         base::InputPortInterface*  inputPort(std::string const& name) const { return 0; }
00210         base::OutputPortInterface* outputPort(std::string const& name) const { return 0; }
00211 
00212         base::ChannelElementBase::shared_ptr buildDataStorage(ConnPolicy const& policy) const {
00213             return base::ChannelElementBase::shared_ptr();
00214         }
00215 
00216         base::ChannelElementBase::shared_ptr buildChannelOutput(base::InputPortInterface& port) const
00217         {
00218             return base::ChannelElementBase::shared_ptr();
00219         }
00220 
00221         base::ChannelElementBase::shared_ptr buildChannelInput(base::OutputPortInterface& port) const
00222         {
00223             return base::ChannelElementBase::shared_ptr();
00224         }
00225     };
00226 }}
00227 
00228 #endif