Browse Source

sparse_set/storage: opaque get from base

Michele Caini 4 years ago
parent
commit
dfb5fe1e04

+ 28 - 0
src/entt/entity/sparse_set.hpp

@@ -196,6 +196,14 @@ class basic_sparse_set {
     }
 
 protected:
+    /**
+     * @brief Returns the element assigned to an entity.
+     * @return An opaque pointer to the element assigned to the entity.
+     */
+    virtual const void *get_at(const std::size_t) const ENTT_NOEXCEPT {
+        return nullptr;
+    }
+
     /*! @brief Swaps two entities in a sparse set. */
     virtual void swap_at(const std::size_t, const std::size_t) {}
 
@@ -591,6 +599,26 @@ public:
         return packed[pos];
     }
 
+    /**
+     * @brief Returns the element assigned to an entity, if any.
+     *
+     * @warning
+     * Attempting to use an entity that doesn't belong to the sparse set results
+     * in undefined behavior.
+     *
+     * @param entt A valid identifier.
+     * @return An opaque pointer to the element assigned to the entity, if any.
+     */
+    const void *get(const entity_type entt) const ENTT_NOEXCEPT {
+        ENTT_ASSERT(contains(entt), "Set does not contain entity");
+        return get_at(index(entt));
+    }
+
+    /*! @copydoc get */
+    void *get(const entity_type entt) ENTT_NOEXCEPT {
+        return const_cast<void *>(std::as_const(*this).get(entt));
+    }
+
     /**
      * @brief Assigns an entity to a sparse set.
      *

+ 9 - 0
src/entt/entity/storage.hpp

@@ -284,6 +284,15 @@ class basic_storage: public basic_sparse_set<Entity, typename std::allocator_tra
     }
 
 protected:
+    /**
+     * @brief Returns the element assigned to an entity.
+     * @param pos A valid position of an element within a storage.
+     * @return An opaque pointer to the element assigned to the entity.
+     */
+    const void *get_at(const std::size_t pos) const ENTT_NOEXCEPT override {
+        return std::addressof(element_at(pos));
+    }
+
     /**
      * @brief Swaps two elements in a storage.
      * @param lhs A valid position of an element within a storage.

+ 3 - 0
test/entt/entity/sparse_set.cpp

@@ -49,6 +49,9 @@ TEST(SparseSet, Functionalities) {
     ASSERT_EQ(set.at(1u), static_cast<entt::entity>(entt::null));
     ASSERT_EQ(set[0u], entt::entity{42});
 
+    ASSERT_DEATH(set.get(entt::entity{0}), "");
+    ASSERT_EQ(set.get(entt::entity{42}), nullptr);
+
     set.erase(entt::entity{42});
 
     ASSERT_TRUE(set.empty());

+ 2 - 0
test/entt/entity/storage.cpp

@@ -596,6 +596,7 @@ TEST(Storage, TypeFromBase) {
 
     ASSERT_TRUE(pool.contains(entities[0u]));
     ASSERT_FALSE(pool.contains(entities[1u]));
+    ASSERT_EQ(base.get(entities[0u]), &pool.get(entities[0u]));
     ASSERT_EQ(pool.get(entities[0u]), 42);
 
     base.erase(entities[0u]);
@@ -627,6 +628,7 @@ TEST(Storage, EmptyTypeFromBase) {
 
     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));