storage: add get/get_as_tuple to entity storage to make it suitable for use with views

This commit is contained in:
Michele Caini
2023-01-31 17:23:42 +01:00
parent f48de1bac9
commit c0762a6a5a
3 changed files with 65 additions and 19 deletions

3
TODO
View File

@@ -20,9 +20,8 @@ TODO (high prio):
* improve sigh mixin for entity storage (split basic + entt/entt spec)
* doc: exclude only views, storage entity, bump entities
* deprecate/remove registry reserve, capacity, empty, data, destroyed, release and so on
* prepare to turn sparse set begin/end into virtual functions
* refine views and groups to use scoped iterators from entity storage and the like
* use sparse_set free_list to replace entity storage length and return narrow iterators
* use entity as value_type for entity storage, define begin/end as scoped iterators
* test exclude-only views
WIP:

View File

@@ -949,7 +949,7 @@ protected:
if(const auto pos = base_type::index(*first); pos < length) {
base_type::bump(local_traits_type::next(*first));
if (pos != --length) {
if(pos != --length) {
base_type::swap_at(pos, length);
}
}
@@ -1031,6 +1031,34 @@ public:
return *this;
}
/**
* @brief Returns the object assigned to an entity, that is `void`.
*
* @warning
* Attempting to use an entity that doesn't belong to the storage results in
* undefined behavior.
*
* @param entt A valid identifier.
*/
void get([[maybe_unused]] const entity_type entt) const noexcept {
ENTT_ASSERT(base_type::index(entt) < length, "The requested entity is not a live one");
}
/**
* @brief Returns an empty tuple.
*
* @warning
* Attempting to use an entity that doesn't belong to the storage results in
* undefined behavior.
*
* @param entt A valid identifier.
* @return Returns an empty tuple.
*/
[[nodiscard]] std::tuple<> get_as_tuple([[maybe_unused]] const entity_type entt) const noexcept {
ENTT_ASSERT(base_type::index(entt) < length, "The requested entity is not a live one");
return std::tuple{};
}
/**
* @brief Exchanges the contents with those of a given storage.
* @param other Storage to exchange the content with.
@@ -1121,22 +1149,6 @@ public:
return (length - len);
}
/**
* @brief Returns an iterable object to use to _visit_ a storage.
*
* The iterable object returns a tuple that contains the current entity.
*
* @return An iterable object to use to _visit_ the storage.
*/
[[nodiscard]] iterable each() noexcept {
return {internal::extended_storage_iterator{base_type::end() - length}, internal::extended_storage_iterator{base_type::end()}};
}
/*! @copydoc each */
[[nodiscard]] const_iterable each() const noexcept {
return {internal::extended_storage_iterator{base_type::cend() - length}, internal::extended_storage_iterator{base_type::cend()}};
}
/**
* @brief Returns the number of elements considered still in use.
* @return The number of elements considered still in use.
@@ -1154,6 +1166,22 @@ public:
length = len;
}
/**
* @brief Returns an iterable object to use to _visit_ a storage.
*
* The iterable object returns a tuple that contains the current entity.
*
* @return An iterable object to use to _visit_ the storage.
*/
[[nodiscard]] iterable each() noexcept {
return {internal::extended_storage_iterator{base_type::end() - length}, internal::extended_storage_iterator{base_type::end()}};
}
/*! @copydoc each */
[[nodiscard]] const_iterable each() const noexcept {
return {internal::extended_storage_iterator{base_type::cend() - length}, internal::extended_storage_iterator{base_type::cend()}};
}
private:
size_type length;
};

View File

@@ -33,6 +33,9 @@ TEST(StorageEntity, Functionalities) {
ASSERT_EQ(pool.size(), 2u);
ASSERT_EQ(pool.in_use(), 1u);
ASSERT_NO_THROW(pool.get(entities[0u]));
ASSERT_EQ(pool.get_as_tuple(entities[0u]), std::tuple<>{});
pool.erase(entities[0u]);
ASSERT_FALSE(pool.empty());
@@ -40,6 +43,22 @@ TEST(StorageEntity, Functionalities) {
ASSERT_EQ(pool.in_use(), 0u);
}
ENTT_DEBUG_TEST(StorageEntityDeathTest, Get) {
entt::storage<entt::entity> pool;
pool.spawn(entt::entity{99});
ASSERT_DEATH(pool.get(entt::entity{3}), "");
ASSERT_DEATH([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{3}), "");
ASSERT_NO_THROW(pool.get(entt::entity{99}));
ASSERT_NO_THROW([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{99}));
pool.erase(entt::entity{99});
ASSERT_DEATH(pool.get(entt::entity{99}), "");
ASSERT_DEATH([[maybe_unused]] auto tup = pool.get_as_tuple(entt::entity{99}), "");
}
TEST(StorageEntity, Move) {
using traits_type = entt::entt_traits<entt::entity>;