Go to the documentation of this file.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 MutexLock lock(type_lock);
00075 map_t::const_iterator i = data.find( name );
00076 if ( i == data.end() ) {
00077
00078 string tkname = "/" + boost::replace_all_copy(boost::replace_all_copy(name, string("."), "/"), "<","</");
00079 i = data.find( tkname );
00080 if ( i == data.end())
00081 return 0;
00082 }
00083
00084 return i->second;
00085 }
00086
00087 TypeInfoRepository::~TypeInfoRepository()
00088 {
00089
00090 vector<TypeInfo*> todelete = values(data);
00091 sort(todelete.begin(), todelete.end());
00092 vector<TypeInfo*>::iterator begin, last = unique( todelete.begin(), todelete.end() );
00093 begin = todelete.begin();
00094 for( ; begin != last; ++begin )
00095 delete *begin;
00096 delete DataSourceTypeInfo<UnknownType>::TypeInfoObject;
00097 DataSourceTypeInfo<UnknownType>::TypeInfoObject = 0;
00098 }
00099
00100 TypeInfo* TypeInfoRepository::getTypeById(TypeInfo::TypeId type_id) const {
00101 if (!type_id)
00102 return 0;
00103 MutexLock lock(type_lock);
00104
00105 map_t::const_iterator i = data.begin();
00106 for (; i != data.end(); ++i){
00107 if (i->second->getTypeId() && *(i->second->getTypeId()) == *type_id)
00108 return i->second;
00109 }
00110 return 0;
00111 }
00112
00113 TypeInfo* TypeInfoRepository::getTypeById(const char * type_id_name) const {
00114
00115 MutexLock lock(type_lock);
00116 map_t::const_iterator i = data.begin();
00117 for (; i != data.end(); ++i){
00118 if (i->second->getTypeId() && i->second->getTypeId()->name() == type_id_name)
00119 return i->second;
00120 }
00121 return 0;
00122 }
00123
00124 bool TypeInfoRepository::addType(TypeInfo* t)
00125 {
00126 if (!t)
00127 return false;
00128 MutexLock lock(type_lock);
00129 if (data.count(t->getTypeName() ) ) {
00130 log(Error) << "Can't register a new TypeInfo object for '"<<t->getTypeName() << "': one already exists."<<endlog();
00131 return false;
00132 }
00133
00134 data[t->getTypeName()] = t;
00135 return true;
00136 }
00137
00138 bool TypeInfoRepository::addType(TypeInfoGenerator* t)
00139 {
00140 if (!t)
00141 return false;
00142 std::string tname = t->getTypeName();
00143 TypeInfo* ti = t->getTypeInfoObject();
00144
00145 {
00146 MutexLock lock(type_lock);
00147 if (ti && data.count(tname) && data[tname] != ti ) {
00148 log(Error) << "Refusing to add type information for '" << tname << "': the name is already in use by another type."<<endlog();
00149 return false;
00150 }
00151 }
00152
00153 if ( ti == 0 )
00154 ti = new TypeInfo(tname);
00155 else
00156 ti->addAlias(tname);
00157
00158 if ( t->installTypeInfoObject( ti ) ) {
00159 delete t;
00160 }
00161 MutexLock lock(type_lock);
00162
00163 data[ tname ] = ti;
00164
00165 log(Debug) << "Registered Type '"<<tname <<"' to the Orocos Type System."<<Logger::endl;
00166 for(Transports::iterator it = transports.begin(); it != transports.end(); ++it)
00167 if ( (*it)->registerTransport( tname, ti) )
00168 log(Info) << "Registered new '"<< (*it)->getTransportName()<<"' transport for " << tname <<endlog();
00169 return true;
00170 }
00171
00172 std::vector<std::string> TypeInfoRepository::getTypes() const
00173 {
00174 MutexLock lock(type_lock);
00175 return keys( data );
00176 }
00177
00178 string TypeInfoRepository::toDot( const string& type ) const
00179 {
00180 if (type.empty())
00181 return type;
00182
00183 string dotname = boost::replace_all_copy(boost::replace_all_copy(type, string("/"), "."), "<.","<");
00184 if ( dotname[0] == '.')
00185 dotname = dotname.substr(1);
00186 return dotname;
00187 }
00188
00189 std::vector<std::string> TypeInfoRepository::getDottedTypes() const
00190 {
00191 MutexLock lock(type_lock);
00192 vector<string> result = keys( data );
00193 for( vector<string>::iterator it = result.begin(); it != result.end(); ++it)
00194 *it = toDot(*it);
00195 return result;
00196 }
00197
00198 void TypeInfoRepository::registerTransport( TransportPlugin* tr )
00199 {
00200 MutexLock lock(type_lock);
00201 transports.reserve( transports.size() + 1 );
00202 transports.push_back( tr );
00203
00204 map_t::const_iterator i = data.begin();
00205 for( ; i != data.end(); ++i )
00206 if ( tr->registerTransport( i->first , i->second ) )
00207 log(Info) << "Registered new '"<< tr->getTransportName()<<"' transport for " << i->first <<endlog();
00208
00209 if ( tr->registerTransport("unknown_t", DataSourceTypeInfo<UnknownType>::getTypeInfo() ) == false )
00210 log(Debug) << "Transport " << tr->getTransportName() << " did not install a fallback handler for 'unknown_t'." <<endlog();
00211 }
00212
00213 void TypeInfoRepository::logTypeInfo() const
00214 {
00215
00216 log(Debug) << "Types known to the Orocos Type System."<<Logger::endl;
00217 MutexLock lock(type_lock);
00218 for(map_t::const_iterator it = data.begin(); it != data.end(); ++it)
00219 {
00220 std::vector<int> transports;
00221 transports = it->second->getTransportNames();
00222 log(Debug) << "-- " << it->first
00223 << " (" << (*it).second->getTypeName() << ") protocols [";
00224 for (std::vector<int>::const_iterator iter=transports.begin();
00225 iter != transports.end();
00226 ++iter)
00227 {
00228 Logger::log() << *iter;
00229 }
00230 Logger::log() << "]" << Logger::endl;
00231 }
00232
00233 log(Debug) << "Transports known to the Orocos Type System."<<Logger::endl;
00234 for(Transports::const_iterator it = transports.begin(); it != transports.end(); ++it)
00235 {
00236 log(Debug) << "-- " << (*it)->getTransportName() << Logger::endl;
00237 }
00238 }
00239
00240
00241 }