#include #include #include #include #include #include #include enum class my_entity : entt::id_type {}; template struct meta_mixin: Type { using allocator_type = typename Type::allocator_type; using value_type = typename Type::value_type; explicit meta_mixin(const allocator_type &allocator); }; template struct entt::storage_type { using type = meta_mixin>; }; template meta_mixin::meta_mixin(const allocator_type &allocator) : Type{allocator} { using namespace entt::literals; entt::meta() // cross registry, same type .template func &(const entt::id_type)>(&entt::basic_registry::storage), entt::as_ref_t>("storage"_hs) // cross registry, different types .template func &(const entt::id_type)>(&entt::basic_registry::storage), entt::as_ref_t>("storage"_hs); } template struct EntityCopy: testing::Test { using type = Type; }; using EntityCopyTypes = ::testing::Types, entt::basic_registry>; TYPED_TEST_SUITE(EntityCopy, EntityCopyTypes, ); TEST(EntityCopy, SameRegistry) { using namespace entt::literals; entt::registry registry{}; auto &&custom = registry.storage("custom"_hs); const auto src = registry.create(); const auto dst = registry.create(); custom.emplace(src, 1.); registry.emplace(src, 42); registry.emplace(src, 'c'); ASSERT_EQ(registry.size(), 2u); ASSERT_TRUE(custom.contains(src)); ASSERT_FALSE(custom.contains(dst)); ASSERT_TRUE((registry.all_of(src))); ASSERT_FALSE((registry.any_of(dst))); for(auto [id, storage]: registry.storage()) { // discard the custom storage because why not, this is just an example after all if(id != "custom"_hs && storage.contains(src)) { storage.push(dst, storage.value(src)); } } ASSERT_EQ(registry.size(), 2u); ASSERT_TRUE(custom.contains(src)); ASSERT_FALSE(custom.contains(dst)); ASSERT_TRUE((registry.all_of(src))); ASSERT_TRUE((registry.all_of(dst))); ASSERT_EQ(registry.get(dst), 42); ASSERT_EQ(registry.get(dst), 'c'); } TYPED_TEST(EntityCopy, CrossRegistry) { using namespace entt::literals; entt::basic_registry src{}; // other registry type, see typed test suite typename TestFixture::type dst{}; const auto entity = src.create(); const auto copy = dst.create(); src.emplace(entity, 42); src.emplace(entity, 'c'); ASSERT_EQ(src.size(), 1u); ASSERT_EQ(dst.size(), 1u); ASSERT_TRUE((src.all_of(entity))); ASSERT_FALSE((dst.template all_of(copy))); for(auto [id, storage]: src.storage()) { if(storage.contains(entity)) { auto *other = dst.storage(id); if(!other) { using namespace entt::literals; entt::resolve(storage.type()).invoke("storage"_hs, {}, entt::forward_as_meta(dst), id); other = dst.storage(id); } other->push(copy, storage.value(entity)); } } ASSERT_EQ(src.size(), 1u); ASSERT_EQ(dst.size(), 1u); ASSERT_TRUE((src.all_of(entity))); ASSERT_TRUE((dst.template all_of(copy))); ASSERT_EQ(dst.template get(copy), 42); ASSERT_EQ(dst.template get(copy), 'c'); }