organizer: fixed an issue for free functions with payload (close #613)
This commit is contained in:
@@ -86,13 +86,16 @@ struct resource<type_list<Args...>, type_list<Req...>> {
|
||||
|
||||
|
||||
template<typename... Req, typename Ret, typename... Args>
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> to_resource(Ret(*)(Args...));
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> free_function_to_resource(Ret(*)(Args...));
|
||||
|
||||
template<typename... Req, typename Ret, typename Type, typename... Args>
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource(Ret(*)(Type &, Args...));
|
||||
|
||||
template<typename... Req, typename Ret, typename Class, typename... Args>
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> to_resource(Ret(Class:: *)(Args...));
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource(Ret(Class:: *)(Args...));
|
||||
|
||||
template<typename... Req, typename Ret, typename Class, typename... Args>
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> to_resource(Ret(Class:: *)(Args...) const);
|
||||
resource<type_list<std::remove_reference_t<Args>...>, type_list<Req...>> constrained_function_to_resource(Ret(Class:: *)(Args...) const);
|
||||
|
||||
template<typename... Req>
|
||||
resource<type_list<>, type_list<Req...>> to_resource();
|
||||
@@ -371,7 +374,7 @@ public:
|
||||
*/
|
||||
template<auto Candidate, typename... Req>
|
||||
void emplace(const char *name = nullptr) {
|
||||
using resource_type = decltype(internal::to_resource<Req...>(Candidate));
|
||||
using resource_type = decltype(internal::free_function_to_resource<Req...>(Candidate));
|
||||
constexpr auto requires_registry = type_list_contains_v<typename resource_type::args, basic_registry<entity_type>>;
|
||||
|
||||
callback_type *callback = +[](const void *, basic_registry<entity_type> ®) {
|
||||
@@ -403,11 +406,11 @@ public:
|
||||
*/
|
||||
template<auto Candidate, typename... Req, typename Type>
|
||||
void emplace(Type &value_or_instance, const char *name = nullptr) {
|
||||
using resource_type = decltype(internal::to_resource<Req...>(Candidate));
|
||||
using resource_type = decltype(internal::constrained_function_to_resource<Req...>(Candidate));
|
||||
constexpr auto requires_registry = type_list_contains_v<typename resource_type::args, basic_registry<entity_type>>;
|
||||
|
||||
callback_type *callback = +[](const void *payload, basic_registry<entity_type> ®) {
|
||||
Type *curr = static_cast<Type *>(const_cast<std::conditional_t<std::is_const_v<Type>, const void *, void *>>(payload));
|
||||
Type *curr = static_cast<Type *>(const_cast<constness_as_t<void, Type> *>(payload));
|
||||
std::apply(Candidate, std::tuple_cat(std::forward_as_tuple(*curr), to_args(reg, typename resource_type::args{})));
|
||||
};
|
||||
|
||||
@@ -439,7 +442,7 @@ public:
|
||||
*/
|
||||
template<typename... Req>
|
||||
void emplace(function_type *func, const void *payload = nullptr, const char *name = nullptr) {
|
||||
using resource_type = decltype(internal::to_resource<Req...>());
|
||||
using resource_type = internal::resource<type_list<>, type_list<Req...>>;
|
||||
track_dependencies(vertices.size(), true, typename resource_type::ro{}, typename resource_type::rw{});
|
||||
|
||||
vertices.push_back({
|
||||
|
||||
@@ -13,6 +13,10 @@ struct clazz {
|
||||
void rw_int(entt::view<entt::exclude_t<>, int>) {}
|
||||
void rw_int_char(entt::view<entt::exclude_t<>, int, char>) {}
|
||||
void rw_int_char_double(entt::view<entt::exclude_t<>, int, char>, double &) {}
|
||||
|
||||
static void ro_int_with_payload(const clazz &, entt::view<entt::exclude_t<>, const int>) {}
|
||||
static void ro_char_with_payload(const clazz &, entt::view<entt::exclude_t<>, const char>) {}
|
||||
static void ro_int_char_with_payload(clazz &, entt::view<entt::exclude_t<>, const int, const char>) {}
|
||||
};
|
||||
|
||||
void to_args_integrity(entt::view<entt::exclude_t<>, int> view, std::size_t &value, entt::registry ®istry) {
|
||||
@@ -131,6 +135,72 @@ TEST(Organizer, EmplaceMemberFunction) {
|
||||
ASSERT_EQ(organizer.graph().size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Organizer, EmplaceFreeFunctionWithPayload) {
|
||||
entt::organizer organizer;
|
||||
entt::registry registry;
|
||||
clazz instance;
|
||||
|
||||
// TODO
|
||||
|
||||
organizer.emplace<&clazz::ro_int_char_double>(instance, "t1");
|
||||
organizer.emplace<&clazz::ro_int_with_payload>(instance, "t2");
|
||||
organizer.emplace<&clazz::ro_char_with_payload, const clazz>(instance, "t3");
|
||||
organizer.emplace<&clazz::ro_int_char_with_payload, clazz>(instance, "t4");
|
||||
organizer.emplace<&clazz::rw_int_char>(instance, "t5");
|
||||
|
||||
const auto graph = organizer.graph();
|
||||
|
||||
ASSERT_EQ(graph.size(), 5u);
|
||||
|
||||
ASSERT_STREQ(graph[0u].name(), "t1");
|
||||
ASSERT_STREQ(graph[1u].name(), "t2");
|
||||
ASSERT_STREQ(graph[2u].name(), "t3");
|
||||
ASSERT_STREQ(graph[3u].name(), "t4");
|
||||
ASSERT_STREQ(graph[4u].name(), "t5");
|
||||
|
||||
ASSERT_EQ(graph[0u].ro_count(), 3u);
|
||||
ASSERT_EQ(graph[1u].ro_count(), 1u);
|
||||
ASSERT_EQ(graph[2u].ro_count(), 2u);
|
||||
ASSERT_EQ(graph[3u].ro_count(), 2u);
|
||||
ASSERT_EQ(graph[4u].ro_count(), 0u);
|
||||
|
||||
ASSERT_EQ(graph[0u].rw_count(), 0u);
|
||||
ASSERT_EQ(graph[1u].rw_count(), 0u);
|
||||
ASSERT_EQ(graph[2u].rw_count(), 0u);
|
||||
ASSERT_EQ(graph[3u].rw_count(), 1u);
|
||||
ASSERT_EQ(graph[4u].rw_count(), 2u);
|
||||
|
||||
ASSERT_NE(graph[0u].info(), graph[1u].info());
|
||||
ASSERT_NE(graph[1u].info(), graph[2u].info());
|
||||
ASSERT_NE(graph[2u].info(), graph[3u].info());
|
||||
ASSERT_NE(graph[3u].info(), graph[4u].info());
|
||||
|
||||
ASSERT_TRUE(graph[0u].top_level());
|
||||
ASSERT_TRUE(graph[1u].top_level());
|
||||
ASSERT_TRUE(graph[2u].top_level());
|
||||
ASSERT_FALSE(graph[3u].top_level());
|
||||
ASSERT_FALSE(graph[4u].top_level());
|
||||
|
||||
ASSERT_EQ(graph[0u].children().size(), 1u);
|
||||
ASSERT_EQ(graph[1u].children().size(), 1u);
|
||||
ASSERT_EQ(graph[2u].children().size(), 1u);
|
||||
ASSERT_EQ(graph[3u].children().size(), 1u);
|
||||
ASSERT_EQ(graph[4u].children().size(), 0u);
|
||||
|
||||
ASSERT_EQ(graph[0u].children()[0u], 4u);
|
||||
ASSERT_EQ(graph[1u].children()[0u], 4u);
|
||||
ASSERT_EQ(graph[2u].children()[0u], 3u);
|
||||
ASSERT_EQ(graph[3u].children()[0u], 4u);
|
||||
|
||||
for(auto &&vertex: graph) {
|
||||
ASSERT_NO_THROW(vertex.callback()(vertex.data(), registry));
|
||||
}
|
||||
|
||||
organizer.clear();
|
||||
|
||||
ASSERT_EQ(organizer.graph().size(), 0u);
|
||||
}
|
||||
|
||||
TEST(Organizer, EmplaceDirectFunction) {
|
||||
entt::organizer organizer;
|
||||
entt::registry registry;
|
||||
|
||||
Reference in New Issue
Block a user