🛠️🐜 Antkeeper superbuild with dependencies included https://antkeeper.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
5.2 KiB

  1. #ifndef ENTT_ENTITY_ACTOR_HPP
  2. #define ENTT_ENTITY_ACTOR_HPP
  3. #include <cassert>
  4. #include <utility>
  5. #include <type_traits>
  6. #include "../config/config.h"
  7. #include "registry.hpp"
  8. #include "entity.hpp"
  9. #include "fwd.hpp"
  10. namespace entt {
  11. /**
  12. * @brief Dedicated to those who aren't confident with entity-component systems.
  13. *
  14. * Tiny wrapper around a registry, for all those users that aren't confident
  15. * with entity-component systems and prefer to iterate objects directly.
  16. *
  17. * @tparam Entity A valid entity type (see entt_traits for more details).
  18. */
  19. template<typename Entity>
  20. struct basic_actor {
  21. /*! @brief Type of registry used internally. */
  22. using registry_type = basic_registry<Entity>;
  23. /*! @brief Underlying entity identifier. */
  24. using entity_type = Entity;
  25. /**
  26. * @brief Constructs an actor by using the given registry.
  27. * @param ref An entity-component system properly initialized.
  28. */
  29. basic_actor(registry_type &ref)
  30. : reg{&ref}, entt{ref.create()}
  31. {}
  32. /*! @brief Default destructor. */
  33. virtual ~basic_actor() {
  34. reg->destroy(entt);
  35. }
  36. /**
  37. * @brief Move constructor.
  38. *
  39. * After actor move construction, instances that have been moved from are
  40. * placed in a valid but unspecified state. It's highly discouraged to
  41. * continue using them.
  42. *
  43. * @param other The instance to move from.
  44. */
  45. basic_actor(basic_actor &&other)
  46. : reg{other.reg}, entt{other.entt}
  47. {
  48. other.entt = null;
  49. }
  50. /**
  51. * @brief Move assignment operator.
  52. *
  53. * After actor move assignment, instances that have been moved from are
  54. * placed in a valid but unspecified state. It's highly discouraged to
  55. * continue using them.
  56. *
  57. * @param other The instance to move from.
  58. * @return This actor.
  59. */
  60. basic_actor & operator=(basic_actor &&other) {
  61. if(this != &other) {
  62. auto tmp{std::move(other)};
  63. std::swap(reg, tmp.reg);
  64. std::swap(entt, tmp.entt);
  65. }
  66. return *this;
  67. }
  68. /**
  69. * @brief Assigns the given component to an actor.
  70. *
  71. * A new instance of the given component is created and initialized with the
  72. * arguments provided (the component must have a proper constructor or be of
  73. * aggregate type). Then the component is assigned to the actor.<br/>
  74. * In case the actor already has a component of the given type, it's
  75. * replaced with the new one.
  76. *
  77. * @tparam Component Type of the component to create.
  78. * @tparam Args Types of arguments to use to construct the component.
  79. * @param args Parameters to use to initialize the component.
  80. * @return A reference to the newly created component.
  81. */
  82. template<typename Component, typename... Args>
  83. decltype(auto) assign(Args &&... args) {
  84. return reg->template assign_or_replace<Component>(entt, std::forward<Args>(args)...);
  85. }
  86. /**
  87. * @brief Removes the given component from an actor.
  88. * @tparam Component Type of the component to remove.
  89. */
  90. template<typename Component>
  91. void remove() {
  92. reg->template remove<Component>(entt);
  93. }
  94. /**
  95. * @brief Checks if an actor has the given component.
  96. * @tparam Component Type of the component for which to perform the check.
  97. * @return True if the actor has the component, false otherwise.
  98. */
  99. template<typename Component>
  100. bool has() const ENTT_NOEXCEPT {
  101. return reg->template has<Component>(entt);
  102. }
  103. /**
  104. * @brief Returns references to the given components for an actor.
  105. * @tparam Component Types of components to get.
  106. * @return References to the components owned by the actor.
  107. */
  108. template<typename... Component>
  109. decltype(auto) get() const ENTT_NOEXCEPT {
  110. return std::as_const(*reg).template get<Component...>(entt);
  111. }
  112. /*! @copydoc get */
  113. template<typename... Component>
  114. decltype(auto) get() ENTT_NOEXCEPT {
  115. return reg->template get<Component...>(entt);
  116. }
  117. /**
  118. * @brief Returns pointers to the given components for an actor.
  119. * @tparam Component Types of components to get.
  120. * @return Pointers to the components owned by the actor.
  121. */
  122. template<typename... Component>
  123. auto try_get() const ENTT_NOEXCEPT {
  124. return std::as_const(*reg).template try_get<Component...>(entt);
  125. }
  126. /*! @copydoc try_get */
  127. template<typename... Component>
  128. auto try_get() ENTT_NOEXCEPT {
  129. return reg->template try_get<Component...>(entt);
  130. }
  131. /**
  132. * @brief Returns a reference to the underlying registry.
  133. * @return A reference to the underlying registry.
  134. */
  135. inline const registry_type & backend() const ENTT_NOEXCEPT {
  136. return *reg;
  137. }
  138. /*! @copydoc backend */
  139. inline registry_type & backend() ENTT_NOEXCEPT {
  140. return const_cast<registry_type &>(std::as_const(*this).backend());
  141. }
  142. /**
  143. * @brief Returns the entity associated with an actor.
  144. * @return The entity associated with the actor.
  145. */
  146. inline entity_type entity() const ENTT_NOEXCEPT {
  147. return entt;
  148. }
  149. private:
  150. registry_type *reg;
  151. Entity entt;
  152. };
  153. }
  154. #endif // ENTT_ENTITY_ACTOR_HPP