sparse_set:

* opaque emplace returns bool
* opaque insert returnes the number of entities actually emplaced
This commit is contained in:
Michele Caini
2021-12-26 17:04:10 +01:00
parent 40aabe76c7
commit be87191d0a
5 changed files with 56 additions and 37 deletions

View File

@@ -661,10 +661,11 @@ public:
*
* @param entt A valid identifier.
* @param value Optional opaque value to forward to mixins, if any.
* @return True in case of success, false otherwise.
*/
void emplace(const entity_type entt, const void *value = nullptr) {
bool emplace(const entity_type entt, const void *value = nullptr) {
try_emplace(entt, value);
ENTT_ASSERT(contains(entt), "Emplace did not take place");
return contains(entt);
}
/**
@@ -677,18 +678,23 @@ public:
* @tparam It Type of input iterator.
* @param first An iterator to the first element of the range of entities.
* @param last An iterator past the last element of the range of entities.
* @return Number of entities actually assigned to the sparse set.
*/
template<typename It>
void insert(It first, It last) {
size_type insert(It first, It last) {
size_type count{};
for(; first != last && free_list != null; ++first) {
emplace(*first);
count += emplace(*first);
}
reserve(packed.size() + std::distance(first, last));
for(; first != last; ++first) {
emplace(*first);
count += emplace(*first);
}
return count;
}
/**
@@ -740,13 +746,13 @@ public:
*/
template<typename It>
size_type remove(It first, It last) {
size_type found{};
size_type count{};
for(; first != last; ++first) {
found += remove(*first);
count += remove(*first);
}
return found;
return count;
}
/*! @brief Removes all tombstones from the packed array of a sparse set. */

View File

@@ -950,7 +950,10 @@ class sigh_storage_mixin final: public Type {
void try_emplace(const typename Type::entity_type entt, const void *value) final {
ENTT_ASSERT(owner != nullptr, "Invalid pointer to registry");
Type::try_emplace(entt, value);
construction.publish(*owner, entt);
if(Type::contains(entt)) {
construction.publish(*owner, entt);
}
}
public:

View File

@@ -47,7 +47,8 @@ TEST(SighStorageMixin, GenericType) {
pool.on_construct().connect<&listener>(on_construct);
pool.on_destroy().connect<&listener>(on_destroy);
base.emplace(entities[0u]);
ASSERT_TRUE(base.emplace(entities[0u]));
pool.emplace(entities[1u]);
ASSERT_EQ(on_construct.value, 2);
@@ -64,7 +65,7 @@ TEST(SighStorageMixin, GenericType) {
ASSERT_EQ(on_destroy.value, 2);
ASSERT_TRUE(pool.empty());
base.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
ASSERT_EQ(pool.get(entities[0u]), 0);
ASSERT_EQ(pool.get(entities[1u]), 0);
@@ -112,7 +113,8 @@ TEST(SighStorageMixin, EmptyType) {
pool.on_construct().connect<&listener>(on_construct);
pool.on_destroy().connect<&listener>(on_destroy);
base.emplace(entities[0u]);
ASSERT_TRUE(base.emplace(entities[0u]));
pool.emplace(entities[1u]);
ASSERT_EQ(on_construct.value, 2);
@@ -129,7 +131,7 @@ TEST(SighStorageMixin, EmptyType) {
ASSERT_EQ(on_destroy.value, 2);
ASSERT_TRUE(pool.empty());
base.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_TRUE(pool.contains(entities[1u]));
@@ -177,7 +179,7 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) {
pool.on_construct().connect<&listener>(on_construct);
pool.on_destroy().connect<&listener>(on_destroy);
ASSERT_DEATH(base.emplace(entities[0u]), "");
ASSERT_FALSE(base.emplace(entities[0u]));
pool.emplace(entities[1u], 3);
@@ -194,7 +196,7 @@ TEST(SighStorageMixin, NonDefaultConstructibleType) {
ASSERT_EQ(on_destroy.value, 1);
ASSERT_TRUE(pool.empty());
ASSERT_DEATH(base.insert(std::begin(entities), std::end(entities)), "");
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 0u);
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));

View File

@@ -263,12 +263,12 @@ TEST(SparseSet, Emplace) {
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
ASSERT_TRUE(set.empty());
ASSERT_TRUE(set.emplace(entities[0u]));
set.emplace(entities[0u]);
set.erase(entities[0u]);
set.emplace(entities[1u]);
set.emplace(entities[0u]);
ASSERT_TRUE(set.emplace(entities[1u]));
ASSERT_TRUE(set.emplace(entities[0u]));
ASSERT_DEATH(set.emplace(traits_type::combine(3, 1)), "");
ASSERT_DEATH(set.emplace(entities[1u]), "");
@@ -279,8 +279,9 @@ TEST(SparseSet, Emplace) {
ASSERT_EQ(set.index(entities[1u]), 0u);
set.erase(std::begin(entities), std::end(entities));
set.emplace(entities[1u]);
set.emplace(entities[0u]);
ASSERT_TRUE(set.emplace(entities[1u]));
ASSERT_TRUE(set.emplace(entities[0u]));
ASSERT_EQ(set.at(0u), entities[1u]);
ASSERT_EQ(set.at(1u), entities[0u]);
@@ -292,14 +293,13 @@ TEST(SparseSet, EmplaceOutOfBounds) {
entt::sparse_set set{entt::deletion_policy::in_place};
entt::entity entities[2u]{entt::entity{0}, entt::entity{ENTT_SPARSE_PAGE}};
set.emplace(entities[0u]);
ASSERT_TRUE(set.emplace(entities[0u]));
ASSERT_EQ(set.extent(), ENTT_SPARSE_PAGE);
ASSERT_EQ(set.index(entities[0u]), 0u);
set.erase(entities[0u]);
set.emplace(entities[1u]);
ASSERT_TRUE(set.emplace(entities[1u]));
ASSERT_EQ(set.extent(), 2u * ENTT_SPARSE_PAGE);
ASSERT_EQ(set.index(entities[1u]), 0u);
}
@@ -309,8 +309,10 @@ TEST(SparseSet, Insert) {
entt::entity entities[2u]{entt::entity{3}, entt::entity{42}};
set.emplace(entt::entity{12});
set.insert(std::end(entities), std::end(entities));
set.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(set.insert(std::end(entities), std::end(entities)), 0u);
ASSERT_EQ(set.insert(std::begin(entities), std::end(entities)), 2u);
set.emplace(entt::entity{24});
ASSERT_TRUE(set.contains(entities[0u]));
@@ -332,7 +334,8 @@ TEST(SparseSet, Insert) {
ASSERT_EQ(set.data()[set.index(entt::entity{24})], entt::entity{24});
set.erase(std::begin(entities), std::end(entities));
set.insert(std::rbegin(entities), std::rend(entities));
ASSERT_EQ(set.insert(std::rbegin(entities), std::rend(entities)), 2u);
ASSERT_EQ(set.size(), 4u);
ASSERT_EQ(set.at(1u), entities[0u]);

View File

@@ -592,7 +592,8 @@ TEST(Storage, TypeFromBase) {
ASSERT_FALSE(pool.contains(entities[1u]));
int instance = 42;
base.emplace(entities[0u], &instance);
ASSERT_TRUE(base.emplace(entities[0u], &instance));
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -600,7 +601,8 @@ TEST(Storage, TypeFromBase) {
ASSERT_EQ(pool.get(entities[0u]), 42);
base.erase(entities[0u]);
base.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_TRUE(pool.contains(entities[1u]));
@@ -624,14 +626,16 @@ TEST(Storage, EmptyTypeFromBase) {
ASSERT_FALSE(pool.contains(entities[1u]));
empty_stable_type instance{};
base.emplace(entities[0u], &instance);
ASSERT_TRUE(base.emplace(entities[0u], &instance));
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
ASSERT_EQ(base.get(entities[0u]), nullptr);
base.erase(entities[0u]);
base.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_TRUE(pool.contains(entities[1u]));
@@ -655,7 +659,7 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
ASSERT_DEATH(base.emplace(entities[0u]), "");
ASSERT_FALSE(base.emplace(entities[0u]));
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -663,7 +667,8 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
ASSERT_TRUE(pool.empty());
non_default_constructible instance{3};
base.emplace(entities[0u], &instance);
ASSERT_TRUE(base.emplace(entities[0u], &instance));
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -673,7 +678,7 @@ TEST(Storage, NonDefaultConstructibleTypeFromBase) {
ASSERT_TRUE(pool.empty());
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_DEATH(base.insert(std::begin(entities), std::end(entities)), "");
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 0u);
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -693,7 +698,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
ASSERT_FALSE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
base.emplace(entities[0u]);
ASSERT_TRUE(base.emplace(entities[0u]));
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -702,7 +707,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
std::unique_ptr<int> instance = std::make_unique<int>(3);
ASSERT_DEATH(base.emplace(entities[1u], &instance), "");
ASSERT_FALSE(base.emplace(entities[1u], &instance));
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_FALSE(pool.contains(entities[1u]));
@@ -712,7 +717,7 @@ TEST(Storage, NonCopyConstructibleTypeFromBase) {
ASSERT_TRUE(pool.empty());
ASSERT_FALSE(pool.contains(entities[0u]));
base.insert(std::begin(entities), std::end(entities));
ASSERT_EQ(base.insert(std::begin(entities), std::end(entities)), 2u);
ASSERT_TRUE(pool.contains(entities[0u]));
ASSERT_TRUE(pool.contains(entities[1u]));
@@ -1119,7 +1124,7 @@ TEST(Storage, IterableIteratorConversion) {
typename entt::storage<boxed_int>::iterable::iterator it = pool.each().begin();
typename entt::storage<boxed_int>::const_iterable::const_iterator cit = it;
static_assert(std::is_same_v<decltype(*it), std::tuple<entt::entity, boxed_int &>>);
static_assert(std::is_same_v<decltype(*cit), std::tuple<entt::entity, const boxed_int &>>);