Jelajahi Sumber

prepare view for exclusion list

Michele Caini 6 tahun lalu
induk
melakukan
cd108b5f57

+ 2 - 2
src/entt/entity/fwd.hpp

@@ -14,7 +14,7 @@ template <typename>
 class basic_registry;
 
 /*! @class basic_view */
-template<typename, typename...>
+template<typename...>
 class basic_view;
 
 /*! @class basic_runtime_view */
@@ -71,7 +71,7 @@ using continuous_loader = basic_continuous_loader<entity>;
 
 /**
  * @brief Alias declaration for the most common use case.
- * @tparam Component Types of components iterated by the view.
+ * @tparam Types Types of components iterated by the group.
  */
 template<typename... Types>
 using view = basic_view<entity, Types...>;

+ 4 - 3
src/entt/entity/helper.hpp

@@ -29,12 +29,13 @@ struct as_view {
 
     /**
      * @brief Conversion function from a registry to a view.
+     * @tparam Exclude Types of components used to filter the view.
      * @tparam Component Type of components used to construct the view.
      * @return A newly created view.
      */
-    template<typename... Component>
-    operator entt::basic_view<Entity, Component...>() const {
-        return reg.template view<Component...>();
+    template<typename Exclude, typename... Component>
+    operator entt::basic_view<Entity, Exclude, Component...>() const {
+        return reg.template view<Component...>(Exclude{});
     }
 
 private:

+ 5 - 4
src/entt/entity/registry.hpp

@@ -1302,16 +1302,17 @@ public:
      * To get a performance boost, consider using a group instead.
      *
      * @tparam Component Type of components used to construct the view.
+     * @tparam Exclude Types of components used to filter the view.
      * @return A newly created view.
      */
-    template<typename... Component>
-    entt::basic_view<Entity, Component...> view() {
+    template<typename... Component, typename... Exclude>
+    entt::basic_view<Entity, exclude_t<Exclude...>, Component...> view(exclude_t<Exclude...> = {}) {
         return { assure<Component>()... };
     }
 
     /*! @copydoc view */
-    template<typename... Component>
-    entt::basic_view<Entity, Component...> view() const {
+    template<typename... Component, typename... Exclude>
+    entt::basic_view<Entity, exclude_t<Exclude...>, Component...> view(exclude_t<Exclude...> = {}) const {
         static_assert(std::conjunction_v<std::is_const<Component>...>);
         return const_cast<basic_registry *>(this)->view<Component...>();
     }

+ 18 - 8
src/entt/entity/view.hpp

@@ -12,6 +12,7 @@
 #include "../core/type_traits.hpp"
 #include "sparse_set.hpp"
 #include "storage.hpp"
+#include "utility.hpp"
 #include "entity.hpp"
 #include "fwd.hpp"
 
@@ -19,6 +20,16 @@
 namespace entt {
 
 
+/**
+ * @brief View.
+ *
+ * Primary template isn't defined on purpose. All the specializations give a
+ * compile-time error, but for a few reasonable cases.
+ */
+template<typename...>
+class basic_view;
+
+
 /**
  * @brief Multi component view.
  *
@@ -28,8 +39,7 @@ namespace entt {
  * reference to the smallest set of candidate entities in order to get a
  * performance boost when iterate.<br/>
  * Order of elements during iterations are highly dependent on the order of the
- * underlying data structures. See sparse_set and its specializations for more
- * details.
+ * underlying data structures. See sparse_set for more details.
  *
  * @b Important
  *
@@ -54,10 +64,11 @@ namespace entt {
  * In any other case, attempting to use a view results in undefined behavior.
  *
  * @tparam Entity A valid entity type (see entt_traits for more details).
+ * @tparam Exclude Types of components used to filter the view.
  * @tparam Component Types of components iterated by the view.
  */
-template<typename Entity, typename... Component>
-class basic_view {
+template<typename Entity, typename... Exclude, typename... Component>
+class basic_view<Entity, exclude_t<Exclude...>, Component...> {
     static_assert(sizeof...(Component) > 1);
 
     /*! @brief A registry is allowed to create views. */
@@ -74,7 +85,7 @@ class basic_view {
     using traits_type = entt_traits<std::underlying_type_t<Entity>>;
 
     class iterator {
-        friend class basic_view<Entity, Component...>;
+        friend class basic_view<Entity, exclude_t<Exclude...>, Component...>;
 
         iterator(unchecked_type other, underlying_iterator_type first, underlying_iterator_type last) ENTT_NOEXCEPT
             : unchecked{other},
@@ -499,8 +510,7 @@ private:
  * performance. This kind of views can access the underlying data structure
  * directly and avoid superfluous checks.<br/>
  * Order of elements during iterations are highly dependent on the order of the
- * underlying data structure. See sparse_set and its specializations for more
- * details.
+ * underlying data structure. See sparse_set for more details.
  *
  * @b Important
  *
@@ -527,7 +537,7 @@ private:
  * @tparam Component Type of component iterated by the view.
  */
 template<typename Entity, typename Component>
-class basic_view<Entity, Component> {
+class basic_view<Entity, exclude_t<>, Component> {
     /*! @brief A registry is allowed to create views. */
     friend class basic_registry<Entity>;
 

+ 5 - 3
test/entt/entity/helper.cpp

@@ -8,9 +8,11 @@ TEST(Helper, AsView) {
     entt::registry registry;
     const entt::registry cregistry;
 
-    ([](entt::view<int, char>) {})(entt::as_view{registry});
-    ([](entt::view<const int, char>) {})(entt::as_view{registry});
-    ([](entt::view<const double>) {})(entt::as_view{cregistry});
+    ([](entt::view<entt::exclude_t<>, int>) {})(entt::as_view{registry});
+    ([](entt::view<entt::exclude_t<int>, char, double>) {})(entt::as_view{registry});
+    ([](entt::view<entt::exclude_t<const int>, char, double>) {})(entt::as_view{registry});
+    ([](entt::view<entt::exclude_t<const int>, const char, double>) {})(entt::as_view{registry});
+    ([](entt::view<entt::exclude_t<const int>, const char, const double>) {})(entt::as_view{registry});
 }
 
 TEST(Helper, AsGroup) {