Browse Source

Property list (#338)

* Fix typo in comment
* Implemented a function for adding a list of properties to meta-item
Innokentiy Alaytsev 6 years ago
parent
commit
bfa46b795f
4 changed files with 56 additions and 5 deletions
  1. 1 0
      AUTHORS
  2. 5 0
      docs/md/meta.md
  3. 19 3
      src/entt/meta/factory.hpp
  4. 31 2
      test/entt/meta/meta.cpp

+ 1 - 0
AUTHORS

@@ -20,6 +20,7 @@ gale83
 ghost
 grdowns
 Green-Sky
+Innokentiy-Alaytsev
 Kerndog73
 Lawrencemm
 mhammerc

+ 5 - 0
docs/md/meta.md

@@ -522,6 +522,11 @@ entt::meta<my_type>()
             .prop(my_enum::a_value, 42);
 ```
 
+Alternatively, the `props` function is available to associate several properties
+at a time. However, in this case properties in the key/value form aren't
+allowed, since they would be interpreted as two different properties rather than
+a single one.
+
 The meta objects for which properties are supported are currently the meta
 types, meta constructors, meta data and meta functions. It's not possible to
 attach properties to other types of meta objects and the factory returned as a

+ 19 - 3
src/entt/meta/factory.hpp

@@ -703,8 +703,8 @@ class extended_meta_factory: public meta_factory<Type> {
     }
 
     template<typename Key, typename... Value>
-    void unpack(char, Key &&pkey, Value &&... pvalue) {
-        static auto property{std::make_tuple(std::forward<Key>(pkey), std::forward<Value>(pvalue)...)};
+    void unpack(char, Key &&key, Value &&... value) {
+        static auto property{std::make_tuple(std::forward<Key>(key), std::forward<Value>(value)...)};
 
         static internal::meta_prop_node node{
             *curr,
@@ -730,7 +730,7 @@ class extended_meta_factory: public meta_factory<Type> {
 
 public:
     /**
-     * @brief Assigns properties to the last meta object created.
+     * @brief Assigns a property to the last meta object created.
      *
      * Both the key and the value (if any) must be at least copy constructible.
      *
@@ -747,6 +747,22 @@ public:
         return *this;
     }
 
+    /**
+     * @brief Assigns properties to the last meta object created.
+     *
+     * Both the keys and the values (if any) must be at least copy
+     * constructible.
+     *
+     * @tparam Property Types of the properties.
+     * @param property Properties to assign to the last meta object created.
+     * @return A meta factory for the parent type.
+     */
+    template <typename... Property>
+    auto props(Property... property) {
+        (unpack(0, property), ...);
+        return *this;
+    }
+
 private:
     entt::internal::meta_prop_node **curr{nullptr};
 };

+ 31 - 2
test/entt/meta/meta.cpp

@@ -20,7 +20,8 @@ Type get(Type &prop) {
 enum class properties {
     prop_int,
     prop_bool,
-    key_only
+    key_only,
+    prop_list
 };
 
 struct empty_type {
@@ -160,7 +161,9 @@ struct Meta: ::testing::Test {
                     .prop(properties::key_only)
                 .data<properties::key_only>("key_only"_hs)
                     .prop(properties::key_only)
-                .data<&set<properties>, &get<properties>>("value"_hs);
+                .data<&set<properties>, &get<properties>>("value"_hs)
+                .data<properties::prop_list>("prop_list"_hs)
+                    .props(std::pair{properties::prop_bool, true}, std::pair{properties::prop_int, 0}, properties::key_only);
 
         entt::meta<unsigned int>().data<0u>("min"_hs).data<100u>("max"_hs);
 
@@ -2028,6 +2031,32 @@ TEST_F(Meta, KeyOnlyProperties) {
     ASSERT_FALSE(prop.value());
 }
 
+TEST_F(Meta, PropertyList) {
+    const auto type = entt::resolve<properties>();
+    const auto prop_list = type.data("prop_list"_hs);
+    const auto prop_bool = prop_list.prop(properties::prop_bool);
+    const auto prop_int =  prop_list.prop(properties::prop_int);
+    const auto key_prop = prop_list.prop(properties::key_only);
+
+    ASSERT_TRUE(prop_bool);
+    ASSERT_EQ(prop_bool.key().type(), entt::resolve<properties>());
+    ASSERT_EQ(prop_bool.key().cast<properties>(), properties::prop_bool);
+    ASSERT_TRUE(prop_bool.value());
+    ASSERT_TRUE(prop_bool.value().try_cast<bool>());
+
+    ASSERT_TRUE(prop_int);
+    ASSERT_EQ(prop_int.key().type(), entt::resolve<properties>());
+    ASSERT_EQ(prop_int.key().cast<properties>(), properties::prop_int);
+    ASSERT_TRUE(prop_int.value());
+    ASSERT_TRUE(prop_int.value().try_cast<int>());
+
+    ASSERT_TRUE(key_prop);
+    ASSERT_TRUE(key_prop.key());
+    ASSERT_EQ(key_prop.key().type(), entt::resolve<properties>());
+    ASSERT_EQ(key_prop.key().cast<properties>(), properties::key_only);
+    ASSERT_FALSE(key_prop.value());
+}
+
 TEST_F(Meta, Reset) {
     ASSERT_NE(*entt::internal::meta_info<>::global, nullptr);
     ASSERT_NE(entt::internal::meta_info<>::local, nullptr);