Created
June 8, 2021 15:49
-
-
Save danielytics/d43902a9f43bd4d974d26cacc8b29a11 to your computer and use it in GitHub Desktop.
EnTT poly_storage registry copying
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <entt/entity/registry.hpp> | |
struct A { | |
}; | |
struct B { | |
int x; | |
}; | |
int main (int argc, char* argv[]) | |
{ | |
entt::registry registry; | |
entt::registry other; | |
entt::entity entities[10u]; | |
registry.create(std::begin(entities), std::end(entities)); | |
registry.insert<int>(std::begin(entities), std::end(entities), 42); | |
registry.insert<char>(std::begin(entities), std::end(entities), 'c'); | |
registry.insert<B>(std::begin(entities), std::end(entities), {2}); | |
// insert A, an empty component: | |
registry.insert<A>(std::begin(entities), std::end(entities)); | |
for(const auto entity: registry.view<B>()) { | |
std::cout << entt::to_integral(entity); | |
if (registry.any_of<B>(entity)) { | |
std::cout << " registry: " << registry.get<B>(entity).x; | |
} | |
if (other.valid(entity)) { | |
std::cout << " other: "; | |
if (other.any_of<B>(entity)) { | |
std::cout << other.get<B>(entity).x; | |
} | |
} | |
std::cout << "\n"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
main.cpp:52:20: error: cannot take the address of an rvalue of type 'void' | |
return &self.get(entity); | |
^~~~~~~~~~~~~~~~~ | |
main.cpp:67:29: note: in instantiation of member function 'PolyStorage<entt::entity>::members<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>>>::get' requested here | |
&members<Type>::get, | |
^ | |
entt/src/entt/entity/../poly/poly.hpp:274:17: note: in instantiation of function template specialization 'entt::basic_poly<PolyStorage<entt::entity>, 16, 16>::basic_poly<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &, entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &>' requested here | |
*this = basic_poly{std::in_place_type<Type>, std::forward<Args>(args)...}; | |
^ | |
entt/src/entt/entity/registry.hpp:115:33: note: in instantiation of function template specialization 'entt::basic_poly<PolyStorage<entt::entity>, 16, 16>::emplace<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &, entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &>' requested here | |
pdata.poly.template emplace<storage_type<Component> &>(*static_cast<storage_type<Component> *>(pdata.pool.get())); | |
^ | |
entt/src/entt/entity/registry.hpp:566:9: note: in instantiation of function template specialization 'entt::basic_registry<entt::entity>::assure<A>' requested here | |
assure<Component>()->insert(*this, first, last, value); | |
^ | |
main.cpp:98:14: note: in instantiation of function template specialization 'entt::basic_registry<entt::entity>::insert<A, entt::entity *>' requested here | |
registry.insert<A>(std::begin(entities), std::end(entities)); | |
^ | |
main.cpp:57:28: error: no matching member function for call to 'insert' | |
other.template insert<typename Type::value_type>(base.rbegin(), base.rend(), self.rbegin()); | |
~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
main.cpp:68:29: note: in instantiation of member function 'PolyStorage<entt::entity>::members<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>>>::copy_to' requested here | |
&members<Type>::copy_to | |
^ | |
entt/src/entt/entity/../poly/poly.hpp:274:17: note: in instantiation of function template specialization 'entt::basic_poly<PolyStorage<entt::entity>, 16, 16>::basic_poly<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &, entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &>' requested here | |
*this = basic_poly{std::in_place_type<Type>, std::forward<Args>(args)...}; | |
^ | |
entt/src/entt/entity/registry.hpp:115:33: note: in instantiation of function template specialization 'entt::basic_poly<PolyStorage<entt::entity>, 16, 16>::emplace<entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &, entt::sigh_storage_mixin<entt::basic_storage<entt::entity, A, std::allocator<A>, void>> &>' requested here | |
pdata.poly.template emplace<storage_type<Component> &>(*static_cast<storage_type<Component> *>(pdata.pool.get())); | |
^ | |
entt/src/entt/entity/registry.hpp:566:9: note: in instantiation of function template specialization 'entt::basic_registry<entt::entity>::assure<A>' requested here | |
assure<Component>()->insert(*this, first, last, value); | |
^ | |
main.cpp:98:14: note: in instantiation of function template specialization 'entt::basic_registry<entt::entity>::insert<A, entt::entity *>' requested here | |
registry.insert<A>(std::begin(entities), std::end(entities)); | |
^ | |
entt/src/entt/entity/registry.hpp:564:10: note: candidate function template not viable: no known conversion from 'entt::basic_sparse_set<entt::entity, std::allocator<entt::entity>>::reverse_iterator' (aka 'const entt::entity *') to 'const A' for 3rd argument | |
void insert(It first, It last, const Component &value = {}) { | |
^ | |
entt/src/entt/entity/registry.hpp:582:10: note: candidate template ignored: requirement 'std::is_same_v<entt::entity, A>' was not satisfied [with Component = A, EIt = const entt::entity *, CIt = const entt::entity *] | |
void insert(EIt first, EIt last, CIt from) { | |
^ | |
2 errors generated. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <entt/core/utility.hpp> | |
#include <entt/entity/poly_storage.hpp> | |
#include <entt/entity/registry.hpp> | |
template<typename... Type> | |
entt::type_list<Type...> as_type_list(const entt::type_list<Type...> &); | |
template<typename Entity> | |
struct PolyStorage: entt::type_list_cat_t< | |
decltype(as_type_list(std::declval<entt::Storage<Entity>>())), | |
entt::type_list< | |
void(const Entity *, const Entity *, void *), | |
void(entt::basic_registry<Entity> &, const Entity, const void *), | |
const void *(const Entity) const, | |
void(entt::basic_registry<Entity> &) const | |
> | |
> { | |
using entity_type = Entity; | |
using size_type = std::size_t; | |
template<typename Base> | |
struct type: entt::Storage<Entity>::template type<Base> { | |
static constexpr auto base = decltype(as_type_list(std::declval<entt::Storage<Entity>>()))::size; | |
void erase(entt::basic_registry<Entity> &owner, const entity_type *first, const entity_type *last) { | |
entt::poly_call<base + 0>(*this, first, last, &owner); | |
} | |
void emplace(entt::basic_registry<Entity> &owner, const entity_type entity, const void *instance) { | |
entt::poly_call<base + 1>(*this, owner, entity, instance); | |
} | |
const void * get(const entity_type entity) const { | |
return entt::poly_call<base + 2>(*this, entity); | |
} | |
void copy_to(entt::basic_registry<Entity> &other) const { | |
entt::poly_call<base + 3>(*this, other); | |
} | |
}; | |
template<typename Type> | |
struct members { | |
static void emplace(Type &self, entt::basic_registry<Entity> &owner, const entity_type entity, const void *instance) { | |
self.emplace(owner, entity, *static_cast<const typename Type::value_type *>(instance)); | |
} | |
static const typename Type::value_type * get(const Type &self, const entity_type entity) { | |
return &self.get(entity); | |
} | |
static void copy_to(const Type &self, entt::basic_registry<entity_type> &other) { | |
const entt::sparse_set &base = self; | |
other.template insert<typename Type::value_type>(base.rbegin(), base.rend(), self.rbegin()); | |
} | |
}; | |
template<typename Type> | |
using impl = entt::value_list_cat_t< | |
typename entt::Storage<Entity>::template impl<Type>, | |
entt::value_list< | |
&Type::template erase<const entity_type *>, | |
&members<Type>::emplace, | |
&members<Type>::get, | |
&members<Type>::copy_to | |
> | |
>; | |
}; | |
template<typename Entity> | |
struct entt::poly_storage_traits<Entity> { | |
using storage_type = entt::poly<PolyStorage<Entity>>; | |
}; | |
struct A { | |
}; | |
struct B { | |
int x; | |
}; | |
int main (int argc, char* argv[]) | |
{ | |
entt::registry registry; | |
entt::registry other; | |
entt::entity entities[10u]; | |
registry.create(std::begin(entities), std::end(entities)); | |
registry.insert<int>(std::begin(entities), std::end(entities), 42); | |
registry.insert<char>(std::begin(entities), std::end(entities), 'c'); | |
registry.insert<B>(std::begin(entities), std::end(entities), {2}); | |
// insert A, an empty component: | |
registry.insert<A>(std::begin(entities), std::end(entities)); | |
other.assign(registry.data(), registry.data() + registry.size(), registry.destroyed()); | |
registry.visit([&](const auto info) { | |
std::as_const(registry).storage(info)->copy_to(other); | |
}); | |
for(const auto entity: registry.view<B>()) { | |
std::cout << entt::to_integral(entity); | |
if (registry.any_of<B>(entity)) { | |
std::cout << " registry: " << registry.get<B>(entity).x; | |
} | |
if (other.valid(entity)) { | |
std::cout << " other: "; | |
if (other.any_of<B>(entity)) { | |
std::cout << other.get<B>(entity).x; | |
} | |
} | |
std::cout << "\n"; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <entt/core/utility.hpp> | |
#include <entt/entity/poly_storage.hpp> | |
#include <entt/entity/registry.hpp> | |
template<typename... Type> | |
entt::type_list<Type...> as_type_list(const entt::type_list<Type...> &); | |
template<typename Entity> | |
struct PolyStorage: entt::type_list_cat_t< | |
decltype(as_type_list(std::declval<entt::Storage<Entity>>())), | |
entt::type_list< | |
void(const Entity *, const Entity *, void *), | |
void(entt::basic_registry<Entity> &, const Entity, const void *), | |
const void *(const Entity) const, | |
void(entt::basic_registry<Entity> &) const | |
> | |
> { | |
using entity_type = Entity; | |
using size_type = std::size_t; | |
template<typename Base> | |
struct type: entt::Storage<Entity>::template type<Base> { | |
static constexpr auto base = decltype(as_type_list(std::declval<entt::Storage<Entity>>()))::size; | |
void erase(entt::basic_registry<Entity> &owner, const entity_type *first, const entity_type *last) { | |
entt::poly_call<base + 0>(*this, first, last, &owner); | |
} | |
void emplace(entt::basic_registry<Entity> &owner, const entity_type entity, const void *instance) { | |
entt::poly_call<base + 1>(*this, owner, entity, instance); | |
} | |
const void * get(const entity_type entity) const { | |
return entt::poly_call<base + 2>(*this, entity); | |
} | |
void copy_to(entt::basic_registry<Entity> &other) const { | |
entt::poly_call<base + 3>(*this, other); | |
} | |
}; | |
template<typename Type> | |
struct members { | |
static void emplace(Type &self, entt::basic_registry<Entity> &owner, const entity_type entity, const void *instance) { | |
self.emplace(owner, entity, *static_cast<const typename Type::value_type *>(instance)); | |
} | |
static const typename Type::value_type * get(const Type &self, const entity_type entity) { | |
return &self.get(entity); | |
} | |
static void copy_to(const Type &self, entt::basic_registry<entity_type> &other) { | |
const entt::sparse_set &base = self; | |
other.template insert<typename Type::value_type>(base.rbegin(), base.rend(), self.rbegin()); | |
} | |
}; | |
template<typename Type> | |
using impl = entt::value_list_cat_t< | |
typename entt::Storage<Entity>::template impl<Type>, | |
entt::value_list< | |
&Type::template erase<const entity_type *>, | |
&members<Type>::emplace, | |
&members<Type>::get, | |
&members<Type>::copy_to | |
> | |
>; | |
}; | |
template<typename Entity> | |
struct entt::poly_storage_traits<Entity> { | |
using storage_type = entt::poly<PolyStorage<Entity>>; | |
}; | |
struct A { | |
}; | |
struct B { | |
int x; | |
}; | |
int main (int argc, char* argv[]) | |
{ | |
entt::registry registry; | |
entt::registry other; | |
entt::entity entities[10u]; | |
registry.create(std::begin(entities), std::end(entities)); | |
registry.insert<int>(std::begin(entities), std::end(entities), 42); | |
registry.insert<char>(std::begin(entities), std::end(entities), 'c'); | |
registry.insert<B>(std::begin(entities), std::end(entities), {2}); | |
other.assign(registry.data(), registry.data() + registry.size(), registry.destroyed()); | |
registry.visit([&](const auto info) { | |
std::as_const(registry).storage(info)->copy_to(other); | |
}); | |
for(const auto entity: registry.view<B>()) { | |
std::cout << entt::to_integral(entity); | |
if (registry.any_of<B>(entity)) { | |
std::cout << " registry: " << registry.get<B>(entity).x; | |
} | |
if (other.valid(entity)) { | |
std::cout << " other: "; | |
if (other.any_of<B>(entity)) { | |
std::cout << other.get<B>(entity).x; | |
} | |
} | |
std::cout << "\n"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment