RTC Toolkit 6.0.0
Loading...
Searching...
No Matches
factoryRegistry.ipp
Go to the documentation of this file.
1
11
12// Note this is a template implementation file and should not be included directly.
13// The typical header protection macro is not added to avoid it showing up in Doxygen API
14// documentation.
15#pragma once
16
17#include <algorithm>
18#include <cassert>
19
21
22template <class BaseIf>
24 // Check that all factories are unregistered at the time we are destroying this factory registry
25 // object. If this is not the case, then either a library is incorrectly implemented and not
26 // cleaning up properly, or the registry is being destroyed before all shared libraries got a
27 // chance to cleanup and deregister their factories. In either case, this is a bug, which this
28 // assertion failure exposes.
29#ifndef NDEBUG
30 std::scoped_lock lock(m_mutex);
31 assert(m_factories.size() == 0);
32#endif
33}
34
35template <class BaseIf>
37 // Note that we should not log in this function, since it will likely be called during process
38 // startup when no logging facilities are configured or appropriate.
39 std::scoped_lock lock(m_mutex);
40 auto position = std::find(m_factories.begin(), m_factories.end(), factory);
41 if (position == m_factories.end()) {
42 m_factories.push_back(factory);
43 }
44}
45
46template <class BaseIf>
47void FactoryRegistry<BaseIf>::Deregister(const FactoryIf* factory) noexcept {
48 // Note that similar logging restriction applies to this method as for Register, but during
49 // process termination.
50 std::scoped_lock lock(m_mutex);
51 auto position = std::find(m_factories.begin(), m_factories.end(), factory);
52 if (position != m_factories.end()) {
53 m_factories.erase(position);
54 }
55}
56
57template <class BaseIf>
60 std::scoped_lock lock(m_mutex);
61 auto factory = std::find_if(
62 m_factories.begin(), m_factories.end(), [&](auto& x) { return x->CanHandle(id); });
63 if (factory != m_factories.end()) {
64 return *factory;
65 } else {
66 return nullptr;
67 }
68}
69
70template <class BaseIf>
71std::shared_ptr<FactoryRegistry<BaseIf>> FactoryRegistry<BaseIf>::GetInstance() {
72 // Using a static local shared pointer to the global instance, since the C++ language guarantees
73 // will defer the initialisation of an empty registry object to the very first call of
74 // GetInstance. And this is done in a thread-safe manner. In addition, on the Linux platform at
75 // least, the linker will ensure there is only one copy of this object, even if the symbol was
76 // compiled into multiple translation units.
77 // The advantage of the static local variable versus a static class attribute is that this
78 // approach is more generic. Whenever a new type for T is used by the end user of this class,
79 // there is nothing special that needs to be done by the user. While using a static class
80 // attribute, e.g. s_registry, would require adding additional template specialisations to the
81 // common shared library of the following form:
82 //
83 // template<>
84 // std::shared_ptr<FactoryRegistry<MyInterface>> FactoryRegistry<MyInterface>::s_registry {};
85 //
86 // This would limit how flexible the FactoryRegistry class is.
87 //
88 // The reason to use a shared_ptr is to use reference counting to control the life-cycle of the
89 // registry object. The RegisterFactory must hold a shared pointer to the factory registry
90 // object for as long as the RegisterFactory exists, i.e. for as long as it has registered a
91 // factory with the registry. Using shared pointers should guarantee that the registry object
92 // will only be deleted once all relevant RegisterFactory classes are cleaned up.
93 // Experience has shown that if we do not use a shared_ptr and simply return a reference to a
94 // local object, the cleanup order becomes dependent on the link order of the shared libraries,
95 // i.e. undefined.
96 //
97 static std::shared_ptr<FactoryRegistry<BaseIf>> registry =
98 std::make_shared<FactoryRegistry<BaseIf>>();
99 return registry;
100}
101
102template <class BaseIf, class Factory>
107
108template <class BaseIf, class Factory>
112
113} // namespace rtctk::componentFramework
The base class for all factory objects that are registered in the FactoryRegistry.
Definition factoryRegistry.hpp:56
A simple registry of various factory objects.
Definition factoryRegistry.hpp:46
void Register(const FactoryIf *factory)
Register the factory if it was not already registered.
Definition factoryRegistry.ipp:36
void Deregister(const FactoryIf *factory) noexcept
Remove the factory from the registry if it was already registered.
Definition factoryRegistry.ipp:47
~FactoryRegistry()
Definition factoryRegistry.ipp:23
static std::shared_ptr< FactoryRegistry< BaseIf > > GetInstance()
Returns the registry singleton.
Definition factoryRegistry.ipp:71
const FactoryIf * FindCompatibleFactory(const AdapterIdType &id) const noexcept
Finds the first factory that can handle the given identifier.
Definition factoryRegistry.ipp:59
typename BaseIf::AdapterIdType AdapterIdType
Definition factoryRegistry.hpp:48
Factory m_factory
Definition factoryRegistry.hpp:203
RegisterFactory()
Definition factoryRegistry.ipp:103
std::shared_ptr< FactoryRegistry< BaseIf > > m_registry
Definition factoryRegistry.hpp:200
~RegisterFactory()
Definition factoryRegistry.ipp:109
Definition commandReplier.cpp:21