GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 49, 0 excluded
0.0%
Functions:
0 of 17, 0 excluded
0.0%
Branches:
0 of 38, 0 excluded
0.0%

apps/runner/src/eu/runner/entity.h
Line Branch Exec Source
1 #pragma once
2 #include <algorithm>
3 #include <set>
4
5 namespace eu::runner
6 {
7 struct Entity;
8 struct Component;
9 struct SpatialComponent;
10 struct EntitySystem;
11 struct World;
12
13 enum class UpdateStage
14 {
15 start_frame,
16 before_physics,
17 physics,
18 after_physics,
19 end_frame
20 };
21 constexpr unsigned int update_stage_count = static_cast<unsigned int>(UpdateStage::end_frame) + 1;
22
23 struct UpdateStageAndPrio
24 {
25 UpdateStage stage;
26 int prio;
27 };
28
29 template<typename TSystem>
30 struct SystemWithPrio
31 {
32 TSystem* system;
33 int prio;
34 };
35
36 ✗ constexpr std::size_t cast(UpdateStage s)
37 {
38 ✗ return static_cast<std::size_t>(s);
39 }
40
41 template<typename TSystem>
42 struct UpdateHandler
43 {
44 std::array<std::vector<SystemWithPrio<TSystem>>, update_stage_count> stages;
45
46 ✗ void add(TSystem* system)
47 {
48 ✗ const UpdateStageAndPrio s = system->get_stage();
49
50 ✗ auto& systems = stages[cast(s.stage)];
51
52 ✗ systems.emplace_back(system, s.prio);
53 ✗ std::sort(systems.begin(), systems.end(), [](const auto& lhs, const auto& rhs)
54 {
55 ✗ return lhs.prio < rhs.prio;
56 });
57 ✗ }
58
59 ✗ void update(UpdateStage stage, float dt)
60 {
61 ✗ auto& systems = stages[cast(stage)];
62 ✗ for (auto& sys : systems)
63 {
64 ✗ sys.system->update(dt);
65 }
66 ✗ }
67 };
68
69 struct Entity
70 {
71 Entity(const std::string& n, std::set<Hsh>&& t);
72 ✗ ~Entity() = default;
73
74 Entity(const Entity&) = delete;
75 Entity(Entity&&) = delete;
76 void operator=(const Entity&) = delete;
77 void operator=(Entity&&) = delete;
78
79 const std::string name;
80
81 // todo(Gustav): split HshSt into 2, one with a primary hash and one without
82 World* world = nullptr;
83 std::vector<std::unique_ptr<Component>> components;
84 std::vector<std::unique_ptr<EntitySystem>> systems;
85 UpdateHandler<EntitySystem> updates;
86
87 void add_component(std::unique_ptr<Component> c);
88 void add_system(std::unique_ptr<EntitySystem> system);
89 [[nodiscard]] bool has_tag(const Hsh& h) const;
90
91 [[nodiscard]] SpatialComponent* get_root() const;
92 void set_root(SpatialComponent* c);
93
94 void imgui();
95
96 private:
97 SpatialComponent* root = nullptr;
98 std::set<Hsh> tags;
99 };
100
101 struct Component
102 {
103 ✗ Component() = default;
104 ✗ virtual ~Component() = default;
105
106 Component(const Component& rhs) = delete;
107 Component(Component&&) = delete;
108 void operator=(const Component& rhs) = delete;
109 void operator=(Component&&) = delete;
110
111 static const HshSt& type();
112 virtual const HshSt& get_type();
113
114 virtual const char* display() = 0;
115 virtual void imgui() = 0;
116 };
117 #define EU_DEC_COMPONENT_TYPE() static const HshSt& type(); const HshSt& get_type() override
118 #define EU_IMP_COMPONENT_TYPE(COMP, PAREN) \
119 const eu::HshSt& COMP::type() { const static auto s = PAREN::type().combine(Hsh{#COMP}); return s; }\
120 const eu::HshSt& COMP::get_type() { return type(); }
121
122 template<typename T>
123 concept ComponentLike = std::is_base_of_v<Component, T> && requires
124 {
125 { T::type() } -> std::same_as<const HshSt&>;
126 };
127
128 ✗ template<ComponentLike TComp> TComp* component_cast(Component* c)
129 {
130 ✗ if (c && c->get_type().is(TComp::type()))
131 {
132 ✗ return static_cast<TComp*>(c);
133 }
134 else
135 {
136 ✗ return nullptr;
137 }
138 }
139
140 struct SpatialComponent : Component
141 {
142 void set_transform(const m4& t);
143 [[nodiscard]] const m4& get_transform() const;
144
145 EU_DEC_COMPONENT_TYPE();
146
147 void imgui() override;
148 private:
149 m4 transform = m4_identity;
150 // todo(gustav): add hierarchy
151 };
152
153 // essentially a named update
154 struct EntitySystem
155 {
156 ✗ EntitySystem() = default;
157 ✗ virtual ~EntitySystem() = default;
158
159 EntitySystem(const EntitySystem& rhs) = delete;
160 EntitySystem(EntitySystem&&) = delete;
161 void operator=(const EntitySystem& rhs) = delete;
162 void operator=(EntitySystem&&) = delete;
163
164 virtual UpdateStageAndPrio get_stage() = 0;
165
166 virtual void add_component(Component* component) = 0;
167 virtual void on_root_changed(SpatialComponent* root) = 0;
168
169 virtual void update(float dt) = 0;
170
171 virtual const char* display() = 0;
172 virtual void imgui() = 0;
173 };
174
175 struct WorldSystem
176 {
177 ✗ WorldSystem() = default;
178 ✗ virtual ~WorldSystem() = default;
179
180 WorldSystem(const WorldSystem& rhs) = delete;
181 WorldSystem(WorldSystem&&) = delete;
182 void operator=(const WorldSystem& rhs) = delete;
183 void operator=(WorldSystem&&) = delete;
184
185 virtual UpdateStageAndPrio get_stage() = 0;
186
187 virtual void add_component(Entity* entity, Component* component) = 0;
188 virtual void on_root_changed(Entity* entity, SpatialComponent* component) = 0;
189
190 virtual const char* display() = 0;
191 virtual void update(float dt) = 0;
192 virtual void imgui() = 0;
193 };
194
195 struct World
196 {
197 std::vector<std::unique_ptr<Entity>> entities;
198 std::vector<std::unique_ptr<WorldSystem>> systems;
199 UpdateHandler<WorldSystem> updates;
200
201 Entity* add_entity(const std::string& name, std::set<Hsh>&& tags);
202
203 void add_system(std::unique_ptr<WorldSystem> sys);
204 void on_add_component(Entity* entity, Component* component);
205 void on_root_changed(Entity* entity, SpatialComponent* component);
206
207 void update(UpdateStage stage, float dt);
208 void gui();
209 };
210
211 }
212
213
214 /**
215 * @}
216 */
217