meta: allow unsetting flags from meta factory

This commit is contained in:
skypjack
2025-11-12 10:08:31 +01:00
parent fe8320c66f
commit d15e514f10
4 changed files with 30 additions and 8 deletions

1
TODO
View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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) {