20 #include <unordered_map>
25 enum class component_status
44 template<std::derived_from<rtti_pure_base> base_component_t>
48 using pointer_type = std::unique_ptr<base_component_t>;
55 using time_ordered_priority_key::operator<;
56 constexpr
bool operator==(
const status&)
const noexcept =
default;
61 std::unordered_map<class_id, std::unique_ptr<class_data>> derivedClasses;
63 std::multimap<status, base_component_t*> priorityCache;
65 [[nodiscard]] class_data& get_or_add_class_data(
class_id id) noexcept;
68 static constexpr
auto stub_callback = [](
auto&&...)
81 template<std::derived_from<base_component_t> component_t>
82 [[maybe_unused]] component_t*
add(
83 std::unique_ptr<component_t> pComponent,
84 priority ePriority = priority::normal,
92 [[maybe_unused]] std::unique_ptr<base_component_t>
remove(
const base_component_t* pRawComponent) noexcept;
100 template<std::derived_from<base_component_t> component_t>
101 [[nodiscard]] component_t*
try_get(
bool bIncludeDisabled =
false) noexcept;
109 template<std::derived_from<base_component_t> component_t>
110 [[nodiscard]]
const component_t*
try_get(
bool bIncludeDisabled =
false)
const noexcept;
119 template<std::derived_from<base_component_t> component_t = base_component_t>
120 [[nodiscard]] component_t*
try_get(
class_id id,
bool bIncludeDisabled =
false) noexcept;
129 template<std::derived_from<base_component_t> component_t = base_component_t>
130 [[nodiscard]]
const component_t*
try_get(
class_id id,
bool bIncludeDisabled =
false)
const noexcept;
138 template<std::derived_from<base_component_t> component_t>
139 [[nodiscard]] component_t&
get(
bool bIncludeDisabled =
false) noexcept;
147 template<std::derived_from<base_component_t> component_t>
148 [[nodiscard]]
const component_t&
get(
bool bIncludeDisabled =
false)
const noexcept;
157 template<std::derived_from<base_component_t> component_t = base_component_t>
158 [[nodiscard]] base_component_t&
get(
class_id id,
bool bIncludeDisabled =
false) noexcept;
167 template<std::derived_from<base_component_t> component_t = base_component_t>
168 [[nodiscard]]
const base_component_t&
get(
class_id id,
bool bIncludeDisabled =
false)
const noexcept;
175 template<std::derived_from<base_component_t> component_t = base_component_t>
176 [[nodiscard]]
auto view() noexcept;
183 template<std::derived_from<base_component_t> component_t = base_component_t>
184 [[nodiscard]]
auto view()
const noexcept;
192 const base_component_t* pRawComponent)
const noexcept;
201 const base_component_t* pRawComponent,
211 const base_component_t* pRawComponent,
221 const base_component_t* pRawComponent,
229 [[nodiscard]] std::optional<priority>
get_component_priority(
const base_component_t* pRawComponent)
const noexcept;
238 const base_component_t* pRawComponent,
239 priority eNewComponentPriority) noexcept;
245 [[nodiscard]]
bool empty()
const noexcept;
250 void clear() noexcept;
258 [[nodiscard]] std::optional<status> get_status(
const base_component_t* pRawComponent)
const noexcept;
267 [[maybe_unused]]
bool set_status(
const base_component_t* pRawComponent, status status) noexcept;
277 std::derived_from<base_component_t> component_t,
278 callable_c<void, class_data&> callable_t = decltype(stub_callback)>
279 class_data& get_or_add_class_data(callable_t iterateClassDataFunction = stub_callback) noexcept
287 using t1 =
typename component_t::inheritance_tuple_type;
288 using t2 =
typename base_component_t::inheritance_tuple_type;
289 using t3 = tuple::remove_t<t1, t2>;
291 class_data* pClassData = &m_RootClass;
292 iterateClassDataFunction(*pClassData);
295 [&pClassData, &iterateClassDataFunction]<
class T,
size_t I>()
297 pClassData = &pClassData->get_or_add_class_data(T::get_class_id_static());
298 iterateClassDataFunction(*pClassData);
312 std::derived_from<base_component_t> component_t,
313 callable_c<void, class_data&> callable_t = decltype(stub_callback)>
314 const class_data& get_or_add_class_data(callable_t iterateClassDataFunction = stub_callback)
const noexcept
316 return QX_CONST_CAST_THIS()->template get_or_add_class_data<component_t>(std::move(iterateClassDataFunction));
326 template<callable_c<
void,
class_data&> callable_t = decltype(stub_callback)>
327 class_data& get_or_add_class_data(
328 const base_component_t* pRawComponent,
329 callable_t iterateClassDataFunction = stub_callback) noexcept
331 class_data* pClassData = &m_RootClass;
332 iterateClassDataFunction(*pClassData);
334 std::span<const class_id> allIds = pRawComponent->get_inheritance_sequence();
335 std::span<const class_id> baseClassIds(
336 std::ranges::find(allIds, base_component_t::get_class_id_static()),
339 for (
auto it = baseClassIds.begin() + 1; it != baseClassIds.end(); ++it)
341 pClassData = &pClassData->get_or_add_class_data(*it);
342 iterateClassDataFunction(*pClassData);
355 template<callable_c<
void,
class_data&> callable_t = decltype(stub_callback)>
356 const class_data& get_or_add_class_data(
357 const base_component_t* pRawComponent,
358 callable_t iterateClassDataFunction = stub_callback)
const noexcept
360 return QX_CONST_CAST_THIS()->get_or_add_class_data(pRawComponent, std::move(iterateClassDataFunction));
364 class_data m_RootClass;
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...
RTTI system based on polymorphism.
A structure that can be used as a key in ordered containers so that items are ordered in descending o...