GCC Code Coverage Report


./
Coverage:
low: ≥ 0%
medium: ≥ 75.0%
high: ≥ 90.0%
Lines:
0 of 48, 0 excluded
0.0%
Functions:
0 of 16, 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 C(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[C(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[C(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
73 Entity(const Entity&) = delete;
74 Entity(Entity&&) = delete;
75 void operator=(const Entity&) = delete;
76 void operator=(Entity&&) = delete;
77
78 const std::string name;
79
80 // todo(Gustav): split HshSt into 2, one with a primary hash and one without
81 World* world = nullptr;
82 std::vector<std::unique_ptr<Component>> components;
83 std::vector<std::unique_ptr<EntitySystem>> systems;
84 UpdateHandler<EntitySystem> updates;
85
86 void add_component(std::unique_ptr<Component> c);
87 void add_system(std::unique_ptr<EntitySystem> system);
88 bool has_tag(const Hsh& h) const;
89
90 SpatialComponent* get_root() const;
91 void set_root(SpatialComponent* c);
92
93 void imgui();
94
95 private:
96 SpatialComponent* root = nullptr;
97 std::set<Hsh> tags;
98 };
99
100 struct Component
101 {
102 Component() = default;
103 virtual ~Component() = default;
104
105 Component(const Component& rhs) = delete;
106 Component(Component&&) = delete;
107 void operator=(const Component& rhs) = delete;
108 void operator=(Component&&) = delete;
109
110 static const HshSt& type();
111 virtual const HshSt& get_type();
112
113 virtual const char* display() = 0;
114 virtual void imgui() = 0;
115 };
116 #define EU_DEC_COMPONENT_TYPE() static const HshSt& type(); const HshSt& get_type() override
117 #define EU_IMP_COMPONENT_TYPE(COMP, PAREN) \
118 const eu::HshSt& COMP::type() { const static auto s = PAREN::type().combine(Hsh{#COMP}); return s; }\
119 const eu::HshSt& COMP::get_type() { return type(); }
120
121 template<typename T>
122 concept ComponentLike = std::is_base_of_v<Component, T> && requires
123 {
124 { T::type() } -> std::same_as<const HshSt&>;
125 };
126
127 template<ComponentLike TComp> TComp* component_cast(Component* c)
128 {
129 if (c && c->get_type().is(TComp::type()))
130 {
131 return static_cast<TComp*>(c);
132 }
133 else
134 {
135 return nullptr;
136 }
137 }
138
139 struct SpatialComponent : Component
140 {
141 void set_transform(const m4& t);
142 const m4& get_transform() const;
143
144 EU_DEC_COMPONENT_TYPE();
145
146 void imgui() override;
147 private:
148 m4 transform = m4_identity;
149 // todo(gustav): add hierarchy
150 };
151
152 // essentially a named update
153 struct EntitySystem
154 {
155 EntitySystem() = default;
156 virtual ~EntitySystem() = default;
157
158 EntitySystem(const EntitySystem& rhs) = delete;
159 explicit EntitySystem(Component&&) = delete;
160 void operator=(const EntitySystem& rhs) = delete;
161 void operator=(EntitySystem&&) = delete;
162
163 virtual UpdateStageAndPrio get_stage() = 0;
164
165 virtual void add_component(Component* component) = 0;
166 virtual void on_root_changed(SpatialComponent* root) = 0;
167
168 virtual void update(float dt) = 0;
169
170 virtual const char* display() = 0;
171 virtual void imgui() = 0;
172 };
173
174 struct WorldSystem
175 {
176 WorldSystem() = default;
177 virtual ~WorldSystem() = default;
178
179 WorldSystem(const WorldSystem& rhs) = delete;
180 explicit WorldSystem(Component&&) = delete;
181 void operator=(const WorldSystem& rhs) = delete;
182 void operator=(WorldSystem&&) = delete;
183
184 virtual UpdateStageAndPrio get_stage() = 0;
185
186 virtual void add_component(Entity* entity, Component* component) = 0;
187 virtual void on_root_changed(Entity* entity, SpatialComponent* component) = 0;
188
189 virtual const char* display() = 0;
190 virtual void update(float dt) = 0;
191 virtual void imgui() = 0;
192 };
193
194 struct World
195 {
196 std::vector<std::unique_ptr<Entity>> entities;
197 std::vector<std::unique_ptr<WorldSystem>> systems;
198 UpdateHandler<WorldSystem> updates;
199
200 Entity* add_entity(const std::string& name, std::set<Hsh>&& tags);
201
202 void add_system(std::unique_ptr<WorldSystem> sys);
203 void on_add_component(Entity* entity, Component* component);
204 void on_root_changed(Entity* entity, SpatialComponent* component);
205
206 void update(UpdateStage stage, float dt);
207 void gui();
208 };
209
210 }
211
212
213 /**
214 * @}
215 */
216