sigh mixin: automatic signal registration for components (#1168)
This commit is contained in:
@@ -11,6 +11,42 @@
|
||||
|
||||
namespace entt {
|
||||
|
||||
/*! @cond TURN_OFF_DOXYGEN */
|
||||
namespace internal {
|
||||
|
||||
template<typename T, typename Reg, typename = void>
|
||||
struct has_on_construct final: std::false_type {};
|
||||
|
||||
template<typename T, typename Reg>
|
||||
struct has_on_construct<
|
||||
T, Reg,
|
||||
std::void_t<decltype(T::on_construct(std::declval<Reg &>(),
|
||||
std::declval<Reg &>().create()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template<typename T, typename Reg, typename = void>
|
||||
struct has_on_update final: std::false_type {};
|
||||
|
||||
template<typename T, typename Reg>
|
||||
struct has_on_update<
|
||||
T, Reg,
|
||||
std::void_t<decltype(T::on_update(std::declval<Reg &>(),
|
||||
std::declval<Reg &>().create()))>>
|
||||
: std::true_type {};
|
||||
|
||||
template<typename T, typename Reg, typename = void>
|
||||
struct has_on_destroy final: std::false_type {};
|
||||
|
||||
template<typename T, typename Reg>
|
||||
struct has_on_destroy<
|
||||
T, Reg,
|
||||
std::void_t<decltype(T::on_destroy(std::declval<Reg &>(),
|
||||
std::declval<Reg &>().create()))>>
|
||||
: std::true_type {};
|
||||
|
||||
} // namespace internal
|
||||
/*! @endcond */
|
||||
|
||||
/**
|
||||
* @brief Mixin type used to add signal support to storage types.
|
||||
*
|
||||
@@ -108,7 +144,21 @@ public:
|
||||
owner{},
|
||||
construction{allocator},
|
||||
destruction{allocator},
|
||||
update{allocator} {}
|
||||
update{allocator} {
|
||||
using element_type = typename Type::element_type;
|
||||
|
||||
if constexpr(internal::has_on_construct<element_type, Registry>::value) {
|
||||
entt::sink{construction}.template connect<&element_type::on_construct>();
|
||||
}
|
||||
|
||||
if constexpr(internal::has_on_update<element_type, Registry>::value) {
|
||||
entt::sink{update}.template connect<&element_type::on_update>();
|
||||
}
|
||||
|
||||
if constexpr(internal::has_on_destroy<element_type, Registry>::value) {
|
||||
entt::sink{destruction}.template connect<&element_type::on_destroy>();
|
||||
}
|
||||
}
|
||||
|
||||
/*! @brief Default copy constructor, deleted on purpose. */
|
||||
basic_sigh_mixin(const basic_sigh_mixin &) = delete;
|
||||
|
||||
62
test/entt/entity/storage_signals.cpp
Normal file
62
test/entt/entity/storage_signals.cpp
Normal file
@@ -0,0 +1,62 @@
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <entt/entity/registry.hpp>
|
||||
|
||||
struct count_tracker final {
|
||||
inline static void on_construct(entt::registry &, entt::entity) {
|
||||
++created;
|
||||
}
|
||||
|
||||
inline static void on_update(entt::registry &, entt::entity) {
|
||||
++updated;
|
||||
}
|
||||
|
||||
inline static void on_destroy(entt::registry &, entt::entity) {
|
||||
++destroyed;
|
||||
}
|
||||
|
||||
inline static std::size_t created = 0;
|
||||
inline static std::size_t updated = 0;
|
||||
inline static std::size_t destroyed = 0;
|
||||
|
||||
inline static std::size_t alive() {
|
||||
return created - destroyed;
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Type>
|
||||
struct StorageSignals: testing::Test {
|
||||
using type = Type;
|
||||
};
|
||||
|
||||
using StorageSignalsTypes = ::testing::Types<count_tracker>;
|
||||
|
||||
TYPED_TEST_SUITE(StorageSignals, StorageSignalsTypes, );
|
||||
|
||||
TYPED_TEST(StorageSignals, AutoSignals) {
|
||||
using value_type = typename TestFixture::type;
|
||||
|
||||
entt::registry registry;
|
||||
auto const id = registry.create();
|
||||
|
||||
registry.emplace<count_tracker>(id);
|
||||
|
||||
ASSERT_EQ(count_tracker::created, 1);
|
||||
ASSERT_EQ(count_tracker::updated, 0);
|
||||
ASSERT_EQ(count_tracker::destroyed, 0);
|
||||
ASSERT_EQ(count_tracker::alive(), 1);
|
||||
|
||||
registry.replace<count_tracker>(id);
|
||||
|
||||
ASSERT_EQ(count_tracker::created, 1);
|
||||
ASSERT_EQ(count_tracker::updated, 1);
|
||||
ASSERT_EQ(count_tracker::destroyed, 0);
|
||||
ASSERT_EQ(count_tracker::alive(), 1);
|
||||
|
||||
registry.remove<count_tracker>(id);
|
||||
|
||||
ASSERT_EQ(count_tracker::created, 1);
|
||||
ASSERT_EQ(count_tracker::updated, 1);
|
||||
ASSERT_EQ(count_tracker::destroyed, 1);
|
||||
ASSERT_EQ(count_tracker::alive(), 0);
|
||||
}
|
||||
Reference in New Issue
Block a user