kodi
ComponentContainer.h
1 /*
2  * Copyright (C) 2022 Team Kodi
3  * This file is part of Kodi - https://kodi.tv
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  * See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "threads/CriticalSection.h"
12 
13 #include <cstddef>
14 #include <memory>
15 #include <mutex>
16 #include <stdexcept>
17 #include <typeindex>
18 #include <unordered_map>
19 #include <utility>
20 
25 template<class BaseType>
27 {
28 public:
30  template<class T>
31  std::shared_ptr<T> GetComponent()
32  {
33  return std::const_pointer_cast<T>(std::as_const(*this).template GetComponent<T>());
34  }
35 
37  template<class T>
38  std::shared_ptr<const T> GetComponent() const
39  {
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);
44 
45  throw std::logic_error("ComponentContainer: Attempt to obtain non-existent component");
46  }
47 
49  std::size_t size() const { return m_components.size(); }
50 
51 protected:
53  void RegisterComponent(const std::shared_ptr<BaseType>& component)
54  {
55  if (!component)
56  return;
57 
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;
62 
63  std::unique_lock<CCriticalSection> lock(m_critSection);
64  m_components.insert({std::type_index(typeid(componentRef)), component});
65  }
66 
68  void DeregisterComponent(const std::type_info& typeInfo)
69  {
70  std::unique_lock<CCriticalSection> lock(m_critSection);
71  m_components.erase(typeInfo);
72  }
73 
74 private:
75  mutable CCriticalSection m_critSection;
76  std::unordered_map<std::type_index, std::shared_ptr<BaseType>>
77  m_components;
78 };
std::size_t size() const
Returns number of registered components.
Definition: ComponentContainer.h:49
std::shared_ptr< T > GetComponent()
Obtain a component.
Definition: ComponentContainer.h:31
std::shared_ptr< const T > GetComponent() const
Obtain a component.
Definition: ComponentContainer.h:38
A generic container for components.
Definition: ServiceBroker.h:55
void DeregisterComponent(const std::type_info &typeInfo)
Deregister a component.
Definition: ComponentContainer.h:68
void RegisterComponent(const std::shared_ptr< BaseType > &component)
Register a new component instance.
Definition: ComponentContainer.h:53