13 template<std::derived_from<rtti_pure_base> base_component_t>
14 typename components<base_component_t>::class_data& components<base_component_t>::class_data::get_or_add_class_data(
17 if (
const auto it = derivedClasses.find(
id); it != derivedClasses.end())
18 return *it->second.get();
20 auto pClassData = std::make_unique<class_data>();
21 auto pRawClassData = pClassData.get();
22 derivedClasses[id] = std::move(pClassData);
23 return *pRawClassData;
26 template<std::derived_from<rtti_pure_base> base_component_t>
27 template<std::derived_from<base_component_t> component_t>
29 std::unique_ptr<component_t> pComponent,
36 auto pRawComponent = pComponent.get();
37 class_data& classData = get_or_add_class_data(
39 [ePriority, statusFlags, pRawComponent](class_data& classData)
42 status.ePriority = ePriority;
43 status.statusFlags = statusFlags;
44 classData.priorityCache.emplace(status, pRawComponent);
46 classData.components.push_back(std::move(pComponent));
50 template<std::derived_from<rtti_pure_base> base_component_t>
56 class_data& classData = get_or_add_class_data(
58 [pRawComponent](class_data& classData)
61 classData.priorityCache,
62 [pRawComponent](
const auto& pair)
64 return pair.second == pRawComponent;
68 const auto it = std::ranges::find_if(
70 [pRawComponent](
const pointer_type& pointer)
72 return pointer.get() == pRawComponent;
75 if (it == classData.components.end())
78 std::unique_ptr<base_component_t> pComponent = std::move(*it);
79 classData.components.erase(it);
83 template<std::derived_from<rtti_pure_base> base_component_t>
84 template<std::derived_from<base_component_t> component_t>
87 class_data& classData = get_or_add_class_data<component_t>();
88 const auto it = std::ranges::find_if(
89 classData.priorityCache,
90 [bIncludeDisabled](
const auto& pair)
92 return bIncludeDisabled || !pair.first.statusFlags.contains(component_status::disabled);
95 return it != classData.priorityCache.end() ?
static_cast<component_t*
>(it->second) :
nullptr;
98 template<std::derived_from<rtti_pure_base> base_component_t>
99 template<std::derived_from<base_component_t> component_t>
105 template<std::derived_from<rtti_pure_base> base_component_t>
106 template<std::derived_from<base_component_t> component_t>
111 const auto it = std::ranges::find_if(
112 m_RootClass.priorityCache,
113 [
id, bIncludeDisabled](
const auto& pair)
115 return (bIncludeDisabled || !pair.first.statusFlags.contains(component_status::disabled))
116 && pair.second->is_derived_from_id(id);
119 return it != m_RootClass.priorityCache.end() ? rtti_cast<component_t>(it->second) :
nullptr;
122 template<std::derived_from<rtti_pure_base> base_component_t>
123 template<std::derived_from<base_component_t> component_t>
129 template<std::derived_from<rtti_pure_base> base_component_t>
130 template<std::derived_from<base_component_t> component_t>
133 return *try_get<component_t>(bIncludeDisabled);
136 template<std::derived_from<rtti_pure_base> base_component_t>
137 template<std::derived_from<base_component_t> component_t>
143 template<std::derived_from<rtti_pure_base> base_component_t>
144 template<std::derived_from<base_component_t> component_t>
147 return *try_get<component_t>(
id, bIncludeDisabled);
150 template<std::derived_from<rtti_pure_base> base_component_t>
151 template<std::derived_from<base_component_t> component_t>
157 template<std::derived_from<rtti_pure_base> base_component_t>
158 template<std::derived_from<base_component_t> component_t>
161 class_data& classData = get_or_add_class_data<component_t>();
162 return classData.priorityCache
163 | std::views::filter(
166 return pair.second->template is_derived_from<component_t>()
167 && !pair.first.statusFlags.contains(component_status::disabled);
169 | std::views::transform(
170 [](
auto& pair) -> component_t&
172 return *
static_cast<component_t*
>(pair.second);
176 template<std::derived_from<rtti_pure_base> base_component_t>
177 template<std::derived_from<base_component_t> component_t>
180 const class_data& classData = get_or_add_class_data<component_t>();
181 return classData.priorityCache
182 | std::views::filter(
185 return pair.second->template is_derived_from<component_t>()
186 && !pair.first.statusFlags.contains(component_status::disabled);
188 | std::views::transform(
189 [](
const auto& pair) ->
const component_t&
191 return *
static_cast<const component_t*
>(pair.second);
195 template<std::derived_from<rtti_pure_base> base_component_t>
197 const base_component_t* pRawComponent)
const noexcept
199 std::optional<status> optComponentStatus = get_status(pRawComponent);
200 return optComponentStatus ? std::optional(optComponentStatus->statusFlags) : std::nullopt;
203 template<std::derived_from<rtti_pure_base> base_component_t>
205 const base_component_t* pRawComponent,
208 std::optional<status> optComponentStatus = get_status(pRawComponent);
209 if (!optComponentStatus)
212 optComponentStatus->statusFlags = newStatus;
213 return set_status(pRawComponent, *optComponentStatus);
216 template<std::derived_from<rtti_pure_base> base_component_t>
218 const base_component_t* pRawComponent,
221 std::optional<flags<component_status>> optComponentStatus = get_component_status(pRawComponent);
222 if (!optComponentStatus)
225 optComponentStatus->add(newStatuses);
226 return set_component_status(pRawComponent, *optComponentStatus);
229 template<std::derived_from<rtti_pure_base> base_component_t>
231 const base_component_t* pRawComponent,
234 std::optional<flags<component_status>> optComponentStatus = get_component_status(pRawComponent);
235 if (!optComponentStatus)
238 optComponentStatus->remove(statusesToRemove);
239 return set_component_status(pRawComponent, *optComponentStatus);
242 template<std::derived_from<rtti_pure_base> base_component_t>
244 const base_component_t* pRawComponent)
const noexcept
246 std::optional<status> optComponentStatus = get_status(pRawComponent);
247 return optComponentStatus ? std::optional(optComponentStatus->ePriority) : std::nullopt;
250 template<std::derived_from<rtti_pure_base> base_component_t>
252 const base_component_t* pRawComponent,
253 priority eNewComponentPriority) noexcept
255 std::optional<status> optComponentStatus = get_status(pRawComponent);
256 if (!optComponentStatus)
259 optComponentStatus->ePriority = eNewComponentPriority;
260 return set_status(pRawComponent, *optComponentStatus);
263 template<std::derived_from<rtti_pure_base> base_component_t>
266 return m_RootClass.priorityCache.empty();
269 template<std::derived_from<rtti_pure_base> base_component_t>
272 m_RootClass.derivedClasses.clear();
273 m_RootClass.components.clear();
274 m_RootClass.priorityCache.clear();
277 template<std::derived_from<rtti_pure_base> base_component_t>
279 const base_component_t* pRawComponent)
const noexcept
284 auto it = std::ranges::find_if(
285 m_RootClass.priorityCache,
286 [pRawComponent](
const auto& pair)
288 return pair.second == pRawComponent;
291 return it != m_RootClass.priorityCache.end() ? std::optional<status>(it->first) : std::nullopt;
295 template<std::derived_from<rtti_pure_base> base_component_t>
296 bool components<base_component_t>::set_status(
const base_component_t* pRawComponent, status status) noexcept
301 bool bChanged =
true;
302 get_or_add_class_data(
304 [pRawComponent, status, &bChanged](class_data& classData)
306 const auto it = std::ranges::find_if(
307 classData.priorityCache,
308 [pRawComponent](
const auto& pair)
310 return pair.second == pRawComponent;
313 if (it == classData.priorityCache.end())
319 if (it->first != status)
321 classData.priorityCache.emplace(status, it->second);
322 classData.priorityCache.erase(it);
Class id, unique for each class using qx rtti system.
Container for components system.
component_t & get(bool bIncludeDisabled=false) noexcept
Get a component of the given type with the highest priority (no existence checks are performed)
std::unique_ptr< base_component_t > remove(const base_component_t *pRawComponent) noexcept
Remove the component from the container.
bool add_component_status(const base_component_t *pRawComponent, flags< component_status > newStatuses) noexcept
Add new component status flags to the current ones.
bool set_component_priority(const base_component_t *pRawComponent, priority eNewComponentPriority) noexcept
Set component priority.
void clear() noexcept
Clear the container, e.g. remove all the components.
component_t * try_get(bool bIncludeDisabled=false) noexcept
Try to get a component of the given type with the highest priority.
bool set_component_status(const base_component_t *pRawComponent, flags< component_status > newStatus) noexcept
Set (override) a component status.
auto view() noexcept
Get a view which may be used in a ranged-based for loop and consists of components of a given type wi...
bool empty() const noexcept
Check if container doesn't have any components.
bool remove_component_status(const base_component_t *pRawComponent, flags< component_status > statusesToRemove) noexcept
Add component status flags from the current ones.
component_t * add(std::unique_ptr< component_t > pComponent, priority ePriority=priority::normal, flags< component_status > statusFlags=component_status::default_value) noexcept
Add a component.
std::optional< flags< component_status > > get_component_status(const base_component_t *pRawComponent) const noexcept
Get component status.
std::optional< priority > get_component_priority(const base_component_t *pRawComponent) const noexcept
Get component priority.
#define QX_CONST_CAST_THIS()
This macro is made for situations where you have a const method and you need exactly the same method ...
priority
User may use the predefined values or the custom ones, for ex. "normal - 1", this type is supposed to...