#include #include #include #include #include #include #include /** * Yeah, I could have used a single memory chunk and a free list and associated * entities with a pointer to their first element, but this is just an example * of how to create a custom storage class. * You can have fun regarding the actual implementation. */ template struct multi_instance_storage: entt::basic_storage> { using underlying_storage = entt::basic_storage>; using value_type = typename underlying_storage::value_type; using entity_type = typename underlying_storage::entity_type; using size_type = typename underlying_storage::size_type; using iterator = typename underlying_storage::iterator; using const_iterator = typename underlying_storage::const_iterator; template void insert(Args &&...) = delete; using underlying_storage::remove; using underlying_storage::erase; template Type & emplace(const entity_type entt, Args &&... args) { std::vector *vec = underlying_storage::try_get(entt); if(!vec) { vec = &underlying_storage::emplace(entt); } return vec->emplace_back(Type{std::forward(args)...}); } void remove(const entity_type entt, const size_type index) { auto &vec = underlying_storage::get(entt); vec.erase(vec.begin() + index); if(vec.empty()) { underlying_storage::remove(entt); } } }; struct single_instance_type { int value; }; struct multi_instance_type { int value; }; template struct entt::pool { using type = storage_adapter_mixin>; }; TEST(Example, MultiInstanceStorage) { entt::registry registry; const auto entity = registry.create(); ASSERT_FALSE(registry.has(entity)); registry.emplace(entity, 0); ASSERT_TRUE(registry.has(entity)); ASSERT_EQ(registry.get(entity).size(), 1u); registry.remove(entity, 0u); ASSERT_FALSE(registry.has(entity)); registry.emplace(entity, 42); registry.emplace(entity, 3); registry.emplace(entity, 0); ASSERT_EQ(registry.get(entity).size(), 3u); ASSERT_EQ(registry.get(entity)[0].value, 42); ASSERT_EQ(registry.get(entity)[1].value, 3); ASSERT_EQ(registry.get(entity)[2].value, 0); registry.remove(entity, 1u); ASSERT_TRUE(registry.has(entity)); ASSERT_EQ(registry.get(entity).size(), 2u); ASSERT_EQ(registry.get(entity)[0].value, 42); ASSERT_EQ(registry.get(entity)[1].value, 0); registry.remove(entity); ASSERT_FALSE(registry.has(entity)); }