2 * Copyright (C) 2022 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
11 #include "threads/CriticalSection.h"
18 #include <unordered_map>
21 //! \brief A generic container for components.
22 //! \details A component has to be derived from the BaseType.
23 //! Only a single instance of each derived type can be registered.
24 //! Intended use is through inheritance.
25 template<class BaseType
>
26 class CComponentContainer
29 //! \brief Obtain a component.
31 std::shared_ptr
<T
> GetComponent()
33 return std::const_pointer_cast
<T
>(std::as_const(*this).template GetComponent
<T
>());
36 //! \brief Obtain a component.
38 std::shared_ptr
<const T
> GetComponent() const
40 std::unique_lock
<CCriticalSection
> lock(m_critSection
);
41 const auto it
= m_components
.find(std::type_index(typeid(T
)));
42 if (it
!= m_components
.end())
43 return std::static_pointer_cast
<const T
>((*it
).second
);
45 throw std::logic_error("ComponentContainer: Attempt to obtain non-existent component");
48 //! \brief Returns number of registered components.
49 std::size_t size() const { return m_components
.size(); }
52 //! \brief Register a new component instance.
53 void RegisterComponent(const std::shared_ptr
<BaseType
>& component
)
58 // Note: Extra var needed to avoid clang warning
59 // "Expression with side effects will be evaluated despite being used as an operand to 'typeid'"
60 // https://stackoverflow.com/questions/46494928/clang-warning-on-expression-side-effects
61 const auto& componentRef
= *component
;
63 std::unique_lock
<CCriticalSection
> lock(m_critSection
);
64 m_components
.insert({std::type_index(typeid(componentRef
)), component
});
67 //! \brief Deregister a component.
68 void DeregisterComponent(const std::type_info
& typeInfo
)
70 std::unique_lock
<CCriticalSection
> lock(m_critSection
);
71 m_components
.erase(typeInfo
);
75 mutable CCriticalSection m_critSection
; //!< Critical section for map updates
76 std::unordered_map
<std::type_index
, std::shared_ptr
<BaseType
>>
77 m_components
; //!< Map of components