TypeInfoRepository.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  tag: The SourceWorks Tue Sep 7 00:55:18 CEST 2010 TypeInfoRepository.cpp
3 
4  TypeInfoRepository.cpp - description
5  -------------------
6  begin : Tue September 07 2010
7  copyright : (C) 2010 The SourceWorks
8  email : peter@thesourceworks.com
9 
10  ***************************************************************************
11  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * Lesser General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
38 
39 #include "TypeInfoRepository.hpp"
40 
41 #include "rtt-config.h"
42 
43 #include "../Logger.hpp"
44 #include "TypeTransporter.hpp"
45 #include "TransportPlugin.hpp"
46 #include "../internal/mystd.hpp"
47 #include "../internal/DataSourceTypeInfo.hpp"
48 #include <boost/algorithm/string.hpp>
49 
50 namespace RTT
51 {
52  using namespace std;
53  using namespace detail;
54 
55  namespace {
56  boost::shared_ptr<TypeInfoRepository> typerepos;
57  }
58 
60  {
61  }
62 
63  boost::shared_ptr<TypeInfoRepository> TypeInfoRepository::Instance()
64  {
65  if ( typerepos )
66  return typerepos;
67  typerepos.reset( new TypeInfoRepository() );
68 
69  return typerepos;
70  }
71 
73  typerepos.reset();
74  }
75 
76  void TypeInfoRepository::setAutoLoader(const boost::function<bool (const std::string &)> &loader)
77  {
78  loadTypeKitForName = loader;
79  }
80 
81  TypeInfo* TypeInfoRepository::typeInternal( const std::string& name ) const
82  {
83  MutexLock lock(type_lock);
84  map_t::const_iterator i = data.find( name );
85  if ( i != data.end() ) {
86  // found
87  return i->second;
88  }
89 
90  // try alternate name replace / with dots:
91  string tkname = "/" + boost::replace_all_copy(boost::replace_all_copy(name, string("."), "/"), "<","</");
92  i = data.find( tkname );
93  if ( i != data.end() ) {
94  // found
95  return i->second;
96  }
97 
98  // try alias name
99  for (i = data.begin(); i != data.end(); ++i) {
100  std::vector< std::string > names = i->second->getTypeNames();
101  vector<std::string>::iterator j = names.begin();
102  for (; j != names.end(); ++j) {
103  if(((*j) == name) || ((*j) == tkname)) {
104  return i->second;
105  }
106  }
107  }
108 
109  // not found
110  return 0;
111  }
112 
113  TypeInfo* TypeInfoRepository::type( const std::string& name ) const
114  {
115  TypeInfo *ret = typeInternal(name);
116 
117  if(!ret && loadTypeKitForName)
118  {
119  if(loadTypeKitForName(name))
120  ret = typeInternal(name);
121  }
122 
123  return ret;
124  }
125 
127  {
128  // because of aliases, we only want unique pointers:
129  vector<TypeInfo*> todelete = values(data);
130  sort(todelete.begin(), todelete.end());
131  vector<TypeInfo*>::iterator begin, last = unique( todelete.begin(), todelete.end() );
132  begin = todelete.begin();
133  for( ; begin != last; ++begin )
134  delete *begin;
137  }
138 
140  if (!type_id)
141  return 0;
142  MutexLock lock(type_lock);
143  // Ask each type for its type id name.
144  map_t::const_iterator i = data.begin();
145  for (; i != data.end(); ++i){
146  if (i->second->getTypeId() && *(i->second->getTypeId()) == *type_id)
147  return i->second;
148  }
149  return 0;
150  }
151 
152  TypeInfo* TypeInfoRepository::getTypeById(const char * type_id_name) const {
153  // Ask each type for its type id name.
154  MutexLock lock(type_lock);
155  map_t::const_iterator i = data.begin();
156  for (; i != data.end(); ++i){
157  if (i->second->getTypeId() && i->second->getTypeId()->name() == type_id_name)
158  return i->second;
159  }
160  return 0;
161  }
162 
164  {
165  if (!t)
166  return false;
167  MutexLock lock(type_lock);
168  if (data.count(t->getTypeName() ) ) {
169  log(Error) << "Can't register a new TypeInfo object for '"<<t->getTypeName() << "': one already exists."<<endlog();
170  return false;
171  }
172 
173  data[t->getTypeName()] = t;
174  return true;
175  }
176 
178  {
179  if (!t)
180  return false;
181  std::string tname = t->getTypeName();
182  TypeInfo* ti = t->getTypeInfoObject();
183 
184  {
185  MutexLock lock(type_lock);
186  if (ti && data.count(tname) && data[tname] != ti ) {
187  log(Error) << "Refusing to add type information for '" << tname << "': the name is already in use by another type."<<endlog();
188  return false;
189  }
190  }
191  // Check for first registration, or alias:
192  if ( ti == 0 )
193  ti = new TypeInfo(tname);
194  else
195  ti->addAlias(tname);
196 
197  if ( t->installTypeInfoObject( ti ) ) {
198  delete t;
199  }
200  MutexLock lock(type_lock);
201  // keep track of this type:
202  data[ tname ] = ti;
203 
204  log(Debug) << "Registered Type '"<<tname <<"' to the Orocos Type System."<<Logger::endl;
205  for(Transports::iterator it = transports.begin(); it != transports.end(); ++it)
206  if ( (*it)->registerTransport( tname, ti) )
207  log(Info) << "Registered new '"<< (*it)->getTransportName()<<"' transport for " << tname <<endlog();
208  return true;
209  }
210 
211  std::vector<std::string> TypeInfoRepository::getTypes() const
212  {
213  MutexLock lock(type_lock);
214  return keys( data );
215  }
216 
217  string TypeInfoRepository::toDot( const string& type ) const
218  {
219  if (type.empty())
220  return type;
221  // try alternate name replace / with dots:
222  string dotname = boost::replace_all_copy(boost::replace_all_copy(type, string("/"), "."), "<.","<");
223  if ( dotname[0] == '.')
224  dotname = dotname.substr(1);
225  return dotname;
226  }
227 
228  std::vector<std::string> TypeInfoRepository::getDottedTypes() const
229  {
230  MutexLock lock(type_lock);
231  vector<string> result = keys( data );
232  for( vector<string>::iterator it = result.begin(); it != result.end(); ++it)
233  *it = toDot(*it);
234  return result;
235  }
236 
238  {
239  MutexLock lock(type_lock);
240  transports.reserve( transports.size() + 1 );
241  transports.push_back( tr );
242  // inform transport of existing types.
243  map_t::const_iterator i = data.begin();
244  for( ; i != data.end(); ++i )
245  if ( tr->registerTransport( i->first , i->second ) )
246  log(Info) << "Registered new '"<< tr->getTransportName()<<"' transport for " << i->first <<endlog();
247  // give chance to register fallback protocol:
248  if ( tr->registerTransport("unknown_t", DataSourceTypeInfo<UnknownType>::getTypeInfo() ) == false )
249  log(Debug) << "Transport " << tr->getTransportName() << " did not install a fallback handler for 'unknown_t'." <<endlog();
250  }
251 
253  {
254  // dump the names of all known types
255  log(Debug) << "Types known to the Orocos Type System."<<Logger::endl;
256  MutexLock lock(type_lock);
257  for(map_t::const_iterator it = data.begin(); it != data.end(); ++it)
258  {
259  std::vector<int> transports;
260  transports = it->second->getTransportNames();
261  log(Debug) << "-- " << it->first
262  << " (" << (*it).second->getTypeName() << ") protocols [";
263  for (std::vector<int>::const_iterator iter=transports.begin();
264  iter != transports.end();
265  ++iter)
266  {
267  Logger::log() << *iter;
268  }
269  Logger::log() << "]" << Logger::endl;
270  }
271  // dump the names of all known transports
272  log(Debug) << "Transports known to the Orocos Type System."<<Logger::endl;
273  for(Transports::const_iterator it = transports.begin(); it != transports.end(); ++it)
274  {
275  log(Debug) << "-- " << (*it)->getTransportName() << Logger::endl;
276  }
277  }
278 
279 
280 }
void addAlias(const std::string &alias)
Definition: TypeInfo.cpp:72
const std::string & getTypeName() const
Definition: TypeInfo.hpp:83
std::vector< std::string > getDottedTypes() const
std::vector< std::string > getTypes() const
Definition: mystd.hpp:163
virtual bool installTypeInfoObject(TypeInfo *ti)=0
const std::type_info * TypeId
Definition: TypeInfo.hpp:70
virtual std::string getTransportName() const =0
std::string toDot(const std::string &type) const
void registerTransport(TransportPlugin *tr)
TypeInfo * typeInternal(const std::string &name) const
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
virtual TypeInfo * getTypeInfoObject() const =0
std::vector< typename MapT::key_type > keys(const MapT &map)
Definition: mystd.hpp:151
static Logger & log()
Definition: Logger.cpp:117
std::vector< typename MapT::mapped_type > values(const MapT &map)
Definition: mystd.hpp:140
TypeInfo * getTypeById(TypeInfo::TypeId type_id) const
void setAutoLoader(const boost::function< bool(const std::string &)> &loader)
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:53
virtual const std::string & getTypeName() const =0
static Logger & log()
Definition: Logger.hpp:350
virtual bool registerTransport(std::string type_name, TypeInfo *ti)=0
static Logger::LogFunction endlog()
Definition: Logger.hpp:362
TypeInfo * type(const std::string &name) const
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
Definition: MutexLock.hpp:51


rtt
Author(s): RTT Developers
autogenerated on Tue Jun 25 2019 19:33:37