Main MRPT website > C++ reference for MRPT 1.5.7
internal_class_registry.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 #include "base-precomp.h" // Precompiled headers
11 
12 
13 #include <mrpt/utils/CObject.h>
14 
15 #include <map>
16 #include <cstdarg>
17 #include <mutex>
18 #include <atomic>
19 #include <iostream>
20 
22 
23 using namespace mrpt;
24 using namespace mrpt::utils;
25 using namespace mrpt::synch;
26 using namespace mrpt::system;
27 using namespace std;
28 
29 
30 /*---------------------------------------------------------------
31  STATIC GLOBAL VARIABLES
32  ---------------------------------------------------------------*/
34 
35 // Creation on first call pattern:
37 {
38  static std::atomic<int> cnt(0);
39  return cnt;
40 }
41 
42 // Creation on first call pattern:
44 {
47  return lst;
48 }
49 
50 
51 namespace mrpt
52 {
53  namespace utils
54  {
55  typedef std::map<std::string,const TRuntimeClassId*> TClassnameToRuntimeId;
56 
57  /** A singleton with the central registry for CSerializable run-time classes: users do not use this class in any direct way.
58  * \note Class is thread-safe.
59  */
61  {
62  public:
63  /** The unique access point point to the singleton instance.
64  */
66  {
67  static CClassRegistry obj;
68  return obj;
69  }
70 
71  void Add( const std::string &className, const TRuntimeClassId &id )
72  {
73  m_being_modified=true;
74  {
75  std::unique_lock<std::mutex> lk(m_cs);
76 
77  // Sanity check: don't allow registering twice the same class name!
78  const auto it = registeredClasses.find(className);
79  if (it != registeredClasses.cend()) {
80  if (it->second != &id) {
81  std::cerr << mrpt::format("[MRPT class registry] Warning: overwriting already registered className=`%s` with different `TRuntimeClassId`!\n", className.c_str());
82  }
83  }
84  registeredClasses[className] = &id;
85  }
86  m_being_modified=false;
87  }
88 
89  const TRuntimeClassId *Get(const std::string &className)
90  {
91  // Optimization to avoid the costly lock() in virtually all situations:
92  bool has_to_unlock = false;
93  if (m_being_modified)
94  {
95  m_cs.lock();
96  has_to_unlock = true;
97  }
98  const TRuntimeClassId *ret = registeredClasses[className];
99  if (has_to_unlock) m_cs.unlock();
100  return ret;
101  }
102 
103  std::vector<const TRuntimeClassId*> getListOfAllRegisteredClasses()
104  {
105  std::unique_lock<std::mutex> lk(m_cs);
106 
107  std::vector<const TRuntimeClassId*> ret;
108  for (TClassnameToRuntimeId::iterator it=registeredClasses.begin();it!=registeredClasses.end();++it)
109  ret.push_back( it->second );
110  return ret;
111  }
112 
113  private:
114  // PRIVATE constructor
115  CClassRegistry() : m_being_modified(false)
116  {
117  }
118  // PRIVATE destructor
120 
121  // This must be static since we can be called from C startup
122  // functions and it cannot be assured that classesKeeper will be
123  // initialized before other classes that call it...
125  std::mutex m_cs;
126  std::atomic<bool> m_being_modified;
127 
128  };
129 
130  } // End of namespace
131 } // End of namespace
132 
133 
134 /** Register all pending classes - to be called just before de-serializing an object, for example.
135 */
137 {
138  if (!pending_class_registers_modified) return; // Quick return
139 
140  while( pending_class_registers_count()!=0 )
141  {
142  TRegisterFunction *ptrToPtr = pending_class_registers().get();
144 
145  // Call it:
146  if((*ptrToPtr)!=NULL)
147  {
148  (*(*ptrToPtr)) ();
149  delete ptrToPtr;
150  }
151  }
153 }
154 
155 
156 
157 /*---------------------------------------------------------------
158  RegisterClass
159  ---------------------------------------------------------------*/
160 void utils::registerClass(const TRuntimeClassId* pNewClass)
161 {
162  // Register it:
163  CClassRegistry::Instance().Add( std::string( pNewClass->className ), *pNewClass);
164 
165  // Automatically register all classes when the first one is registered.
167 }
168 
169 /** For internal use within mrpt sources, and only in exceptional cases (CMultiMetricMaps, CImage,...)
170  */
171 void utils::registerClassCustomName(const char*customName, const TRuntimeClassId* pNewClass)
172 {
173  // Register it:
174  CClassRegistry::Instance().Add( customName, *pNewClass);
175 
176  // Automatically register all classes when the first one is registered.
178 }
179 
180 /*---------------------------------------------------------------
181  getAllRegisteredClasses
182  ---------------------------------------------------------------*/
183 std::vector<const TRuntimeClassId*> utils::getAllRegisteredClasses()
184 {
186 }
187 
188 std::vector<const TRuntimeClassId*> utils::getAllRegisteredClassesChildrenOf(const TRuntimeClassId* parent_id)
189 {
190  std::vector<const TRuntimeClassId*> res;
191  const auto lst = mrpt::utils::getAllRegisteredClasses();
192  for (const auto &c : lst) {
193  if (c->derivedFrom(parent_id) && c!=parent_id) {
194  res.push_back(c);
195  }
196  }
197  return res;
198 }
199 
200 /*---------------------------------------------------------------
201  findRegisteredClass
202  ---------------------------------------------------------------*/
204 {
205  return CClassRegistry::Instance().Get( className );
206 }
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:29
static CClassRegistry & Instance()
The unique access point point to the singleton instance.
void BASE_IMPEXP registerAllPendingClasses()
Register all pending classes - to be called just before de-serializing an object, for example...
std::vector< const mrpt::utils::TRuntimeClassId * > BASE_IMPEXP getAllRegisteredClasses()
Returns a list with all the classes registered in the system through mrpt::utils::registerClass.
Scalar * iterator
Definition: eigen_plugins.h:23
STL namespace.
std::map< std::string, const TRuntimeClassId * > TClassnameToRuntimeId
GLsizei GLsizei GLuint * obj
Definition: glext.h:3902
void BASE_IMPEXP registerClassCustomName(const char *customName, const TRuntimeClassId *pNewClass)
Mostly for internal use within mrpt sources, to handle exceptional cases with multiple serialization ...
void(* TRegisterFunction)()
const GLubyte * c
Definition: glext.h:5590
const TRuntimeClassId BASE_IMPEXP * findRegisteredClass(const std::string &className)
Return info about a given class by its name, or NULL if the class is not registered.
const TRuntimeClassId * Get(const std::string &className)
This namespace provides multitask, synchronization utilities.
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
A thread-safe template queue for object passing between threads; for a template argument of T...
GLsizei const GLchar ** string
Definition: glext.h:3919
CThreadSafeQueue< TRegisterFunction > BASE_IMPEXP & pending_class_registers()
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
volatile bool BASE_IMPEXP pending_class_registers_modified
Set to true if pending_class_registers() has been called after registerAllPendingClasses(). Startup value is false.
GLuint id
Definition: glext.h:3770
A singleton with the central registry for CSerializable run-time classes: users do not use this class...
void Add(const std::string &className, const TRuntimeClassId &id)
void BASE_IMPEXP registerClass(const mrpt::utils::TRuntimeClassId *pNewClass)
Register a class into the MRPT internal list of "CSerializable" descendents.
std::vector< const TRuntimeClassId * > getListOfAllRegisteredClasses()
A structure that holds runtime class type information.
Definition: CObject.h:36
GLuint res
Definition: glext.h:6298
const char * className
Definition: CObject.h:38
std::vector< const TRuntimeClassId * > BASE_IMPEXP getAllRegisteredClassesChildrenOf(const TRuntimeClassId *parent_id)
Like getAllRegisteredClasses(), but filters the list to only include children clases of a given base ...
std::atomic< int > BASE_IMPEXP & pending_class_registers_count()



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019