Skip to main content

Entity.ixx File

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

Included Headers

#include <cassert> #include <utility> #include <helios.ecs.concepts.Traits> #include <helios.ecs.types.ComponentTypeId> #include <helios.ecs.commands> #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 <utility>
9
10
11export module helios.ecs.Entity;
12
13
14import helios.ecs.types.EntityHandle;
15
16import helios.ecs.EntityManager;
17import helios.ecs.components;
18import helios.ecs.commands;
19import helios.ecs.concepts.Traits;
20
21import helios.ecs.ComponentOpsRegistry;
22
23import helios.ecs.types.ComponentTypeId;
24
25using namespace helios::ecs::types;
26using namespace helios::ecs::commands;
28using namespace helios::ecs::components;
29export namespace helios::ecs {
30
85 template<typename TEntityManager>
86 class Entity {
87
91 TEntityManager::Handle_type entityHandle_{0,0};
92
96 TEntityManager* entityManager_;
97
103 template<typename T>
104 void markDirty() {
105 if (!entityManager_->template managesDirty<T>()) {
106 bool mg = entityManager_->template managesDirty<T>();
107 assert((entityManager_->template managesDirty<T>()) && "Cannot mark component as dirty, not tracked by EntityManager." );
108
109 }
110 getOrAdd<DirtyComponentSpec<T>>();
111 }
112
113 public:
114
115 using Handle_type = TEntityManager::Handle_type;
126
133 explicit Entity(
134 const Handle_type entityHandle,
135 TEntityManager* entityManager
136
137 ) noexcept : entityHandle_(entityHandle), entityManager_(entityManager) {
138 assert(entityManager_ != nullptr && "EntityManager must not be null.");
139 };
140
146 template<typename TFunc>
147 void forEachComponentTypeId(TFunc&& func) const {
148 entityManager_->forEachComponentTypeId(entityHandle_, std::forward<TFunc>(func));
149 }
150
156 [[nodiscard]] Handle_type handle() noexcept {
157 return entityHandle_;
158 }
159
165 [[nodiscard]] Handle_type handle() const noexcept {
166 return entityHandle_;
167 }
168
182 template<typename T, typename ...Args>
183 T& add(Args&& ...args) {
184
185 bool active = true;
186
187 if (entityManager_->template has<ActiveComponent_type>(entityHandle_)) {
188 active = true;
189 } else {
190 active = false;
191 }
192
193 auto* cmp = entityManager_->template emplace<T>(entityHandle_, std::forward<Args>(args)...);
194
195 auto typeId = ComponentTypeId_type::template id<T>();
196 const auto ops = ComponentOpsRegistry_type::ops(typeId);
197 void* raw = entityManager_->raw(entityHandle_, typeId);
198
199 if (active && ops.onActivate) {
200 ops.onActivate(raw);
201 } else if (!active && ops.onDeactivate) {
202 ops.onDeactivate(raw);
203 }
204
205 return *cmp;
206 }
207
220 template<typename TComponent, typename TBuffer, typename ...Args>
221 requires std::is_same_v<typename TEntityManager::Handle_type, typename TBuffer::Handle_type>
222 void deferAdd(TBuffer& buffer, Args&& ...args) {
223 buffer.template add<AddComponentCommand<TComponent>>(entityHandle_, std::forward<Args>(args)...);
224 }
225
236 template<typename TComponent, typename TBuffer>
237 requires std::is_same_v<typename TEntityManager::Handle_type, typename TBuffer::Handle_type>
238 void deferRemove(TBuffer& buffer) {
239 buffer.template add<RemoveComponentCommand<TComponent>>(entityHandle_);
240 }
241
251 template<typename TBuffer>
252 requires std::is_same_v<typename TEntityManager::Handle_type, typename TBuffer::Handle_type>
253 void deferSetActive(TBuffer& buffer) {
254 buffer.template add<ActivateEntityCommand<typename TEntityManager::Handle_type>>(entityHandle_);
255 }
256
266 template<typename TBuffer>
267 requires std::is_same_v<typename TEntityManager::Handle_type, typename TBuffer::Handle_type>
268 void deferSetInactive(TBuffer& buffer) {
269 buffer.template add<DeactivateEntityCommand<typename TEntityManager::Handle_type>>(entityHandle_);
270 }
271
282 template<typename T, typename ...Args>
283 T& getOrAdd(Args&& ...args) {
284 if (entityManager_->template has<T>(entityHandle_)) {
285 return *entityManager_->template get<T>(entityHandle_);
286 }
287 return add<T>(std::forward<Args>(args)...);
288 }
289
300 template<typename T, typename ...Args>
301 T& trackDirty(Args&& ...args) {
302 entityManager_->template trackDirty<T>();
303 markDirty<T>();
304 return getOrAdd<T>(std::forward<Args>(args)...);
305 }
306
315 template<typename TComponent, typename TValue>
316 requires IsComponentDirtyTrackable<TComponent, TValue>
317 && std::is_trivially_copyable_v<TValue>
318 && (sizeof(TValue) <= 2* sizeof(void*))
319 void setTrackedValue(TComponent* component, TValue value) {
320 assert(component != nullptr && "Unexpected nullptr for component.");
321 component->setValue(value);
322 markDirty<TComponent>();
323 }
324
333 template<typename TComponent, typename TValue>
334 requires IsComponentDirtyTrackable<TComponent, TValue>
335 && (!(std::is_trivially_copyable_v<TValue>
336 && (sizeof(TValue) <= 2* sizeof(void*))))
337 void setTrackedValue(TComponent* component, const TValue& value) {
338 assert(component != nullptr && "Unexpected nullptr for component.");
339 component->setValue(value);
340 markDirty<TComponent>();
341 }
342
343
351 template<typename T>
352 bool remove() {
353 return entityManager_->template remove<T>(entityHandle_);
354 }
355
363 void* raw(const ComponentTypeId_type typeId) {
364 return entityManager_->raw(entityHandle_, typeId);
365 }
366
374 template<typename T>
375 T* get() {
376 return entityManager_->template get<T>(entityHandle_);
377 }
378
386 template<typename T>
387 const T* get() const {
388 return entityManager_->template get<T>(entityHandle_);
389 }
390
398 template<typename T>
399 bool has() const noexcept{
400 return entityManager_->template has<T>(entityHandle_);
401 }
402
410 bool has(ComponentTypeId_type typeId) const noexcept {
411 return entityManager_->has(entityHandle_, typeId);
412 }
413
420 entityManager_->enable(entityHandle_, typeId);
421 }
422
429 entityManager_->disable(entityHandle_, typeId);
430 }
431
455 void setActive(const bool active) {
456 const bool isActive = entityManager_->template has<ActiveComponent_type>(entityHandle_);
457 const bool isInActive = !isActive;
458
459 if (!isActive && active) {
460 if (auto* hc = entityManager_->template get<HierarchyComponent_type>(entityHandle_)) {
461 hc->markDirty();
462 }
463 remove<InactiveComponent_type>();
464 trackDirty<ActiveComponent_type>();
465 }
466
467 if (!isInActive && !active) {
468 if (auto* hc = entityManager_->template get<HierarchyComponent_type>(entityHandle_)) {
469 hc->markDirty();
470 }
471 remove<ActiveComponent_type>();
472 trackDirty<InactiveComponent_type>();
473 }
474
476 [&](const ComponentTypeId_type typeId) {
477 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
478
479 if (active && ops.onActivate) {
480 void* raw = entityManager_->raw(entityHandle_, typeId);
481 ops.onActivate(raw);
482 } else if (!active && ops.onDeactivate) {
483 void* raw = entityManager_->raw(entityHandle_, typeId);
484 ops.onDeactivate(raw);
485 }
486 }
487 );
488 }
489
495 [[nodiscard]] bool isActive() const {
496 return entityManager_->template has<ActiveComponent_type>(entityHandle_);
497 }
498
505 void onRelease() {
506
508 [&](const ComponentTypeId_type typeId) {
509 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
510
511 if (ops.onRelease) {
512 void* raw = entityManager_->raw(entityHandle_, typeId);
513 ops.onRelease(raw);
514 }
515 }
516 );
517
518
519 }
520
527 void onAcquire() {
529 [&](const ComponentTypeId_type typeId) {
530 const auto& ops = ComponentOpsRegistry_type::ops(typeId);
531
532 if (ops.onAcquire) {
533 void* raw = entityManager_->raw(entityHandle_, typeId);
534 ops.onAcquire(raw);
535 }
536 }
537 );
538 }
539
540 };
541
542
543
544} // namespace helios

Generated via doxygen2docusaurus 2.0.0 by Doxygen 1.9.8.