🛠️🐜 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.

339 lines
11 KiB

  1. #ifndef ENTT_ENTITY_ENTITY_HPP
  2. #define ENTT_ENTITY_ENTITY_HPP
  3. #include <cstddef>
  4. #include <cstdint>
  5. #include <type_traits>
  6. #include "../config/config.h"
  7. #include "fwd.hpp"
  8. namespace entt {
  9. /**
  10. * @cond TURN_OFF_DOXYGEN
  11. * Internal details not to be documented.
  12. */
  13. namespace internal {
  14. template<typename, typename = void>
  15. struct entt_traits;
  16. template<typename Type>
  17. struct entt_traits<Type, std::enable_if_t<std::is_enum_v<Type>>>
  18. : entt_traits<std::underlying_type_t<Type>> {};
  19. template<typename Type>
  20. struct entt_traits<Type, std::enable_if_t<std::is_class_v<Type>>>
  21. : entt_traits<typename Type::entity_type> {};
  22. template<>
  23. struct entt_traits<std::uint32_t> {
  24. using entity_type = std::uint32_t;
  25. using version_type = std::uint16_t;
  26. static constexpr entity_type entity_mask = 0xFFFFF;
  27. static constexpr entity_type version_mask = 0xFFF;
  28. static constexpr std::size_t entity_shift = 20u;
  29. };
  30. template<>
  31. struct entt_traits<std::uint64_t> {
  32. using entity_type = std::uint64_t;
  33. using version_type = std::uint32_t;
  34. static constexpr entity_type entity_mask = 0xFFFFFFFF;
  35. static constexpr entity_type version_mask = 0xFFFFFFFF;
  36. static constexpr std::size_t entity_shift = 32u;
  37. };
  38. } // namespace internal
  39. /**
  40. * Internal details not to be documented.
  41. * @endcond
  42. */
  43. /**
  44. * @brief Entity traits.
  45. * @tparam Type Type of identifier.
  46. */
  47. template<typename Type>
  48. class entt_traits: internal::entt_traits<Type> {
  49. using base_type = internal::entt_traits<Type>;
  50. public:
  51. /*! @brief Value type. */
  52. using value_type = Type;
  53. /*! @brief Underlying entity type. */
  54. using entity_type = typename base_type::entity_type;
  55. /*! @brief Underlying version type. */
  56. using version_type = typename base_type::version_type;
  57. /*! @brief Reserved identifier. */
  58. static constexpr entity_type reserved = base_type::entity_mask | (base_type::version_mask << base_type::entity_shift);
  59. /*! @brief Page size, default is `ENTT_SPARSE_PAGE`. */
  60. static constexpr auto page_size = ENTT_SPARSE_PAGE;
  61. /**
  62. * @brief Converts an entity to its underlying type.
  63. * @param value The value to convert.
  64. * @return The integral representation of the given value.
  65. */
  66. [[nodiscard]] static constexpr entity_type to_integral(const value_type value) ENTT_NOEXCEPT {
  67. return static_cast<entity_type>(value);
  68. }
  69. /**
  70. * @brief Returns the entity part once converted to the underlying type.
  71. * @param value The value to convert.
  72. * @return The integral representation of the entity part.
  73. */
  74. [[nodiscard]] static constexpr entity_type to_entity(const value_type value) ENTT_NOEXCEPT {
  75. return (to_integral(value) & base_type::entity_mask);
  76. }
  77. /**
  78. * @brief Returns the version part once converted to the underlying type.
  79. * @param value The value to convert.
  80. * @return The integral representation of the version part.
  81. */
  82. [[nodiscard]] static constexpr version_type to_version(const value_type value) ENTT_NOEXCEPT {
  83. return (to_integral(value) >> base_type::entity_shift);
  84. }
  85. /**
  86. * @brief Constructs an identifier from its parts.
  87. *
  88. * If the version part is not provided, a tombstone is returned.<br/>
  89. * If the entity part is not provided, a null identifier is returned.
  90. *
  91. * @param entity The entity part of the identifier.
  92. * @param version The version part of the identifier.
  93. * @return A properly constructed identifier.
  94. */
  95. [[nodiscard]] static constexpr value_type construct(const entity_type entity, const version_type version) ENTT_NOEXCEPT {
  96. return value_type{(entity & base_type::entity_mask) | (static_cast<entity_type>(version) << base_type::entity_shift)};
  97. }
  98. /**
  99. * @brief Combines two identifiers in a single one.
  100. *
  101. * The returned identifier is a copy of the first element except for its
  102. * version, which is taken from the second element.
  103. *
  104. * @param lhs The identifier from which to take the entity part.
  105. * @param rhs The identifier from which to take the version part.
  106. * @return A properly constructed identifier.
  107. */
  108. [[nodiscard]] static constexpr value_type combine(const entity_type lhs, const entity_type rhs) ENTT_NOEXCEPT {
  109. constexpr auto mask = (base_type::version_mask << base_type::entity_shift);
  110. return value_type{(lhs & base_type::entity_mask) | (rhs & mask)};
  111. }
  112. };
  113. /**
  114. * @copydoc entt_traits<Entity>::to_integral
  115. * @tparam Entity The value type.
  116. */
  117. template<typename Entity>
  118. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_integral(const Entity value) ENTT_NOEXCEPT {
  119. return entt_traits<Entity>::to_integral(value);
  120. }
  121. /**
  122. * @copydoc entt_traits<Entity>::to_entity
  123. * @tparam Entity The value type.
  124. */
  125. template<typename Entity>
  126. [[nodiscard]] constexpr typename entt_traits<Entity>::entity_type to_entity(const Entity value) ENTT_NOEXCEPT {
  127. return entt_traits<Entity>::to_entity(value);
  128. }
  129. /**
  130. * @copydoc entt_traits<Entity>::to_version
  131. * @tparam Entity The value type.
  132. */
  133. template<typename Entity>
  134. [[nodiscard]] constexpr typename entt_traits<Entity>::version_type to_version(const Entity value) ENTT_NOEXCEPT {
  135. return entt_traits<Entity>::to_version(value);
  136. }
  137. /*! @brief Null object for all identifiers. */
  138. struct null_t {
  139. /**
  140. * @brief Converts the null object to identifiers of any type.
  141. * @tparam Entity Type of identifier.
  142. * @return The null representation for the given type.
  143. */
  144. template<typename Entity>
  145. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  146. using entity_traits = entt_traits<Entity>;
  147. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  148. }
  149. /**
  150. * @brief Compares two null objects.
  151. * @param other A null object.
  152. * @return True in all cases.
  153. */
  154. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  155. return true;
  156. }
  157. /**
  158. * @brief Compares two null objects.
  159. * @param other A null object.
  160. * @return False in all cases.
  161. */
  162. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const null_t other) const ENTT_NOEXCEPT {
  163. return false;
  164. }
  165. /**
  166. * @brief Compares a null object and an identifier of any type.
  167. * @tparam Entity Type of identifier.
  168. * @param entity Identifier with which to compare.
  169. * @return False if the two elements differ, true otherwise.
  170. */
  171. template<typename Entity>
  172. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  173. using entity_traits = entt_traits<Entity>;
  174. return entity_traits::to_entity(entity) == entity_traits::to_entity(*this);
  175. }
  176. /**
  177. * @brief Compares a null object and an identifier of any type.
  178. * @tparam Entity Type of identifier.
  179. * @param entity Identifier with which to compare.
  180. * @return True if the two elements differ, false otherwise.
  181. */
  182. template<typename Entity>
  183. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  184. return !(entity == *this);
  185. }
  186. };
  187. /**
  188. * @brief Compares a null object and an identifier of any type.
  189. * @tparam Entity Type of identifier.
  190. * @param entity Identifier with which to compare.
  191. * @param other A null object yet to be converted.
  192. * @return False if the two elements differ, true otherwise.
  193. */
  194. template<typename Entity>
  195. [[nodiscard]] constexpr bool operator==(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  196. return other.operator==(entity);
  197. }
  198. /**
  199. * @brief Compares a null object and an identifier of any type.
  200. * @tparam Entity Type of identifier.
  201. * @param entity Identifier with which to compare.
  202. * @param other A null object yet to be converted.
  203. * @return True if the two elements differ, false otherwise.
  204. */
  205. template<typename Entity>
  206. [[nodiscard]] constexpr bool operator!=(const Entity entity, const null_t other) ENTT_NOEXCEPT {
  207. return !(other == entity);
  208. }
  209. /*! @brief Tombstone object for all identifiers. */
  210. struct tombstone_t {
  211. /**
  212. * @brief Converts the tombstone object to identifiers of any type.
  213. * @tparam Entity Type of identifier.
  214. * @return The tombstone representation for the given type.
  215. */
  216. template<typename Entity>
  217. [[nodiscard]] constexpr operator Entity() const ENTT_NOEXCEPT {
  218. using entity_traits = entt_traits<Entity>;
  219. return entity_traits::combine(entity_traits::reserved, entity_traits::reserved);
  220. }
  221. /**
  222. * @brief Compares two tombstone objects.
  223. * @param other A tombstone object.
  224. * @return True in all cases.
  225. */
  226. [[nodiscard]] constexpr bool operator==([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  227. return true;
  228. }
  229. /**
  230. * @brief Compares two tombstone objects.
  231. * @param other A tombstone object.
  232. * @return False in all cases.
  233. */
  234. [[nodiscard]] constexpr bool operator!=([[maybe_unused]] const tombstone_t other) const ENTT_NOEXCEPT {
  235. return false;
  236. }
  237. /**
  238. * @brief Compares a tombstone object and an identifier of any type.
  239. * @tparam Entity Type of identifier.
  240. * @param entity Identifier with which to compare.
  241. * @return False if the two elements differ, true otherwise.
  242. */
  243. template<typename Entity>
  244. [[nodiscard]] constexpr bool operator==(const Entity entity) const ENTT_NOEXCEPT {
  245. using entity_traits = entt_traits<Entity>;
  246. return entity_traits::to_version(entity) == entity_traits::to_version(*this);
  247. }
  248. /**
  249. * @brief Compares a tombstone object and an identifier of any type.
  250. * @tparam Entity Type of identifier.
  251. * @param entity Identifier with which to compare.
  252. * @return True if the two elements differ, false otherwise.
  253. */
  254. template<typename Entity>
  255. [[nodiscard]] constexpr bool operator!=(const Entity entity) const ENTT_NOEXCEPT {
  256. return !(entity == *this);
  257. }
  258. };
  259. /**
  260. * @brief Compares a tombstone object and an identifier of any type.
  261. * @tparam Entity Type of identifier.
  262. * @param entity Identifier with which to compare.
  263. * @param other A tombstone object yet to be converted.
  264. * @return False if the two elements differ, true otherwise.
  265. */
  266. template<typename Entity>
  267. [[nodiscard]] constexpr bool operator==(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  268. return other.operator==(entity);
  269. }
  270. /**
  271. * @brief Compares a tombstone object and an identifier of any type.
  272. * @tparam Entity Type of identifier.
  273. * @param entity Identifier with which to compare.
  274. * @param other A tombstone object yet to be converted.
  275. * @return True if the two elements differ, false otherwise.
  276. */
  277. template<typename Entity>
  278. [[nodiscard]] constexpr bool operator!=(const Entity entity, const tombstone_t other) ENTT_NOEXCEPT {
  279. return !(other == entity);
  280. }
  281. /**
  282. * @brief Compile-time constant for null entities.
  283. *
  284. * There exist implicit conversions from this variable to identifiers of any
  285. * allowed type. Similarly, there exist comparison operators between the null
  286. * entity and any other identifier.
  287. */
  288. inline constexpr null_t null{};
  289. /**
  290. * @brief Compile-time constant for tombstone entities.
  291. *
  292. * There exist implicit conversions from this variable to identifiers of any
  293. * allowed type. Similarly, there exist comparison operators between the
  294. * tombstone entity and any other identifier.
  295. */
  296. inline constexpr tombstone_t tombstone{};
  297. } // namespace entt
  298. #endif