Helios Engine 0.1.0
A modular ECS based data-oriented C++23 game engine
 
Loading...
Searching...
No Matches
component.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <helios/core_pch.hpp>
4
5#include <ctti/name.hpp>
6#include <ctti/type_id.hpp>
7
8#include <concepts>
9#include <cstddef>
10#include <string_view>
11#include <type_traits>
12
13namespace helios::ecs {
14
15/**
16 * @brief Helper to detect const components.
17 * @details Used to determine if a component type is const-qualified.
18 */
19template <typename T>
20struct IsConstComponent : std::false_type {};
21
22template <typename T>
23struct IsConstComponent<const T> : std::true_type {};
24
25template <typename T>
27
28/**
29 * @brief Concept for const-qualified component types.
30 * @details Used to constrain template parameters to const components.
31 */
32template <typename T>
34
35/**
36 * @brief Concept to check if a type can be used as a component.
37 */
38template <typename T>
39concept ComponentTrait = std::is_object_v<std::remove_cvref_t<T>> && std::is_destructible_v<std::remove_cvref_t<T>>;
40
41/**
42 * @brief Concept for components that provide a static name method.
43 * @details Named components can provide a human-readable identifier.
44 */
45template <typename T>
47 { T::GetName() } -> std::same_as<std::string_view>;
48};
49
50/**
51 * @brief Concept for tag components (empty).
52 */
53template <typename T>
54concept TagComponentTrait = ComponentTrait<T> && std::is_empty_v<T>;
55
56/**
57 * @brief Concept for trivially copyable components (POD-like).
58 */
59template <typename T>
61 ComponentTrait<T> && std::is_trivially_copyable_v<T> && std::is_trivially_destructible_v<T>;
62
63/**
64 * @brief Concept for tiny components (single cache line portion), where sizeof(T) <= 16.
65 */
66template <typename T>
67concept TinyComponentTrait = ComponentTrait<T> && (sizeof(T) <= 16);
68
69/**
70 * @brief Concept for small components that fit in cache line, where sizeof(T) <= 64.
71 */
72template <typename T>
73concept SmallComponentTrait = ComponentTrait<T> && (sizeof(T) <= 64);
74
75/**
76 * @brief Concept for medium components (multiple cache line portions), where 64 < sizeof(T) <= 256.
77 */
78template <typename T>
79concept MediumComponentTrait = ComponentTrait<T> && (sizeof(T) > 64 && sizeof(T) <= 256);
80
81/**
82 * @brief Concept for large components that don't fit in cache line, where sizeof(T) > 256.
83 */
84template <typename T>
85concept LargeComponentTrait = ComponentTrait<T> && (sizeof(T) > 256);
86
87/**
88 * @brief Component traits for optimization decisions.
89 */
90template <ComponentTrait T>
92 static constexpr bool kIsTrivial = TrivialComponentTrait<T>;
93 static constexpr bool kIsTiny = TinyComponentTrait<T>;
94 static constexpr bool kIsSmall = SmallComponentTrait<T>;
95 static constexpr bool kIsMedium = MediumComponentTrait<T>;
96 static constexpr bool kIsLarge = LargeComponentTrait<T>;
97 static constexpr size_t kSize = sizeof(T);
98 static constexpr size_t kAlignment = alignof(T);
99};
100
101/**
102 * @brief Type ID for components.
103 */
105
106/**
107 * @brief Type ID for components using CTTI.
108 * @tparam T Component type
109 * @return Unique type ID for the component
110 */
111template <ComponentTrait T>
113 return ctti::type_index_of<T>().hash();
114}
115
116template <ComponentTrait T>
117[[nodiscard]] constexpr std::string_view ComponentNameOf() noexcept {
118 if constexpr (ComponentWithNameTrait<T>) {
119 return T::GetName();
120 } else {
121 return ctti::name_of<T>();
122 }
123}
124
125/**
126 * @brief Component type info for runtime operations.
127 */
129public:
130 constexpr ComponentTypeInfo(const ComponentTypeInfo&) noexcept = default;
133
136
142
143 constexpr bool operator==(const ComponentTypeInfo& other) const noexcept { return type_id_ == other.type_id_; }
144 constexpr bool operator!=(const ComponentTypeInfo& other) const noexcept { return !(*this == other); }
145
146 constexpr bool operator<(const ComponentTypeInfo& other) const noexcept { return type_id_ < other.type_id_; }
147
148 [[nodiscard]] constexpr size_t TypeId() const noexcept { return type_id_; }
149 [[nodiscard]] constexpr size_t Size() const noexcept { return size_; }
150 [[nodiscard]] constexpr size_t Alignment() const noexcept { return alignment_; }
151 [[nodiscard]] constexpr bool IsTrivial() const noexcept { return is_trivial_; }
152
153private:
154 constexpr ComponentTypeInfo(ComponentTypeId type_id, size_t size, size_t alignment, bool is_trivial) noexcept
155 : type_id_(type_id), size_(size), alignment_(alignment), is_trivial_(is_trivial) {}
156
157 ComponentTypeId type_id_ = 0;
158 size_t size_ = 0;
159 size_t alignment_ = 0;
160 bool is_trivial_ = false;
161};
162
163} // namespace helios::ecs
164
165template <>
166struct std::hash<helios::ecs::ComponentTypeInfo> {
167 constexpr size_t operator()(const helios::ecs::ComponentTypeInfo& info) const noexcept { return info.TypeId(); }
168};
Component type info for runtime operations.
constexpr size_t Alignment() const noexcept
constexpr bool operator!=(const ComponentTypeInfo &other) const noexcept
constexpr ComponentTypeInfo(const ComponentTypeInfo &) noexcept=default
constexpr ComponentTypeInfo(ComponentTypeInfo &&) noexcept=default
constexpr bool operator<(const ComponentTypeInfo &other) const noexcept
constexpr bool IsTrivial() const noexcept
constexpr bool operator==(const ComponentTypeInfo &other) const noexcept
static constexpr ComponentTypeInfo Create() noexcept
constexpr size_t TypeId() const noexcept
constexpr size_t Size() const noexcept
Concept to check if a type can be used as a component.
Definition component.hpp:39
Concept for components that provide a static name method.
Definition component.hpp:46
Concept for const-qualified component types.
Definition component.hpp:33
Concept for large components that don't fit in cache line, where sizeof(T) > 256.
Definition component.hpp:85
Concept for medium components (multiple cache line portions), where 64 < sizeof(T) <= 256.
Definition component.hpp:79
Concept for small components that fit in cache line, where sizeof(T) <= 64.
Definition component.hpp:73
Concept for tag components (empty).
Definition component.hpp:54
Concept for tiny components (single cache line portion), where sizeof(T) <= 16.
Definition component.hpp:67
Concept for trivially copyable components (POD-like).
Definition component.hpp:60
constexpr bool IsConstComponent_v
Definition component.hpp:26
constexpr std::string_view ComponentNameOf() noexcept
size_t ComponentTypeId
Type ID for components.
constexpr ComponentTypeId ComponentTypeIdOf() noexcept
Type ID for components using CTTI.
BasicQuery< World, Allocator, Components... > Query
Type alias for query with mutable world access.
Definition query.hpp:2481
Component traits for optimization decisions.
Definition component.hpp:91
static constexpr size_t kSize
Definition component.hpp:97
static constexpr bool kIsTrivial
Definition component.hpp:92
static constexpr size_t kAlignment
Definition component.hpp:98
static constexpr bool kIsTiny
Definition component.hpp:93
static constexpr bool kIsSmall
Definition component.hpp:94
static constexpr bool kIsLarge
Definition component.hpp:96
static constexpr bool kIsMedium
Definition component.hpp:95
Helper to detect const components.
Definition component.hpp:20
constexpr size_t operator()(const helios::ecs::ComponentTypeInfo &info) const noexcept