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



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019