Orocos Real-Time Toolkit  2.9.0
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 
59  TypeInfoRepository::TypeInfoRepository()
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)
Adds an alias to the this type.
Definition: TypeInfo.cpp:72
const std::string & getTypeName() const
Return the type name which was first registered.
Definition: TypeInfo.hpp:83
std::vector< std::string > getDottedTypes() const
List all registered types in the package.type notation.
std::vector< std::string > getTypes() const
List all types registered with their original type name.
STL namespace.
This class contains all known types to Orocos.
virtual bool installTypeInfoObject(TypeInfo *ti)=0
Installs the type info object in the global data source type info handler and adds any additional fea...
const std::type_info * TypeId
Definition: TypeInfo.hpp:70
A class which registers TypeTransporter instances to types.
virtual std::string getTransportName() const =0
Returns the (protocol) name of this transport.
std::string toDot(const std::string &type) const
Convert any type name returned by getTypes() to the dotted type notation.
All generator classes inherit from this object in order to allow them to be added to the TypeInfoRepo...
void registerTransport(TransportPlugin *tr)
Call this function to add a new (network) transport for Orocos types.
void logTypeInfo() const
Dump all known types, along with transports and their types, to the log.
static std::ostream & endl(std::ostream &__os)
Definition: Logger.cpp:383
bool addType(TypeInfo *ti)
Add a type to the Orocos type repository.
A class for representing a user type, and which can build instances of that type. ...
Definition: TypeInfo.hpp:67
virtual TypeInfo * getTypeInfoObject() const =0
Returns the TypeInfo object of this type, or null if none exists yet.
std::vector< typename MapT::key_type > keys(const MapT &map)
Definition: mystd.hpp:151
Every DataSource of type T has a type info class which it can ask type information.
static Logger & log()
As Instance(), but more userfriendly.
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
Return the type info structure of a given type by its type_id.
void setAutoLoader(const boost::function< bool(const std::string &)> &loader)
Contains TaskContext, Activity, OperationCaller, Operation, Property, InputPort, OutputPort, Attribute.
Definition: Activity.cpp:52
virtual const std::string & getTypeName() const =0
Return the type name for which this generator generates type info features.
virtual bool registerTransport(std::string type_name, TypeInfo *ti)=0
Add a transport for the given type to the types::TypeInfo instance.
TypeInfo * type(const std::string &name) const
Retrieve a type with a given name.
MutexLock is a scope based Monitor, protecting critical sections with a Mutex object through locking ...
Definition: MutexLock.hpp:51