registry: only opaque stamp is allowed, use assign/assign_or_replace for components

This commit is contained in:
Michele Caini
2020-01-11 01:23:57 +01:00
parent 352e4576fc
commit 7ba14f5a57
3 changed files with 12 additions and 39 deletions

1
TODO
View File

@@ -14,7 +14,6 @@
* observer: user defined filters (eg .replace<T, &function> or .group<T, U, &func>)
* use underlying_type as entity type within pools and registry? it would make different registries work together flawlessy
* can we write a bool conv func for entt::entity that silently compares it to null?
* stamp makes sense only when the list of components is empty
* reset... reset everywhere...
* document undocumented parts (entt::overload and a few others)
* any-of rule for views/groups (eg entity has A and any of B/C/D)

View File

@@ -1458,44 +1458,32 @@ public:
/**
* @brief Stamps an entity onto another entity.
*
* The components must be copyable for obvious reasons. The entities
* must be both valid.<br/>
* If no components are provided, the registry will try to copy all the
* existing types. The non-copyable ones will be ignored.
*
* This feature supports exclusion lists as an alternative to component
* lists. An excluded type will never be copied.
* This function supports exclusion lists. An excluded type will never be
* copied.
*
* @warning
* Attempting to copy components that aren't copyable results in unexpected
* behaviors.<br/>
* A static assertion will abort the compilation when the components
* provided aren't copy constructible. Otherwise, an assertion will abort
* the execution at runtime in debug mode in case one or more types cannot
* be copied.
* An assertion will abort the execution at runtime in debug mode in case
* one or more types cannot be copied.
*
* @warning
* Attempting to use invalid entities results in undefined behavior.<br/>
* An assertion will abort the execution at runtime in debug mode in case of
* invalid entities.
*
* @tparam Component Types of components to copy.
* @tparam Exclude Types of components not to be copied.
* @param dst A valid entity identifier to copy to.
* @param other The registry that owns the source entity.
* @param src A valid entity identifier to be copied.
*/
template<typename... Component, typename... Exclude>
template<typename... Exclude>
void stamp(const entity_type dst, const basic_registry &other, const entity_type src, exclude_t<Exclude...> = {}) {
if constexpr(sizeof...(Component) == 0) {
for(size_type pos{}; pos < other.pools.size(); ++pos) {
if(const auto &pdata = other.pools[pos]; pdata.stamp && ((pdata.type_id != type_info<Exclude>::id()) && ...) && pdata.pool->has(src)) {
pdata.stamp(*this, dst, *pdata.pool, src);
}
for(size_type pos{}; pos < other.pools.size(); ++pos) {
if(const auto &pdata = other.pools[pos]; ((pdata.type_id != type_info<Exclude>::id()) && ...) && pdata.pool->has(src)) {
ENTT_ASSERT(pdata.stamp);
pdata.stamp(*this, dst, *pdata.pool, src);
}
} else {
static_assert(sizeof...(Exclude) == 0 && std::conjunction_v<std::is_copy_constructible<Component>...>);
(assign_or_replace<Component>(dst, other.template get<Component>(src)), ...);
}
}

View File

@@ -1460,7 +1460,7 @@ TEST(Registry, Stamp) {
registry.assign<char>(prototype, 'c');
auto entity = registry.create();
registry.stamp<int, char>(entity, registry, prototype);
registry.stamp(entity, registry, prototype);
ASSERT_TRUE((registry.has<int, char>(entity)));
ASSERT_EQ(registry.get<int>(entity), 3);
@@ -1468,10 +1468,10 @@ TEST(Registry, Stamp) {
registry.replace<int>(prototype, 42);
registry.replace<char>(prototype, 'a');
registry.stamp<int>(entity, registry, prototype);
registry.stamp(entity, registry, prototype);
ASSERT_EQ(registry.get<int>(entity), 42);
ASSERT_EQ(registry.get<char>(entity), 'c');
ASSERT_EQ(registry.get<char>(entity), 'a');
}
TEST(Registry, StampExclude) {
@@ -1502,20 +1502,6 @@ TEST(Registry, StampExclude) {
ASSERT_TRUE(registry.orphan(entity));
}
TEST(Registry, StampMoveOnlyComponent) {
entt::registry registry;
const auto prototype = registry.create();
registry.assign<std::unique_ptr<int>>(prototype);
registry.assign<char>(prototype);
const auto entity = registry.create();
registry.stamp(entity, registry, prototype);
ASSERT_TRUE(registry.has<char>(entity));
ASSERT_FALSE(registry.has<std::unique_ptr<int>>(entity));
}
TEST(Registry, GetOrAssign) {
entt::registry registry;
const auto entity = registry.create();