1
0
Эх сурвалжийг харах

added find functionality to sparse sets/views

Michele Caini 7 жил өмнө
parent
commit
7e3abb27a4

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

@@ -298,6 +298,16 @@ public:
         return iterator_type{&direct, {}};
     }
 
+    /**
+     * @brief Finds an entity.
+     * @param entity A valid entity identifier.
+     * @return An iterator to the given entity if it's found, past the end
+     * iterator otherwise.
+     */
+    iterator_type find(const entity_type entity) const ENTT_NOEXCEPT {
+        return has(entity) ? --(end() - get(entity)) : end();
+    }
+
     /**
      * @brief Checks if a sparse set contains an entity.
      * @param entity A valid entity identifier.

+ 32 - 0
src/entt/entity/view.hpp

@@ -195,6 +195,16 @@ public:
         return handler->view_type::end();
     }
 
+    /**
+     * @brief Finds an entity.
+     * @param entity A valid entity identifier.
+     * @return An iterator to the given entity if it's found, past the end
+     * iterator otherwise.
+     */
+    iterator_type find(const entity_type entity) const ENTT_NOEXCEPT {
+        return handler->view_type::find(entity);
+    }
+
     /**
      * @brief Returns the identifier that occupies the given position.
      * @param pos Position of the element to return.
@@ -558,6 +568,18 @@ public:
         return iterator_type{unchecked(view), view->end(), view->end()};
     }
 
+    /**
+     * @brief Finds an entity.
+     * @param entity A valid entity identifier.
+     * @return An iterator to the given entity if it's found, past the end
+     * iterator otherwise.
+     */
+    iterator_type find(const entity_type entity) const ENTT_NOEXCEPT {
+        const auto *view = candidate();
+        iterator_type it{unchecked(view), view->find(entity), view->end()};
+        return (it != end() && *it == entity) ? it : end();
+    }
+
     /**
      * @brief Checks if a view contains an entity.
      * @param entity A valid entity identifier.
@@ -781,6 +803,16 @@ public:
         return pool->view_type::end();
     }
 
+    /**
+     * @brief Finds an entity.
+     * @param entity A valid entity identifier.
+     * @return An iterator to the given entity if it's found, past the end
+     * iterator otherwise.
+     */
+    iterator_type find(const entity_type entity) const ENTT_NOEXCEPT {
+        return pool->view_type::find(entity);
+    }
+
     /**
      * @brief Returns the identifier that occupies the given position.
      * @param pos Position of the element to return.

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

@@ -101,6 +101,26 @@ TEST(SparseSetNoType, Iterator) {
     ASSERT_EQ(*begin.operator->(), 3);
 }
 
+TEST(SparseSetNoType, Find) {
+    entt::sparse_set<std::uint64_t> set;
+    set.construct(3);
+    set.construct(42);
+    set.construct(99);
+
+    ASSERT_NE(set.find(3), set.end());
+    ASSERT_NE(set.find(42), set.end());
+    ASSERT_NE(set.find(99), set.end());
+    ASSERT_EQ(set.find(0), set.end());
+
+    auto it = set.find(99);
+
+    ASSERT_EQ(*it, 99);
+    ASSERT_EQ(*(++it), 42);
+    ASSERT_EQ(*(++it), 3);
+    ASSERT_EQ(++it, set.end());
+    ASSERT_EQ(++set.find(3), set.end());
+}
+
 TEST(SparseSetNoType, Data) {
     entt::sparse_set<std::uint64_t> set;
 

+ 104 - 0
test/entt/entity/view.cpp

@@ -215,6 +215,42 @@ TEST(PersistentView, ConstNonConstAndAllInBetween) {
     });
 }
 
+TEST(PersistentView, Find) {
+    entt::registry<> registry;
+    auto view = registry.persistent_view<int, const char>();
+
+    const auto e0 = registry.create();
+    registry.assign<int>(e0);
+    registry.assign<char>(e0);
+
+    const auto e1 = registry.create();
+    registry.assign<int>(e1);
+    registry.assign<char>(e1);
+
+    const auto e2 = registry.create();
+    registry.assign<int>(e2);
+    registry.assign<char>(e2);
+
+    const auto e3 = registry.create();
+    registry.assign<int>(e3);
+    registry.assign<char>(e3);
+
+    registry.remove<int>(e1);
+
+    ASSERT_NE(view.find(e0), view.end());
+    ASSERT_EQ(view.find(e1), view.end());
+    ASSERT_NE(view.find(e2), view.end());
+    ASSERT_NE(view.find(e3), view.end());
+
+    auto it = view.find(e2);
+
+    ASSERT_EQ(*it, e2);
+    ASSERT_EQ(*(++it), e3);
+    ASSERT_EQ(*(++it), e0);
+    ASSERT_EQ(++it, view.end());
+    ASSERT_EQ(++view.find(e0), view.end());
+}
+
 TEST(SingleComponentView, Functionalities) {
     entt::registry<> registry;
     auto view = registry.view<char>();
@@ -355,6 +391,38 @@ TEST(SingleComponentView, ConstNonConstAndAllInBetween) {
     });
 }
 
+TEST(SingleComponentView, Find) {
+    entt::registry<> registry;
+    auto view = registry.view<int>();
+
+    const auto e0 = registry.create();
+    registry.assign<int>(e0);
+
+    const auto e1 = registry.create();
+    registry.assign<int>(e1);
+
+    const auto e2 = registry.create();
+    registry.assign<int>(e2);
+
+    const auto e3 = registry.create();
+    registry.assign<int>(e3);
+
+    registry.remove<int>(e1);
+
+    ASSERT_NE(view.find(e0), view.end());
+    ASSERT_EQ(view.find(e1), view.end());
+    ASSERT_NE(view.find(e2), view.end());
+    ASSERT_NE(view.find(e3), view.end());
+
+    auto it = view.find(e2);
+
+    ASSERT_EQ(*it, e2);
+    ASSERT_EQ(*(++it), e3);
+    ASSERT_EQ(*(++it), e0);
+    ASSERT_EQ(++it, view.end());
+    ASSERT_EQ(++view.find(e0), view.end());
+}
+
 TEST(MultipleComponentView, Functionalities) {
     entt::registry<> registry;
     auto view = registry.view<int, char>();
@@ -521,6 +589,42 @@ TEST(MultipleComponentView, ConstNonConstAndAllInBetween) {
     });
 }
 
+TEST(MultipleComponentView, Find) {
+    entt::registry<> registry;
+    auto view = registry.view<int, const char>();
+
+    const auto e0 = registry.create();
+    registry.assign<int>(e0);
+    registry.assign<char>(e0);
+
+    const auto e1 = registry.create();
+    registry.assign<int>(e1);
+    registry.assign<char>(e1);
+
+    const auto e2 = registry.create();
+    registry.assign<int>(e2);
+    registry.assign<char>(e2);
+
+    const auto e3 = registry.create();
+    registry.assign<int>(e3);
+    registry.assign<char>(e3);
+
+    registry.remove<int>(e1);
+
+    ASSERT_NE(view.find(e0), view.end());
+    ASSERT_EQ(view.find(e1), view.end());
+    ASSERT_NE(view.find(e2), view.end());
+    ASSERT_NE(view.find(e3), view.end());
+
+    auto it = view.find(e2);
+
+    ASSERT_EQ(*it, e2);
+    ASSERT_EQ(*(++it), e3);
+    ASSERT_EQ(*(++it), e0);
+    ASSERT_EQ(++it, view.end());
+    ASSERT_EQ(++view.find(e0), view.end());
+}
+
 TEST(RawView, Functionalities) {
     entt::registry<> registry;
     auto view = registry.raw_view<char>();