Pārlūkot izejas kodu

moved tags from entity/helper to core/type_traits (see #419)

Michele Caini 6 gadi atpakaļ
vecāks
revīzija
d9f93ccc11

+ 38 - 0
docs/md/core.md

@@ -14,6 +14,9 @@
 * [Monostate](#monostate)
 * [Type info](#type-info)
   * [Almost unique identifiers](#almost-unique-identifiers)
+* [Traits](#traits)
+  * [Member class type](#member-class-type)
+  * [Tags](#tags)
 <!--
 @endcond TURN_OFF_DOXYGEN
 -->
@@ -256,3 +259,38 @@ many others. As already mentioned above, since users have full control over
 their types, this problem is in any case easy to solve and should not worry too
 much.<br/>
 In all likelihood, it will never happen to run into a conflict anyway.
+
+# Traits
+
+This section contains a handful of utilities and traits not present in the
+standard template library but which can be useful in everyday life.
+
+## Member class type
+
+The `auto` template parameter introduced with C++17 made it possible to simplify
+many class templates and template functions but also made the class type opaque
+when members are passed as template arguments.<br/>
+The purpose of this utility is to extract the class type in a few lines of code:
+
+```cpp
+template<typename Member>
+using clazz = entt::member_class_t<Member>;
+```
+
+## Tags
+
+Since in `EnTT` the type identified by `ENTT_ID_TYPE` is very important and
+widely used, there is a more user-friendly shortcut for the creation of integral
+constants based on it.<br/>
+This shortcut is the alias template `entt::tag`.
+
+If used in combination with hashed strings, it helps to use human-readable names
+where types would be required otherwise. As an example:
+
+```cpp
+registry.assign<entt::tag<"enemy"_hs>>(entity);
+```
+
+However, this isn't the only permitted use. Literally any value convertible to
+`ENTT_ID_TYPE` is a good candidate, such as the named constants of an unscoped
+enum.

+ 0 - 15
docs/md/entity.md

@@ -20,7 +20,6 @@
     * [Null entity](#null-entity)
     * [Stamp](#stamp)
     * [Dependencies](#dependencies)
-    * [Tags](#tags)
     * [Actor](#actor)
     * [Context variables](#context-variables)
   * [Meet the runtime](#meet-the-runtime)
@@ -626,20 +625,6 @@ There are many other types of dependencies. In general, most of the functions
 that accept an entity as the first argument are good candidates for this
 purpose.
 
-### Tags
-
-There's nothing magical about the way tags can be assigned to entities while
-avoiding a performance hit at runtime. Nonetheless, the syntax can be annoying
-and that's why a more user-friendly shortcut is provided to do it.<br/>
-This shortcut is the alias template `entt::tag`.
-
-If used in combination with hashed strings, it helps to use tags where types
-would be required otherwise. As an example:
-
-```cpp
-registry.assign<entt::tag<"enemy"_hs>>(entity);
-```
-
 ### Actor
 
 The `actor` class is designed for those who don't feel immediately comfortable

+ 8 - 0
src/entt/core/type_traits.hpp

@@ -201,6 +201,14 @@ template<typename Member>
 using member_class_t = typename member_class<Member>::type;
 
 
+/**
+ * @brief Alias template to ease the creation of named values.
+ * @tparam Value A constant value at least convertible to `ENTT_ID_TYPE`.
+ */
+template<ENTT_ID_TYPE Value>
+using tag = std::integral_constant<ENTT_ID_TYPE, Value>;
+
+
 }
 
 

+ 0 - 23
src/entt/entity/helper.hpp

@@ -142,29 +142,6 @@ template<typename Entity>
 as_group(const basic_registry<Entity> &) ENTT_NOEXCEPT -> as_group<true, Entity>;
 
 
-/**
- * @brief Alias template to ease the assignment of tags to entities.
- *
- * If used in combination with hashed strings, it simplifies the assignment of
- * tags to entities and the use of tags in general where a type would be
- * required otherwise.<br/>
- * As an example and where the user defined literal for hashed strings hasn't
- * been changed:
- * @code{.cpp}
- * entt::registry registry;
- * registry.assign<entt::tag<"enemy"_hs>>(entity);
- * @endcode
- *
- * @note
- * Tags are empty components and therefore candidates for the empty component
- * optimization.
- *
- * @tparam Value The numeric representation of an instance of hashed string.
- */
-template<ENTT_ID_TYPE Value>
-using tag = std::integral_constant<ENTT_ID_TYPE, Value>;
-
-
 }
 
 

+ 7 - 0
test/entt/core/type_traits.cpp

@@ -1,4 +1,6 @@
 #include <gtest/gtest.h>
+#include <entt/config/config.h>
+#include <entt/core/hashed_string.hpp>
 #include <entt/core/type_traits.hpp>
 
 TEST(Choice, Functionalities) {
@@ -34,3 +36,8 @@ TEST(MemberClass, Functionalities) {
     ASSERT_TRUE((std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::bar)>>));
     ASSERT_TRUE((std::is_same_v<clazz, entt::member_class_t<decltype(&clazz::quux)>>));
 }
+
+TEST(Tag, Functionalities) {
+    ASSERT_EQ(entt::tag<"foobar"_hs>::value, entt::hashed_string::value("foobar"));
+    ASSERT_TRUE((std::is_same_v<typename entt::tag<"foobar"_hs>::value_type, ENTT_ID_TYPE>));
+}

+ 0 - 25
test/entt/entity/helper.cpp

@@ -22,28 +22,3 @@ TEST(Helper, AsGroup) {
     ([](entt::group<entt::exclude_t<int>, entt::get_t<const char>, double>) {})(entt::as_group{registry});
     ([](entt::group<entt::exclude_t<int>, entt::get_t<const char>, const double>) {})(entt::as_group{registry});
 }
-
-TEST(Helper, Tag) {
-    entt::registry registry;
-    const auto entity = registry.create();
-    registry.assign<entt::tag<"foobar"_hs>>(entity);
-    registry.assign<int>(entity, 42);
-    int counter{};
-
-    ASSERT_FALSE(registry.has<entt::tag<"barfoo"_hs>>(entity));
-    ASSERT_TRUE(registry.has<entt::tag<"foobar"_hs>>(entity));
-
-    for(auto entt: registry.view<int, entt::tag<"foobar"_hs>>()) {
-        (void)entt;
-        ++counter;
-    }
-
-    ASSERT_NE(counter, 0);
-
-    for(auto entt: registry.view<entt::tag<"foobar"_hs>>()) {
-        (void)entt;
-        --counter;
-    }
-
-    ASSERT_EQ(counter, 0);
-}