Răsfoiți Sursa

meta: allow unsetting flags from meta factory

skypjack 3 luni în urmă
părinte
comite
d15e514f10
4 a modificat fișierele cu 30 adăugiri și 8 ștergeri
  1. 0 1
      TODO
  2. 11 6
      src/entt/meta/factory.hpp
  3. 2 1
      test/common/meta_traits.h
  4. 17 0
      test/entt/meta/meta_factory.cpp

+ 0 - 1
TODO

@@ -34,4 +34,3 @@ TODO:
 * finish the imgui viewer/editor!
 * archetype-like a-là EnTT support (see my own notes)
 * meta: conversion_helper machinery has lot of room for improvements
-* meta_factory: add a replace flag to traits to get around the |-only mechanism

+ 11 - 6
src/entt/meta/factory.hpp

@@ -106,13 +106,17 @@ protected:
         }
     }
 
-    void traits(const meta_traits value) {
+    void traits(const meta_traits value, const bool unset) {
+        auto set_or_unset_on = [=](auto &node) {
+            node.traits = (unset ? (node.traits & ~value) : (node.traits | value));
+        };
+
         if(bucket == parent) {
-            fetch_node().traits |= value;
+            set_or_unset_on(fetch_node());
         } else if(invoke == nullptr) {
-            find_member_or_assert()->traits |= value;
+            set_or_unset_on(*find_member_or_assert());
         } else {
-            find_overload_or_assert()->traits |= value;
+            set_or_unset_on(*find_overload_or_assert());
         }
     }
 
@@ -474,12 +478,13 @@ public:
      *
      * @tparam Value Type of the traits value.
      * @param value Traits value.
+     * @param unset True to unset the given traits, false otherwise.
      * @return A meta factory for the parent type.
      */
     template<typename Value>
-    meta_factory traits(const Value value) {
+    meta_factory traits(const Value value, const bool unset = false) {
         static_assert(std::is_enum_v<Value>, "Invalid enum type");
-        base_type::traits(internal::user_to_meta_traits(value));
+        base_type::traits(internal::user_to_meta_traits(value), unset);
         return *this;
     }
 

+ 2 - 1
test/common/meta_traits.h

@@ -10,7 +10,8 @@ enum class meta_traits : std::uint8_t {
     one = 0x01,
     two = 0x02,
     three = 0x04,
-    _entt_enum_as_bitmask
+    all = 0xFF,
+    _entt_enum_as_bitmask = all
 };
 
 } // namespace test

+ 17 - 0
test/entt/meta/meta_factory.cpp

@@ -351,6 +351,23 @@ TEST_F(MetaFactory, Traits) {
     ASSERT_EQ(type.data("member"_hs).traits<test::meta_traits>(), test::meta_traits::one);
     ASSERT_EQ(type.func("func"_hs).traits<test::meta_traits>(), test::meta_traits::two);
     ASSERT_EQ(type.func("func"_hs).next().traits<test::meta_traits>(), test::meta_traits::three);
+
+    entt::meta_factory<clazz>{}
+        .traits(test::meta_traits::one, true)
+        .data<&base::member>("member"_hs)
+        .traits(test::meta_traits::one | test::meta_traits::three, true)
+        .func<&clazz::set_int>("func"_hs)
+        .traits(test::meta_traits::one | test::meta_traits::three, true)
+        .func<&clazz::set_boxed_int>("func"_hs)
+        .traits(test::meta_traits::all, true);
+
+    // traits are copied and never refreshed
+    type = entt::resolve<clazz>();
+
+    ASSERT_EQ(type.traits<test::meta_traits>(), test::meta_traits::three);
+    ASSERT_EQ(type.data("member"_hs).traits<test::meta_traits>(), test::meta_traits::none);
+    ASSERT_EQ(type.func("func"_hs).traits<test::meta_traits>(), test::meta_traits::two);
+    ASSERT_EQ(type.func("func"_hs).next().traits<test::meta_traits>(), test::meta_traits::none);
 }
 
 TEST_F(MetaFactory, Custom) {