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 #include "../rtt-config.h"
00040 #include "Types.hpp"
00041 #include "TemplateTypeInfo.hpp"
00042 #include "TemplateConstructor.hpp"
00043
00044 namespace RTT
00045 {
00046 namespace types
00047 {
00048
00055 template<class T>
00056 struct EnumTypeInfo: public TemplateTypeInfo<T, false>
00057 {
00058 protected:
00059 static int enum_to_int(T e)
00060 {
00061 return (int) e;
00062 }
00063
00064 static T int_to_enum(int i)
00065 {
00066 return (T) i;
00067 }
00068
00069 std::map<T,string> to_string;
00070 typedef std::map<T,string> MapType;
00071 public:
00072 EnumTypeInfo(const char* type) :
00073 TemplateTypeInfo<T, false> (type)
00074 {
00075 if (!Types()->type("int")) {
00076 log(Error) << "Failed to register enum <-> int conversion because type int is not known in type system."<<endlog();
00077 } else {
00078 Types()->type("int")->addConstructor(newConstructor(
00079 &EnumTypeInfo<T>::enum_to_int, true));
00080 }
00081 this->addConstructor( newConstructor( &EnumTypeInfo<T>::int_to_enum, true) );
00082 }
00083
00090 virtual bool composeType(base::DataSourceBase::shared_ptr source,
00091 base::DataSourceBase::shared_ptr result) const
00092 {
00093
00094 if (result->update(source.get()))
00095 return true;
00096
00097 internal::DataSource<int>::shared_ptr ds =
00098 internal::DataSource<int>::narrow( source.get() );
00099 if (ds)
00100 {
00101 typename internal::AssignableDataSource<T>::shared_ptr menum =
00102 internal::AssignableDataSource<T>::narrow( source.get() );
00103 assert(menum);
00104 menum->set( (T)ds->get() );
00105 return true;
00106 }
00107
00108 internal::DataSource<string>::shared_ptr dss =
00109 internal::DataSource<string>::narrow( source.get() );
00110 if (dss)
00111 {
00112 typename internal::AssignableDataSource<T>::shared_ptr menum =
00113 internal::AssignableDataSource<T>::narrow( result.get() );
00114 assert(menum);
00115 for( typename MapType::const_iterator it = to_string.begin(); it != to_string.end(); ++it)
00116 if ( it->second == dss->get() ) {
00117 menum->set( it->first );
00118 return true;
00119 }
00120 }
00121
00122 return false;
00123 }
00124
00132 virtual base::DataSourceBase::shared_ptr decomposeType(base::DataSourceBase::shared_ptr source) const
00133 {
00134
00135 typename internal::DataSource<T>::shared_ptr ds = internal::DataSource<T>::narrow( source.get() );
00136 if ( ds )
00137 {
00138
00139 if ( to_string.count( ds->get() ) == 0 ) {
00140 log(Warning) << "No enum-to-string mapping defined for enum " << this->getTypeName() <<". Converting to int."<<endlog();
00141 return new internal::ValueDataSource<int>( ds->get() );
00142 }
00143 internal::ValueDataSource<string>::shared_ptr vds = new internal::ValueDataSource<string>( to_string.find(ds->get())->second );
00144 return vds;
00145 }
00146
00147 return base::DataSourceBase::shared_ptr();
00148 }
00149 };
00150 }
00151 }