@@ -76,11 +76,14 @@ namespace impl
76
76
typedef std::string LibraryPath;
77
77
typedef std::string ClassName;
78
78
typedef std::string BaseClassName;
79
- typedef std::map<ClassName, impl:: AbstractMetaObjectBase * > FactoryMap;
79
+ typedef std::map<ClassName, std::shared_ptr< AbstractMetaObjectBase> > FactoryMap;
80
80
typedef std::map<BaseClassName, FactoryMap> BaseToFactoryMapMap;
81
81
typedef std::pair<LibraryPath, std::shared_ptr<rcpputils::SharedLibrary>> LibraryPair;
82
82
typedef std::vector<LibraryPair> LibraryVector;
83
- typedef std::vector<AbstractMetaObjectBase *> MetaObjectVector;
83
+ typedef std::vector<std::shared_ptr<AbstractMetaObjectBase>> MetaObjectVector;
84
+
85
+ CLASS_LOADER_PUBLIC
86
+ MetaObjectVector & getMetaObjectGraveyard ();
84
87
85
88
CLASS_LOADER_PUBLIC
86
89
void printDebugInfoToScreen ();
@@ -139,8 +142,15 @@ ClassLoader * getCurrentlyActiveClassLoader();
139
142
* @param loader - pointer to the currently active ClassLoader.
140
143
*/
141
144
CLASS_LOADER_PUBLIC
142
- void setCurrentlyActiveClassLoader (ClassLoader * loader);
145
+ void setCurrentlyActiveClassLoader (std::shared_ptr< ClassLoader> loader);
143
146
147
+ /* *
148
+ * @brief Inserts meta object into the graveyard to preserve the lifetime.
149
+ *
150
+ * @param meta_obj - pointer to the meta object.
151
+ */
152
+ CLASS_LOADER_PUBLIC
153
+ void insertMetaObjectIntoGraveyard (std::shared_ptr<AbstractMetaObjectBase> meta_obj);
144
154
145
155
/* *
146
156
* @brief This function extracts a reference to the FactoryMap for appropriate base class out of
@@ -240,8 +250,8 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
240
250
}
241
251
242
252
// Create factory
243
- impl::AbstractMetaObject<Base> * new_factory =
244
- new impl::MetaObject<Derived, Base>(class_name, base_class_name);
253
+ auto new_factory =
254
+ std::make_shared< impl::MetaObject<Derived, Base> >(class_name, base_class_name);
245
255
new_factory->addOwningClassLoader (getCurrentlyActiveClassLoader ());
246
256
new_factory->setAssociatedLibraryPath (getCurrentlyLoadingLibraryName ());
247
257
@@ -260,13 +270,17 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
260
270
" and use either class_loader::ClassLoader/MultiLibraryClassLoader to open." ,
261
271
class_name.c_str ());
262
272
}
273
+
274
+ // We insert every factory into the graveyard to preserve the lifetime of all meta objects
275
+ // until the process exits.
276
+ insertMetaObjectIntoGraveyard (new_factory);
263
277
factoryMap[class_name] = new_factory;
264
278
getPluginBaseToFactoryMapMapMutex ().unlock ();
265
279
266
280
CONSOLE_BRIDGE_logDebug (
267
281
" class_loader.impl: "
268
282
" Registration of %s complete (Metaobject Address = %p)" ,
269
- class_name.c_str (), reinterpret_cast <void *>(new_factory));
283
+ class_name.c_str (), reinterpret_cast <void *>(new_factory. get () ));
270
284
}
271
285
272
286
/* *
@@ -278,22 +292,22 @@ void registerPlugin(const std::string & class_name, const std::string & base_cla
278
292
* @return A pointer to newly created plugin, note caller is responsible for object destruction
279
293
*/
280
294
template <typename Base>
281
- Base * createInstance (const std::string & derived_class_name, ClassLoader * loader)
295
+ Base * createInstance (const std::string & derived_class_name, std::shared_ptr< ClassLoader> loader)
282
296
{
283
297
AbstractMetaObject<Base> * factory = nullptr ;
284
298
285
299
getPluginBaseToFactoryMapMapMutex ().lock ();
286
300
FactoryMap & factoryMap = getFactoryMapForBaseClass<Base>();
287
301
if (factoryMap.find (derived_class_name) != factoryMap.end ()) {
288
- factory = dynamic_cast <impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]);
302
+ factory = dynamic_cast <impl::AbstractMetaObject<Base> *>(factoryMap[derived_class_name]. get () );
289
303
} else {
290
304
CONSOLE_BRIDGE_logError (
291
305
" class_loader.impl: No metaobject exists for class type %s." , derived_class_name.c_str ());
292
306
}
293
307
getPluginBaseToFactoryMapMapMutex ().unlock ();
294
308
295
309
Base * obj = nullptr ;
296
- if (factory != nullptr && factory->isOwnedBy (loader)) {
310
+ if (factory != nullptr && factory->isOwnedBy (loader. get () )) {
297
311
obj = factory->create ();
298
312
}
299
313
@@ -333,7 +347,7 @@ Base * createInstance(const std::string & derived_class_name, ClassLoader * load
333
347
* @return A vector of strings where each string is a plugin we can create
334
348
*/
335
349
template <typename Base>
336
- std::vector<std::string> getAvailableClasses (const ClassLoader * loader)
350
+ std::vector<std::string> getAvailableClasses (std::shared_ptr< const ClassLoader> loader)
337
351
{
338
352
std::lock_guard<std::recursive_mutex> lock (getPluginBaseToFactoryMapMapMutex ());
339
353
@@ -342,8 +356,8 @@ std::vector<std::string> getAvailableClasses(const ClassLoader * loader)
342
356
std::vector<std::string> classes_with_no_owner;
343
357
344
358
for (auto & it : factory_map) {
345
- AbstractMetaObjectBase * factory = it.second ;
346
- if (factory->isOwnedBy (loader)) {
359
+ auto factory = it.second ;
360
+ if (factory->isOwnedBy (loader. get () )) {
347
361
classes.push_back (it.first );
348
362
} else if (factory->isOwnedBy (nullptr )) {
349
363
classes_with_no_owner.push_back (it.first );
@@ -364,7 +378,8 @@ std::vector<std::string> getAvailableClasses(const ClassLoader * loader)
364
378
* within a ClassLoader's visible scope
365
379
*/
366
380
CLASS_LOADER_PUBLIC
367
- std::vector<std::string> getAllLibrariesUsedByClassLoader (const ClassLoader * loader);
381
+ std::vector<std::string> getAllLibrariesUsedByClassLoader (
382
+ std::shared_ptr<const ClassLoader> loader);
368
383
369
384
/* *
370
385
* @brief Indicates if passed library loaded within scope of a ClassLoader.
@@ -375,7 +390,7 @@ std::vector<std::string> getAllLibrariesUsedByClassLoader(const ClassLoader * lo
375
390
* @return true if the library is loaded within loader's scope, else false
376
391
*/
377
392
CLASS_LOADER_PUBLIC
378
- bool isLibraryLoaded (const std::string & library_path, const ClassLoader * loader);
393
+ bool isLibraryLoaded (const std::string & library_path, std::shared_ptr< const ClassLoader> loader);
379
394
380
395
/* *
381
396
* @brief Indicates if passed library has been loaded by ANY ClassLoader
0 commit comments