Просмотр исходного кода

meta: invocable properties (aka annotations - see #299)

Michele Caini 6 лет назад
Родитель
Сommit
2382d2e21c
3 измененных файлов с 23 добавлено и 8 удалено
  1. 12 3
      docs/md/meta.md
  2. 10 4
      src/entt/meta/factory.hpp
  3. 1 1
      test/entt/meta/meta.cpp

+ 12 - 3
docs/md/meta.md

@@ -516,9 +516,18 @@ Furthermore, the `prop` function supports different formats for properties:
           .prop(std::make_tuple(std::make_pair("tooltip"_hs, "message"), my_enum::key_only));
   ```
 
-  A tuple can contain one or more properties expressed as described above,
-  except for the key/value form. It will be unpacked and the properties will be
-  treated individually.
+  A tuple can contain one or more properties defined as described above, except
+  for the key/value form. The properties will be treated individually.
+
+* Annotations:
+
+  ```cpp
+  entt::meta<my_type>().type("reflected_type"_hs).prop(&property_generator);
+  ```
+
+  An annotation is an invocable object that returns one or more properties
+  defined as described above, except for the key/value form. The properties will
+  be treated individually.
 
 It's possible to invoke the `prop` function several times if needed, one for
 each property to associate with the last meta object created:

+ 10 - 4
src/entt/meta/factory.hpp

@@ -698,19 +698,25 @@ class extended_meta_factory: public meta_factory<Type> {
 
     template<typename... Property, std::size_t... Index>
     void unpack(std::tuple<Property...> property, std::index_sequence<Index...>) {
-        (unpack(choice<2>, std::get<Index>(property)), ...);
+        (unpack(choice<3>, std::get<Index>(property)), ...);
     }
 
     template<typename... Property>
-    void unpack(choice_t<2>, std::tuple<Property...> property) {
+    void unpack(choice_t<3>, std::tuple<Property...> property) {
         unpack(std::move(property), std::index_sequence_for<Property...>{});
     }
 
     template<typename... KeyOrValue>
-    void unpack(choice_t<1>, std::pair<KeyOrValue...> property) {
+    void unpack(choice_t<2>, std::pair<KeyOrValue...> property) {
         unpack(choice<0>, std::move(property.first), std::move(property.second));
     }
 
+    template<typename Func>
+    auto unpack(choice_t<1>, Func func)
+    -> decltype(unpack(choice<3>, func())) {
+        unpack(choice<3>, func());
+    }
+
     template<typename Key, typename... Value>
     void unpack(choice_t<0>, Key &&key, Value &&... value) {
         static auto property{std::make_tuple(std::forward<Key>(key), std::forward<Value>(value)...)};
@@ -752,7 +758,7 @@ public:
     template<typename PropertyOrKey, typename... Value>
     auto prop(PropertyOrKey &&property_or_key, Value &&... value) {
         static_assert(sizeof...(Value) <= 1);
-        unpack(choice<2>, std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
+        unpack(choice<3>, std::forward<PropertyOrKey>(property_or_key), std::forward<Value>(value)...);
         return *this;
     }
 

+ 1 - 1
test/entt/meta/meta.cpp

@@ -159,7 +159,7 @@ struct Meta: ::testing::Test {
                     .prop(std::make_tuple(std::make_pair(properties::prop_bool, true), std::make_pair(properties::prop_int, 0)))
                     .prop(properties::key_only)
                 .data<properties::key_only>("key_only"_hs)
-                    .prop(properties::key_only)
+                    .prop([]() { return properties::key_only; })
                 .data<&set<properties>, &get<properties>>("value"_hs)
                 .data<properties::prop_list>("prop_list"_hs)
                     .props(std::make_pair(properties::prop_bool, true), std::make_pair(properties::prop_int, 0), properties::key_only);