Skip to main content

Entity.ixx File

High-level facade for entity manipulation in the ECS. More...

Included Headers

#include <cassert> #include <type_traits> #include <typeindex> #include <helios.ecs.types.ComponentTypeId> #include <helios.ecs.ComponentOpsRegistry> #include <helios.ecs.components> #include <helios.ecs.EntityManager> #include <helios.ecs.types.EntityHandle>

Namespaces Index

namespacehelios
namespaceecs

Classes Index

classEntity<TEntityManager>

Lightweight facade for entity component manipulation. More...

Description

High-level facade for entity manipulation in the ECS.

File Listing

The file content with the documentation metadata removed is:

1
5module;
6
7#include <cassert>
8#include <type_traits>
9#include <typeindex>
10
11
12export module helios.ecs.Entity;
13
14
15import helios.ecs.types.EntityHandle;
16
17import helios.ecs.EntityManager;
18import helios.ecs.components;
19
20import helios.ecs.ComponentOpsRegistry;
21
22import helios.ecs.types.ComponentTypeId;
23
24using namespace helios::ecs::types;
25export namespace helios::ecs {
26
81 template<typename TEntityManager>
82 class Entity {
83
87 TEntityManager::Handle_type entityHandle_{0,0};
88
92 TEntityManager* entityManager_;
93
94
95 public:
96
97 using Handle_type = TEntityManager::Handle_type;
102
109 explicit Entity(
110 const Handle_type entityHandle,
111 TEntityManager* entityManager
112
113 ) noexcept : entityHandle_(entityHandle), entityManager_(entityManager) {
114 assert(entityManager_ != nullptr && "EntityManager must not be null.");
115 };
116
122 template<typename TFunc>
123 void forEachComponentTypeId(TFunc&& func) const {
124 entityManager_->forEachComponentTypeId(entityHandle_, std::forward<TFunc>(func));
125 }
126
132 [[nodiscard]] Handle_type handle() noexcept {
133 return entityHandle_;
134 }
135
141 [[nodiscard]] Handle_type handle() const noexcept {
142 return entityHandle_;
143 }
144
158 template<typename T, typename ...Args>
159 T& add(Args&& ...args) {
160
161 bool active = true;
162
163 if (entityManager_->template has<ActiveComponent_type>(entityHandle_)) {
164 active = true;
165 } else {
166 active = false;
167 }
168
169 auto* cmp = entityManager_->template emplace<T>(entityHandle_, std::forward<Args>(args)...);
170
171 auto typeId = ComponentTypeId_type::template id<T>();
172 const auto ops = ComponentOpsRegistry_type::ops(typeId);
173 void* raw = entityManager_->raw(entityHandle_, typeId);
174
175 if (active && ops.onActivate) {
176 ops.onActivate(raw);
177 } else if (!active && ops.onDeactivate) {
178 ops.onDeactivate(raw);
179 }
180
181 return *cmp;
182 }
183
194 template<typename T, typename ...Args>
195 T& getOrAdd(Args&& ...args) {
196 if (entityManager_->template has<T>(entityHandle_)) {
197 return *entityManager_->template get<T>(entityHandle_);
198 }
199 return add<T>(std::forward<Args>(args)...);
200 }
201
209 template<typename T>
210 bool remove() {
211 return entityManager_->template remove<T>(entityHandle_);
212 }
213
221 void* raw(const ComponentTypeId_type typeId) {
222 return entityManager_->raw(entityHandle_, typeId);
223 }
224
232 template<typename T>
233 T* get() {
234 return entityManager_->template get<T>(entityHandle_);
235 }
236
244 template<typename T>
245 const T* get() const {
246 return entityManager_->template get<T>(entityHandle_);
247 }
248
256 template<typename T>
257 bool has() const noexcept{
258 return entityManager_->template has<T>(entityHandle_);
259 }
260
268 bool has(ComponentTypeId_type typeId) const noexcept {
269 return entityManager_->has(entityHandle_, typeId);
270 }
271
278 entityManager_->enable(entityHandle_, typeId);
279 }
280
287 entityManager_->disable(entityHandle_, typeId);
288 }
289
311 void setActive(const bool active) {
312 bool isActive = entityManager_->template has<ActiveComponent_type>(entityHandle_);
313 bool isInActive = !isActive;
314
315 if (!isActive && active) {
316 auto* hc = entityManager_->template get<HierarchyComponent_type>(entityHandle_);
317 if (hc) {
318 hc->markDirty();
319 }
320
321 entityManager_->template emplaceOrGet<ActiveComponent_type>(entityHandle_);
322 }
323
324 if (!isInActive && !active) {
325 auto* hc = entityManager_->template get<HierarchyComponent_type>(entityHandle_);
326 if (hc) {
327 hc->markDirty();
328 }
329
330 entityManager_->template remove<ActiveComponent_type>(entityHandle_);
331 }
332
334 [&](const ComponentTypeId_type typeId) {
335 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
336
337 if (active && ops.onActivate) {
338 void* raw = entityManager_->raw(entityHandle_, typeId);
339 ops.onActivate(raw);
340 } else if (!active && ops.onDeactivate) {
341 void* raw = entityManager_->raw(entityHandle_, typeId);
342 ops.onDeactivate(raw);
343 }
344 }
345 );
346 }
347
353 [[nodiscard]] bool isActive() const {
354 return entityManager_->template has<ActiveComponent_type>(entityHandle_);
355 }
356
363 void onRelease() {
364
366 [&](const ComponentTypeId_type typeId) {
367 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
368
369 if (ops.onRelease) {
370 void* raw = entityManager_->raw(entityHandle_, typeId);
371 ops.onRelease(raw);
372 }
373 }
374 );
375
376
377 }
378
385 void onAcquire() {
387 [&](const ComponentTypeId_type typeId) {
388 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
389
390 if (ops.onAcquire) {
391 void* raw = entityManager_->raw(entityHandle_, typeId);
392 ops.onAcquire(raw);
393 }
394 }
395 );
396 }
397
398 };
399
400
401
402} // namespace helios

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.