Skip to content

Commit 31d5d5f

Browse files
committed
meta: top-level only searches for data and functions
1 parent f3fa359 commit 31d5d5f

File tree

4 files changed

+41
-10
lines changed

4 files changed

+41
-10
lines changed

TODO

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,4 @@ TODO:
3636
* find a way to test deleter and the absence of it in basic_any
3737
* archetype-like a-l� EnTT support (see my own notes)
3838
* meta_factory: add a replace flag to traits to get around the |-only mechanism
39-
* support searching meta data and func only on top level types, no bases
39+
* propagate already loaded meta types from invoke/arg/whatever as much as possible to reduce lookups

src/entt/meta/meta.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,11 @@ class meta_type {
13241324
/**
13251325
* @brief Lookup utility for meta data (bases are also visited).
13261326
* @param id Unique identifier.
1327+
* @param recursive True for a search in the base classes, false otherwise.
13271328
* @return The registered meta data for the given identifier, if any.
13281329
*/
1329-
[[nodiscard]] meta_data data(const id_type id) const {
1330-
const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id);
1330+
[[nodiscard]] meta_data data(const id_type id, const bool recursive = true) const {
1331+
const auto *elem = internal::look_for<&internal::meta_type_descriptor::data>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
13311332
return (elem != nullptr) ? meta_data{*ctx, *elem} : meta_data{};
13321333
}
13331334

@@ -1343,10 +1344,11 @@ class meta_type {
13431344
/**
13441345
* @brief Lookup utility for meta functions (bases are also visited).
13451346
* @param id Unique identifier.
1347+
* @param recursive True for a search in the base classes, false otherwise.
13461348
* @return The registered meta function for the given identifier, if any.
13471349
*/
1348-
[[nodiscard]] meta_func func(const id_type id) const {
1349-
const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id);
1350+
[[nodiscard]] meta_func func(const id_type id, const bool recursive = true) const {
1351+
const auto *elem = internal::look_for<&internal::meta_type_descriptor::func>(internal::meta_context::from(*ctx), fetch_node(), id, recursive);
13501352
return (elem != nullptr) ? meta_func{*ctx, *elem} : meta_func{};
13511353
}
13521354

src/entt/meta/node.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,17 +166,19 @@ template<auto Member, typename Type, typename Value>
166166
}
167167

168168
template<auto Member>
169-
[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id) {
169+
[[nodiscard]] auto *look_for(const meta_context &context, const meta_type_node &node, const id_type id, bool recursive) {
170170
using value_type = typename std::remove_reference_t<decltype((node.details.get()->*Member))>::value_type;
171171

172172
if(node.details) {
173173
if(auto *member = find_member<&value_type::id>((node.details.get()->*Member), id); member != nullptr) {
174174
return member;
175175
}
176176

177-
for(auto &&curr: node.details->base) {
178-
if(auto *elem = look_for<Member>(context, curr.resolve(context), id); elem) {
179-
return elem;
177+
if(recursive) {
178+
for(auto &&curr: node.details->base) {
179+
if(auto *elem = look_for<Member>(context, curr.resolve(context), id, recursive); elem) {
180+
return elem;
181+
}
180182
}
181183
}
182184
}

test/entt/meta/meta_type.cpp

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Type get(Type &elem) {
3232

3333
struct base {
3434
char value{'c'};
35+
36+
static int f() {
37+
return 0;
38+
}
3539
};
3640

3741
struct derived: base {
@@ -134,7 +138,8 @@ struct MetaType: ::testing::Test {
134138

135139
entt::meta_factory<base>{}
136140
.type("base"_hs)
137-
.data<&base::value>("value"_hs);
141+
.data<&base::value>("value"_hs)
142+
.func<&base::f>("func"_hs);
138143

139144
entt::meta_factory<derived>{}
140145
.type("derived")
@@ -455,6 +460,17 @@ TEST_F(MetaType, Data) {
455460
ASSERT_EQ(type.data().cbegin(), type.data().cend());
456461
}
457462

463+
TEST_F(MetaType, DataRecursive) {
464+
using namespace entt::literals;
465+
466+
auto type = entt::resolve<derived>();
467+
const derived instance{};
468+
469+
ASSERT_TRUE(type.data("value"_hs));
470+
ASSERT_EQ('c', type.data("value"_hs).get(instance).cast<char>());
471+
ASSERT_FALSE(type.data("value"_hs, false));
472+
}
473+
458474
TEST_F(MetaType, Func) {
459475
using namespace entt::literals;
460476

@@ -478,6 +494,17 @@ TEST_F(MetaType, Func) {
478494
ASSERT_EQ(type.func().cbegin(), type.func().cend());
479495
}
480496

497+
TEST_F(MetaType, FuncRecursive) {
498+
using namespace entt::literals;
499+
500+
auto type = entt::resolve<derived>();
501+
const derived instance{};
502+
503+
ASSERT_TRUE(type.func("func"_hs));
504+
ASSERT_EQ(0, type.func("func"_hs).invoke(instance).cast<int>());
505+
ASSERT_FALSE(type.func("func"_hs, false));
506+
}
507+
481508
TEST_F(MetaType, Invoke) {
482509
using namespace entt::literals;
483510

0 commit comments

Comments
 (0)