CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
Entity.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Forward.hpp"
11
12#include "Action.hpp"
13#include "Component.hpp"
14#include "EntityID.hpp"
15#include "Event.hpp"
16
19
26
27#include <iosfwd>
28#include <type_traits>
29
30namespace CeresEngine {
31
32 template<CComponent... Components> class EntityObject;
33
42 template<typename T, typename Component> friend struct ComponentFieldMutator;
43
44 public:
46 EntityManager* entityManager = nullptr;
47
49 EntityID entityID = {};
50
51 public:
54 Entity() noexcept = default;
55
60 Entity(EntityManager& entityManager, EntityID id) noexcept;
61
63 CE_EXPLICIT(false) Entity(std::nullptr_t) noexcept; // NOLINT
64
66 Entity& operator=(std::nullptr_t) noexcept;
67
73 Entity(const Entity& other) noexcept = default;
74
79 Entity& operator=(const Entity& other) noexcept = default;
80
81 public: // Entity management
84 [[nodiscard]] CE_SCRIPT_EXPORT()
85 bool valid() const noexcept;
86
89 [[nodiscard]] CE_SCRIPT_EXPORT()
90 Entity copy() const;
91
93 // `block(entity)` right after copying.
97 template<typename Block> [[nodiscard]] Entity copy(Block&& block) const;
98
101 void destroy() const;
102
103 public: // Component management
108 [[nodiscard]] AbstractComponent& add(const ComponentType& type, const Box& initialValue = nullptr) const;
109
116 template<CComponent C, typename... Args> inline C& add(Args&&... args) const noexcept(std::is_nothrow_constructible_v<C, Args...>);
117
126 template<CComponent C, typename Block, typename... Args>
127 inline C& addWith(Block&& block, Args&&... args) const noexcept(std::is_nothrow_constructible_v<C, Args...>);
128
135 template<CComponent C, typename... Args> inline C& set(Args&&... args) const noexcept(std::is_nothrow_constructible_v<C, Args...>);
136
139 void remove(const ComponentType& type) const;
140
143 template<CComponent C> inline void remove() const noexcept(std::is_nothrow_destructible_v<C>);
144
149 [[nodiscard]] AbstractComponent& get(const ComponentType& type) const;
150
155 template<CComponent C> [[nodiscard]] inline C& get() const noexcept;
156
163 template<CComponent C0, CComponent C1, CComponent... Cs> [[nodiscard]] inline Tuple<C0&, C1&, Cs&...> get() const noexcept;
164
169 [[nodiscard]] AbstractComponent& getOr(const ComponentType& type) const;
170
175 template<CComponent C> [[nodiscard]] inline C& getOr() const noexcept(std::is_nothrow_constructible_v<C>);
176
183 template<CComponent C0, CComponent C1, CComponent... Cs> inline Tuple<C0&, C1&, Cs&...> getOr() const noexcept;
184
189 [[nodiscard]] AbstractComponent* getIf(const ComponentType& type) const;
190
195 template<CComponent C> [[nodiscard]] inline C* getIf() const noexcept;
196
203 template<CComponent C0, CComponent C1, CComponent... Cs> [[nodiscard]] inline Tuple<C0*, C1*, Cs*...> getIf() const noexcept;
204
205 // TODO Write docs.
206 [[nodiscard]] Vector<AbstractComponent*> getComponents() const;
207
211 [[nodiscard]] bool has(const ComponentType& type) const noexcept;
212
216 template<CComponent C, CComponent... Cs> [[nodiscard]] inline bool has() const noexcept;
217
221 void clear() const;
222
225 [[nodiscard]] CE_SCRIPT_EXPORT()
226 bool empty() const noexcept;
227
228 public: // EntityObject access
233 template<typename E> [[nodiscard]] inline bool is() const noexcept;
234
238 template<typename E> [[nodiscard]] inline E as() const;
239
243 template<typename... Cs> [[nodiscard]] inline EntityObject<Cs...> having() const;
244
250 template<typename E> [[nodiscard]] inline E being() const noexcept;
251
252 public: // Parent & Children entities
256 [[nodiscard]] CE_SCRIPT_EXPORT()
257 Entity getParent() const noexcept;
258
263 template<typename P> [[nodiscard]] P getParent() const noexcept;
264
269 void setParent(Entity parent) const;
270
273 [[nodiscard]] const Vector<Entity>& getChildren() const noexcept;
274
277 template<typename T> [[nodiscard]] Generator<T> getChildren() const noexcept;
278
281 void setChildren(const Vector<Entity>& children);
282
283 public: // Naming
286 [[nodiscard]] CE_SCRIPT_EXPORT()
287 StringView getName() const noexcept;
288
292 void setName(String name) const;
293
294 public: // Events
300 template<CEntityEvent E, typename... Args> inline void emit(Args&&... args) const;
301
305 template<CEntityEvent E> inline void emit(const E& event) const;
306
313 template<CEntityEvent E, typename Listener> inline WeakEventConnection on(Listener&& listener) const;
314
315 public: // Actions
322 template<CEntityAction A, typename... Args> [[nodiscard]] inline bool canAct(Args&&... args) const;
323
329 template<CEntityAction A, typename... Args> inline decltype(auto) act(Args&&... args) const;
330
331 public: // Entity component accessors
338 template<typename T, CComponent Component> [[nodiscard]] CE_FORCE_INLINE auto mutate(T Component::*ptr) const;
339
349 template<typename MutateFunc, typename T, CComponent Component> [[nodiscard]] CE_FORCE_INLINE decltype(auto) mutate(MutateFunc&& func, T Component::*ptr) const;
350
357 template<typename T, CComponent Component> [[nodiscard]] CE_FORCE_INLINE const T& read(const T Component::*ptr) const;
358
359 public:
361 [[nodiscard]] CE_SCRIPT_EXPORT(property = "getter", name = "entityID")
362 inline EntityID getEntityID() const noexcept;
363
365 [[nodiscard]] CE_SCRIPT_EXPORT(property = "getter", name = "entityManager")
366 inline EntityManager& getEntityManager() const noexcept;
367
368 public: // Operators
371 [[nodiscard]] inline explicit operator bool() const noexcept;
372
379 friend bool operator==(const Entity& a, const Entity& b) noexcept;
380
387 friend bool operator!=(const Entity& a, const Entity& b) noexcept;
388
395 friend bool operator==(const Entity& a, const EntityID& b) noexcept;
396
403 friend bool operator!=(const Entity& a, const EntityID& b) noexcept;
404
409 friend bool operator==(const Entity& a, std::nullptr_t b) noexcept;
410
415 friend bool operator!=(const Entity& a, std::nullptr_t b) noexcept;
416
421 friend std::ostream& operator<<(std::ostream& os, const Entity& entity);
422
423 public:
426 [[nodiscard]] Entity operator[](const EntityIndex childIndex) const { return getChildren()[childIndex]; }
427
430 [[nodiscard]] Entity operator[](const StringView childName) const {
431 for(Entity entity : getChildren()) {
432 if(entity.getName() == childName) {
433 return entity;
434 }
435 }
436 return nullptr;
437 }
438
439 template<typename E> friend E unsafeCastEntityObject(EntityManager& entityManager, EntityID entityID) noexcept;
440 };
441
451
455
457 struct EntityCreated final : public EntityEvent<EntityCreated> {};
458
460 struct EntityDestroyed final : public EntityEvent<EntityDestroyed> {};
461
475
489
493 template<CComponent C> struct ComponentAdded final : public EntityEvent<ComponentAdded<C>> {};
494
498 template<CComponent C> struct ComponentRemoved final : public EntityEvent<ComponentRemoved<C>> {};
499
506
538 template<CComponent... Components> class EntityObject : public Entity {
539 public:
542
546
548 static_assert(areComponents<Components...>, "All parameters in Components must be components.");
549
553 template<typename C> static inline constexpr bool includes = ComponentSet::template includes<C>;
554
560 static inline const _MaskObject mask;
561
562 // static inline const ComponentMask mask = ComponentSet::getComponentMask();
563
568 static inline EntityObject make(Entity entity);
569
570 public:
572 inline EntityObject() = default;
573
575 inline EntityObject(std::nullptr_t) noexcept; // NOLINT
576
581
586
591
596
605
610 inline EntityObject(const EntityObject& other) noexcept = default;
611
616 inline EntityObject& operator=(const EntityObject& other) noexcept = default;
617
618 private:
619 friend class EntityManager;
620
625
626 public:
630 decltype(auto) operator->() const { // NOLINT(readability-const-return-type)
631 struct AccessHelper final : public Components::Accessor... {
632 CE_FLATTEN_INLINE
633 explicit AccessHelper(EntityObject& entity) : Components::Accessor(entity)... {}
634
637 CE_FLATTEN_INLINE
638 decltype(auto) operator->() && { return this; }
639 };
640 return AccessHelper(const_cast<EntityObject&>(*this));
641 }
642
643 public:
646 [[nodiscard]] UInt64 getHash() const { return hash(get<Components>()...); }
647
648 [[nodiscard]] bool compareHash(UInt64& hash) const {
649 const UInt64 prevHash = hash;
650 hash = getHash();
651 return hash == prevHash;
652 }
653
654 public: // Operators
661// template<CComponent... ACs, CComponent... BCs> friend bool operator==(const EntityObject<ACs...>& a, const EntityObject<BCs...>& b);
662
669// template<CComponent... ACs, CComponent... BCs> friend bool operator!=(const EntityObject<ACs...>& a, const EntityObject<BCs...>& b);
670
677// template<CComponent... ACs> friend bool operator==(const EntityObject<ACs...>& a, const Entity& b);
678
685// template<CComponent... ACs> friend bool operator!=(const EntityObject<ACs...>& a, const Entity& b);
686
693// template<CComponent... ACs> friend bool operator==(const EntityObject<ACs...>& a, const EntityID& b);
694
701// template<CComponent... ACs> friend bool operator!=(const EntityObject<ACs...>& a, const EntityID& b);
702
707// template<CComponent... ACs> friend bool operator==(const EntityObject<ACs...>& a, std::nullptr_t b);
708//
709// /// Checks if a entity is not empty.
710// /// \param a The left hand side operator argument
711// /// \param b The right hand side operator argument
712// /// \return True if the entity is not empty
713// template<CComponent... ACs> friend bool operator!=(const EntityObject<ACs...>& a, std::nullptr_t b);
714
719 template<CComponent... ACs> friend std::ostream& operator<<(std::ostream& os, const EntityObject<ACs...>& entity);
720 };
721
722 template<typename E> struct EntityObjectTraits {
724 static constexpr bool isEntityObjectType = false;
725 };
726
727 template<typename... Components> struct EntityObjectTraits<EntityObject<Components...>> {
729 static constexpr bool isEntityObjectType = true;
730 };
731
734 template<typename E>
736 sizeof(typename E::Type) == sizeof(E);
737
740 template<typename... Es> constexpr bool areEntityObjects = (isEntityObject<Es> && ...);
741
747 template<typename O, typename T = void> using ifEntityObject = typename std::enable_if<isEntityObject<O>, T>::type;
748
749 template<typename T>
751
754 template<CEntityObject E> inline constexpr void checkEntityObject() { static_assert(isEntityObject<E>, "E must be an EntityObject type!"); }
755
756 template<CEntityObject... EOs> struct EntityObjectSet {
758 static_assert(areEntityObjects<EOs...>, "All parameters in EOs must be components.");
759
763 template<CEntityObject EO> static inline constexpr bool includes = (std::is_same_v<EO, EOs> || ...);
764
767 static inline const ComponentMask mask = (EOs::ComponentSet::getComponentMask() | ...);
768 };
769
770 template<> struct EntityObjectSet<> {
774 template<CEntityObject EO> static inline constexpr bool includes = false;
775
778 static inline const ComponentMask mask = ComponentMask();
779 };
780
782 template<typename E> static constexpr E entity_cast(const Entity& entity) { return entity.as<E>(); }
783
784#define CE_ENTITY_OBJECT_HASH(T) \
785 template<> struct std::hash<T> : public std::hash<CeresEngine::Entity> {}
786
787} // namespace CeresEngine
788
789#include "Component.inl"
790#include "Entity.inl"
791
792template<> struct std::hash<CeresEngine::Entity> {
793 size_t operator()(const CeresEngine::Entity& entity) const { return CeresEngine::hash(entity.entityManager, entity.getEntityID()); }
794};
795
796template<CeresEngine::CComponent... Components> struct std::hash<CeresEngine::EntityObject<Components...>> {
797 size_t operator()(const CeresEngine::EntityObject<Components...>& entity) const { return CeresEngine::hash(entity.entityManager, entity.getEntityID()); }
798};
#define CE_FORCE_INLINE
Definition Macros.hpp:367
#define CE_SCRIPT_EXPORT(...)
The CE_SCRIPT_EXPORT macro marks a class or method as exportable and available in scripting environme...
Definition Macros.hpp:247
#define CE_EXPLICIT(EXPR)
Definition Macros.hpp:413
A value type that can hold any alongside it's type information.
Definition Box.hpp:40
A type that describes and provides type-erased operations on a component.
Definition Component.hpp:456
The base entity class.
Definition Entity.hpp:41
friend E unsafeCastEntityObject(EntityManager &entityManager, EntityID entityID) noexcept
EntityID getEntityID() const noexcept
EntityID entityID
The entity ID.
Definition Entity.hpp:49
E as() const
Converts the entity handle type into a E entity object.
EntityManager * entityManager
The owning entity manager.
Definition Entity.hpp:46
Entity operator[](const StringView childName) const
Definition Entity.hpp:430
Definition EntityManager.hpp:49
A type-safe entity type.
Definition Entity.hpp:538
EntityObject(const EntityObject &other) noexcept=default
Creates a new entity by copying another.
EntityObject & operator=(const EntityObject &other) noexcept=default
Assing the contents of the entity by copying the contents of another.
EntityObject(EntityManager &entityManager, EntityID entityID)
Creates a new entity object attached to a entity manager.
EntityObject(std::nullptr_t) noexcept
Creates a new empty entity.
static constexpr bool includes
Checks if all Components are valid component types.
Definition Entity.hpp:553
friend std::ostream & operator<<(std::ostream &os, const EntityObject< ACs... > &entity)
Compares two entities for equality.
EntityObject()=default
Creates a new entity object.
bool compareHash(UInt64 &hash) const
Definition Entity.hpp:648
static EntityObject make(Entity entity)
Makes the entity an entity object by adding any missing component and casting it.
UInt64 getHash() const
Computes a hash that uniquely represents the entity object.
Definition Entity.hpp:646
static const _MaskObject mask
Definition Entity.hpp:560
A generator represents a coroutine type that produces a sequence of values of type T,...
Definition Generator.hpp:50
Tuple is a fixed-size collection of heterogeneous values.
Definition Tuple.hpp:15
Connection class.
Definition Event.hpp:44
Definition Component.hpp:117
Definition Action.hpp:69
Definition Event.hpp:73
Definition Entity.hpp:750
Definition Application.hpp:19
std::uint64_t UInt64
Definition DataTypes.hpp:26
constexpr void checkEntityObject()
A trait that checks if the type E is a valid entity object type.
Definition Entity.hpp:754
std::vector< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Vector
Vector is a sequence container that encapsulates dynamic size arrays.
Definition Vector.hpp:17
constexpr bool areEntityObjects
A trait that checks if the types Es are all entity objects.
Definition Entity.hpp:740
constexpr bool areComponents
A trait that checks if the types Cs are all components.
Definition Component.hpp:102
constexpr bool isEntityObject
A trait that checks if the type E is a entity object.
Definition Entity.hpp:735
std::bitset< 128 > ComponentMask
A bitset that represents a components mask (i.e. a set of components)
Definition Component.hpp:35
sfl::small_vector< T, N, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > SmallVector
SmallVector is a sequence container similar to Vector.
Definition SmallVector.hpp:31
typename std::enable_if< isEntityObject< O >, T >::type ifEntityObject
If the type E is a entity object (as defined by isEntityObject<S>), this type is aliased to T.
Definition Entity.hpp:747
auto parent(const Entity &parent)
Sets the entity parent.
Definition Helpers.hpp:52
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
UInt32 EntityIndex
Definition EntityID.hpp:22
Definition Span.hpp:668
A abstract class that provides a trait that allows checking for component implementations.
Definition Component.hpp:39
An event that gets dispatched when a new component of type C gets added to an entity.
Definition Entity.hpp:493
A structure that encodes a set of changes done to a component.
Definition Component.hpp:448
Definition Forward.hpp:28
Components serve as the base for data storage for an entity.
Definition Component.hpp:68
An event that gets dispatched when a component of type C gets removed from an entity.
Definition Entity.hpp:498
Definition Component.hpp:346
static ComponentMask getComponentMask() noexcept
A trait that contains the minimum component mask for that includes all components in the set.
Definition Component.hpp:357
A structure that encodes a change to an entity field.
Definition Entity.hpp:443
ComponentChangeSet change
A structure that describes a set of changes to an entity component field.
Definition Entity.hpp:449
const ComponentType * componentType
The component.
Definition Entity.hpp:445
Definition Entity.hpp:452
SmallVector< EntityChange, 3 > changes
Definition Entity.hpp:453
An event that gets dispatched when an entity has been created.
Definition Entity.hpp:457
An event that gets dispatched when an entity has been destroyed.
Definition Entity.hpp:460
An event that gets dispatched whenever the entity is marked as dirty.
Definition Entity.hpp:501
EntityDirty(const EntityChangeSet &changeSet)
Definition Entity.hpp:504
EntityChangeSet changeSet
Definition Entity.hpp:502
A template class that wraps a event.
Definition Event.hpp:43
Definition EntityID.hpp:25
An event that gets dispatched when an entity name is changed.
Definition Entity.hpp:477
StringView newName
The entity new name entity.
Definition Entity.hpp:479
StringView oldName
The entity old name entity.
Definition Entity.hpp:482
EntityNameChanged(const StringView newName, const StringView oldName)
Creates a new EntityNameChanged event.
Definition Entity.hpp:487
A trait that contains the minimum necessary component mask for an entity to be an entity object of th...
Definition Entity.hpp:557
Definition Entity.hpp:756
static constexpr bool includes
Checks if all EOs are valid entity object types.
Definition Entity.hpp:763
static const ComponentMask mask
A trait that contains the minimum component mask for that includes all components for entity objects ...
Definition Entity.hpp:767
Definition Entity.hpp:722
static constexpr bool isEntityObjectType
A trait that checks if the type E is a entity object.
Definition Entity.hpp:724
An event that gets dispatched when an entity parent is changed.
Definition Entity.hpp:463
EntityParentChanged(const Entity newParent, const Entity oldParent)
Creates a new EntityParentChanged event.
Definition Entity.hpp:473
Entity newParent
The entity new parent entity.
Definition Entity.hpp:465
Entity oldParent
The entity old parent entity.
Definition Entity.hpp:468