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 "TypeInfoRepository.hpp"
00040
00041 #include "rtt-config.h"
00042
00043 #include "../Logger.hpp"
00044 #include "TypeTransporter.hpp"
00045 #include "TransportPlugin.hpp"
00046 #include "../internal/mystd.hpp"
00047 #include "../internal/DataSourceTypeInfo.hpp"
00048 #include <boost/algorithm/string.hpp>
00049
00050 namespace RTT
00051 {
00052 using namespace std;
00053 using namespace detail;
00054
00055 namespace {
00056 boost::shared_ptr<TypeInfoRepository> typerepos;
00057 }
00058
00059 TypeInfoRepository::TypeInfoRepository()
00060 {
00061 }
00062
00063 boost::shared_ptr<TypeInfoRepository> TypeInfoRepository::Instance()
00064 {
00065 if ( typerepos )
00066 return typerepos;
00067 typerepos.reset( new TypeInfoRepository() );
00068
00069 return typerepos;
00070 }
00071
00072 TypeInfo* TypeInfoRepository::type( const std::string& name ) const
00073 {
00074 map_t::const_iterator i = data.find( name );
00075 if ( i == data.end() ) {
00076
00077 string tkname = "/" + boost::replace_all_copy(boost::replace_all_copy(name, string("."), "/"), "<","</");
00078 i = data.find( tkname );
00079 if ( i == data.end())
00080 return 0;
00081 }
00082
00083 return i->second;
00084 }
00085
00086 TypeInfoRepository::~TypeInfoRepository()
00087 {
00088
00089 vector<TypeInfo*> todelete = values(data);
00090 sort(todelete.begin(), todelete.end());
00091 vector<TypeInfo*>::iterator begin, last = unique( todelete.begin(), todelete.end() );
00092 begin = todelete.begin();
00093 for( ; begin != last; ++begin )
00094 delete *begin;
00095 delete DataSourceTypeInfo<UnknownType>::TypeInfoObject;
00096 DataSourceTypeInfo<UnknownType>::TypeInfoObject = 0;
00097 }
00098
00099
00100 TypeInfo* TypeInfoRepository::getTypeById(std::string type_id_name) const {
00101
00102 map_t::const_iterator i = data.begin();
00103 for (; i != data.end(); ++i){
00104 if (i->second->getTypeIdName() == type_id_name)
00105 return i->second;
00106 }
00107 return 0;
00108 }
00109
00110 bool TypeInfoRepository::addType(TypeInfo* t)
00111 {
00112 std::string tname = t->getTypeName();
00113
00114 if ( !t->installTypeInfoObject() ) {
00115
00116 delete t;
00117 return false;
00118 }
00119
00120 data[ tname ] = t;
00121
00122 log(Debug) << "Registered Type '"<<tname <<"' to the Orocos Type System."<<Logger::endl;
00123 for(Transports::iterator it = transports.begin(); it != transports.end(); ++it)
00124 if ( (*it)->registerTransport( tname, t) )
00125 log(Info) << "Registered new '"<< (*it)->getTransportName()<<"' transport for " << tname <<endlog();
00126 return true;
00127 }
00128
00129 bool TypeInfoRepository::aliasType(const string& alias, TypeInfo* source)
00130 {
00131 if (source) {
00132 if (data.count(alias) && data[alias] != source)
00133 delete data[alias];
00134 data[alias] = source;
00135 } else {
00136 log(Error) << "Could not alias type name "<< alias <<" with (null) type info object."<<endlog();
00137 return false;
00138 }
00139 return true;
00140 }
00141
00142 std::vector<std::string> TypeInfoRepository::getTypes() const
00143 {
00144 return keys( data );
00145 }
00146
00147 string TypeInfoRepository::toDot( const string& type ) const
00148 {
00149 if (type.empty())
00150 return type;
00151
00152 string dotname = boost::replace_all_copy(boost::replace_all_copy(type, string("/"), "."), "<.","<");
00153 if ( dotname[0] == '.')
00154 dotname = dotname.substr(1);
00155 return dotname;
00156 }
00157
00158 std::vector<std::string> TypeInfoRepository::getDottedTypes() const
00159 {
00160 vector<string> result = keys( data );
00161 for( vector<string>::iterator it = result.begin(); it != result.end(); ++it)
00162 *it = toDot(*it);
00163 return result;
00164 }
00165
00166 void TypeInfoRepository::registerTransport( TransportPlugin* tr )
00167 {
00168 transports.reserve( transports.size() + 1 );
00169 transports.push_back( tr );
00170
00171 map_t::const_iterator i = data.begin();
00172 for( ; i != data.end(); ++i )
00173 if ( tr->registerTransport( i->first , i->second ) )
00174 log(Info) << "Registered new '"<< tr->getTransportName()<<"' transport for " << i->first <<endlog();
00175
00176 if ( tr->registerTransport("unknown_t", DataSourceTypeInfo<UnknownType>::getTypeInfo() ) == false )
00177 log(Debug) << "Transport " << tr->getTransportName() << " did not install a fallback handler for 'unknown_t'." <<endlog();
00178 }
00179
00180 void TypeInfoRepository::logTypeInfo() const
00181 {
00182
00183 log(Debug) << "Types known to the Orocos Type System."<<Logger::endl;
00184 for(map_t::const_iterator it = data.begin(); it != data.end(); ++it)
00185 {
00186 std::vector<int> transports;
00187 transports = it->second->getTransportNames();
00188 log(Debug) << "-- " << it->first
00189 << " (" << (*it).second->getTypeName() << ") protocols [";
00190 for (std::vector<int>::const_iterator iter=transports.begin();
00191 iter != transports.end();
00192 ++iter)
00193 {
00194 Logger::log() << *iter;
00195 }
00196 Logger::log() << "]" << Logger::endl;
00197 }
00198
00199 log(Debug) << "Transports known to the Orocos Type System."<<Logger::endl;
00200 for(Transports::const_iterator it = transports.begin(); it != transports.end(); ++it)
00201 {
00202 log(Debug) << "-- " << (*it)->getTransportName() << Logger::endl;
00203 }
00204 }
00205
00206
00207 }