TypeInfoRepository.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002   tag: The SourceWorks  Tue Sep 7 00:55:18 CEST 2010  TypeInfoRepository.cpp
00003 
00004                         TypeInfoRepository.cpp -  description
00005                            -------------------
00006     begin                : Tue September 07 2010
00007     copyright            : (C) 2010 The SourceWorks
00008     email                : peter@thesourceworks.com
00009 
00010  ***************************************************************************
00011  *   This library is free software; you can redistribute it and/or         *
00012  *   modify it under the terms of the GNU General Public                   *
00013  *   License as published by the Free Software Foundation;                 *
00014  *   version 2 of the License.                                             *
00015  *                                                                         *
00016  *   As a special exception, you may use this file as part of a free       *
00017  *   software library without restriction.  Specifically, if other files   *
00018  *   instantiate templates or use macros or inline functions from this     *
00019  *   file, or you compile this file and link it with other files to        *
00020  *   produce an executable, this file does not by itself cause the         *
00021  *   resulting executable to be covered by the GNU General Public          *
00022  *   License.  This exception does not however invalidate any other        *
00023  *   reasons why the executable file might be covered by the GNU General   *
00024  *   Public License.                                                       *
00025  *                                                                         *
00026  *   This library is distributed in the hope that it will be useful,       *
00027  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00028  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
00029  *   Lesser General Public License for more details.                       *
00030  *                                                                         *
00031  *   You should have received a copy of the GNU General Public             *
00032  *   License along with this library; if not, write to the Free Software   *
00033  *   Foundation, Inc., 59 Temple Place,                                    *
00034  *   Suite 330, Boston, MA  02111-1307  USA                                *
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             // try alternate name replace / with dots:
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         // found
00088         return i->second;
00089     }
00090 
00091     TypeInfoRepository::~TypeInfoRepository()
00092     {
00093         // because of aliases, we only want unique pointers:
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       // Ask each type for its type id name.
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       // Ask each type for its type id name.
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         // Check for first registration, or alias:
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         // keep track of this type:
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         // try alternate name replace / with dots:
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         // inform transport of existing types.
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         // give chance to register fallback protocol:
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         // dump the names of all known types
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         // dump the names of all known transports
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 }


rtt
Author(s): RTT Developers
autogenerated on Sat Jun 8 2019 18:46:33