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