mixin: support custom private/protected registries - close #1222

This commit is contained in:
Michele Caini
2025-02-27 09:52:05 +01:00
parent 3bd8807ec7
commit da1f56d046
4 changed files with 42 additions and 28 deletions

View File

@@ -36,20 +36,6 @@ template<typename Type, typename Registry>
struct has_on_destroy<Type, Registry, std::void_t<decltype(Type::on_destroy(std::declval<Registry &>(), std::declval<Registry>().create()))>>
: std::true_type {};
template<typename Type>
auto *any_to_owner(any &value) noexcept {
using base_type = basic_registry<typename Type::entity_type, typename Type::allocator_type>;
auto *reg = any_cast<base_type>(&value);
if constexpr(!std::is_same_v<Type, base_type>) {
if(!reg) {
reg = any_cast<Type>(&value);
}
}
return reg;
}
} // namespace internal
/*! @endcond */
@@ -130,7 +116,14 @@ private:
}
void bind_any(any value) noexcept final {
owner = internal::any_to_owner<registry_type>(value);
owner = any_cast<basic_registry_type>(&value);
if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
if(owner == nullptr) {
owner = any_cast<registry_type>(&value);
}
}
underlying_type::bind_any(std::move(value));
}
@@ -421,7 +414,14 @@ class basic_reactive_mixin final: public Type {
private:
void bind_any(any value) noexcept final {
owner = internal::any_to_owner<registry_type>(value);
owner = any_cast<basic_registry_type>(&value);
if constexpr(!std::is_same_v<registry_type, basic_registry_type>) {
if(owner == nullptr) {
owner = any_cast<registry_type>(&value);
}
}
underlying_type::bind_any(std::move(value));
}

View File

@@ -6,7 +6,26 @@
namespace test {
template<typename Entity>
struct basic_custom_registry: entt::basic_registry<Entity> {};
struct custom_registry: private entt::basic_registry<Entity> {
using base_type = entt::basic_registry<Entity>;
template<typename, typename>
friend class entt::basic_sigh_mixin;
template<typename, typename>
friend class entt::basic_reactive_mixin;
public:
using allocator_type = typename base_type::allocator_type;
using entity_type = typename base_type::entity_type;
using base_type::base_type;
using base_type::storage;
using base_type::create;
using base_type::emplace;
using base_type::insert;
};
} // namespace test

View File

@@ -31,7 +31,7 @@ void remove(Type &storage, const typename Type::registry_type &, const typename
template<typename Type>
struct entt::storage_type<Type, test::entity, std::allocator<Type>, std::enable_if_t<!std::is_same_v<Type, test::entity>>> {
using type = entt::basic_sigh_mixin<entt::basic_storage<Type, test::entity>, test::basic_custom_registry<test::entity>>;
using type = entt::basic_sigh_mixin<entt::basic_storage<Type, test::entity>, test::custom_registry<test::entity>>;
};
template<typename Type>
@@ -454,7 +454,7 @@ ENTT_DEBUG_TYPED_TEST(ReactiveMixinDeathTest, Registry) {
TYPED_TEST(ReactiveMixin, CustomRegistry) {
using value_type = typename TestFixture::type;
using registry_type = test::basic_custom_registry<test::entity>;
using registry_type = test::custom_registry<test::entity>;
registry_type registry;
entt::basic_reactive_mixin<entt::basic_storage<value_type, test::entity>, registry_type> pool;
@@ -476,7 +476,7 @@ TYPED_TEST(ReactiveMixin, CustomRegistry) {
ENTT_DEBUG_TYPED_TEST(ReactiveMixinDeathTest, CustomRegistry) {
using value_type = typename TestFixture::type;
using registry_type = test::basic_custom_registry<test::entity>;
using registry_type = test::custom_registry<test::entity>;
entt::basic_reactive_mixin<entt::basic_storage<value_type, test::entity>, registry_type> pool;
ASSERT_DEATH([[maybe_unused]] auto &registry = pool.registry(), "");
ASSERT_DEATH([[maybe_unused]] const auto &registry = std::as_const(pool).registry(), "");

View File

@@ -48,11 +48,6 @@ void listener(std::size_t &counter, Registry &, typename Registry::entity_type)
++counter;
}
template<typename Type>
struct entt::storage_type<Type, test::entity, std::allocator<Type>, std::enable_if_t<!std::is_same_v<Type, test::entity>>> {
using type = entt::basic_sigh_mixin<entt::basic_storage<Type, test::entity>, test::basic_custom_registry<test::entity>>;
};
template<typename Type>
struct SighMixin: testing::Test {
using type = Type;
@@ -433,7 +428,7 @@ TYPED_TEST(SighMixin, Swap) {
TEST(SighMixin, AutoSignal) {
entt::registry registry;
auto const entity = registry.create();
const auto entity = registry.create();
bool created{};
bool updated{};
@@ -488,7 +483,7 @@ ENTT_DEBUG_TYPED_TEST(SighMixinDeathTest, Registry) {
TYPED_TEST(SighMixin, CustomRegistry) {
using value_type = typename TestFixture::type;
using registry_type = test::basic_custom_registry<test::entity>;
using registry_type = test::custom_registry<test::entity>;
registry_type registry;
entt::basic_sigh_mixin<entt::basic_storage<value_type, test::entity>, registry_type> pool;
@@ -520,7 +515,7 @@ TYPED_TEST(SighMixin, CustomRegistry) {
ENTT_DEBUG_TYPED_TEST(SighMixinDeathTest, CustomRegistry) {
using value_type = typename TestFixture::type;
using registry_type = test::basic_custom_registry<test::entity>;
using registry_type = test::custom_registry<test::entity>;
entt::basic_sigh_mixin<entt::basic_storage<value_type, test::entity>, registry_type> pool;
ASSERT_DEATH([[maybe_unused]] auto &registry = pool.registry(), "");
ASSERT_DEATH([[maybe_unused]] const auto &registry = std::as_const(pool).registry(), "");