Orocos Real-Time Toolkit
2.5.0
|
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