Browse Source

view: refine fallback mechanism (with non-regression lib tests)

Michele Caini 1 year ago
parent
commit
3ae5cbbc3a

+ 0 - 1
TODO

@@ -36,7 +36,6 @@ TODO:
 * view specializations for multi, single and filtered elements
 * organizer support to groups
 * meta range: move id to meta objects and return plain types (?), then remove id from meta base and meta ctor too
-* refine the storage fallback mechanism for views (ie alloc?)
 * don't pass reactive storage by default to callback
 * runtime types support for meta for types that aren't backed by C++ types
 * dtor, traits and custom should be part of meta descriptor (update meta_factory tests then)

+ 6 - 5
src/entt/entity/view.hpp

@@ -41,8 +41,8 @@ template<typename It, typename Entity>
 }
 
 template<typename It>
-[[nodiscard]] bool fully_initialized(It first, const It last) noexcept {
-    for(const auto *placeholder = view_placeholder<std::remove_const_t<std::remove_pointer_t<typename std::iterator_traits<It>::value_type>>>(); (first != last) && *first != placeholder; ++first) {}
+[[nodiscard]] bool fully_initialized(It first, const It last, const std::remove_pointer_t<typename std::iterator_traits<It>::value_type> *placeholder) noexcept {
+    for(; (first != last) && *first != placeholder; ++first) {}
     return first == last;
 }
 
@@ -255,7 +255,7 @@ protected:
     /*! @cond TURN_OFF_DOXYGEN */
     basic_common_view() noexcept {
         for(size_type pos{}; pos < Exclude; ++pos) {
-            filter[pos] = internal::view_placeholder<Type>();
+            filter[pos] = placeholder;
         }
     }
 
@@ -277,7 +277,7 @@ protected:
     }
 
     [[nodiscard]] const Type *filter_at(const std::size_t pos) const noexcept {
-        return (filter[pos] == internal::view_placeholder<Type>()) ? nullptr : filter[pos];
+        return (filter[pos] == placeholder) ? nullptr : filter[pos];
     }
 
     void filter_at(const std::size_t pos, const Type *elem) noexcept {
@@ -390,7 +390,7 @@ public:
      * @return True if the view is fully initialized, false otherwise.
      */
     [[nodiscard]] explicit operator bool() const noexcept {
-        return (index != Get) && internal::fully_initialized(filter.begin(), filter.end());
+        return (index != Get) && internal::fully_initialized(filter.begin(), filter.end(), placeholder);
     }
 
     /**
@@ -408,6 +408,7 @@ public:
 private:
     std::array<const common_type *, Get> pools{};
     std::array<const common_type *, Exclude> filter{};
+    const common_type *placeholder{internal::view_placeholder<common_type>()};
     size_type index{Get};
 };
 

+ 12 - 1
test/lib/view/plugin/main.cpp

@@ -2,7 +2,18 @@
 
 #include <gtest/gtest.h>
 #include <cr.h>
+#include "../types.h"
 
 TEST(Lib, View) {
-	// TODO
+    view_type view{};
+
+    cr_plugin ctx;
+    cr_plugin_load(ctx, PLUGIN);
+
+    ctx.userdata = &view;
+    cr_plugin_update(ctx);
+
+    ASSERT_EQ(ctx.userdata, nullptr);
+
+    cr_plugin_close(ctx);
 }

+ 14 - 1
test/lib/view/plugin/plugin.cpp

@@ -1,6 +1,19 @@
 #include <cr.h>
+#include "../types.h"
 
 CR_EXPORT int cr_main(cr_plugin *ctx, cr_op operation) {
-    // TODO
+    switch(operation) {
+    case CR_STEP: {
+        // unset filter fallback should not be accessible across boundaries
+        auto &view = *static_cast<view_type *>(ctx->userdata);
+        ctx->userdata = view.storage<1u>();
+    } break;
+    case CR_CLOSE:
+    case CR_LOAD:
+    case CR_UNLOAD:
+        // nothing to do here, this is only a test.
+        break;
+    }
+
     return 0;
 }

+ 8 - 1
test/lib/view/shared/lib.cpp

@@ -1,3 +1,10 @@
 #include <entt/core/attribute.h>
+#include "../types.h"
 
-ENTT_API void do_nothing() {}
+ENTT_API const void *filter(const view_type &view) {
+    // forces the creation of all symbols for the view type
+    view_type other{};
+
+    // unset filter fallback should not be accessible across boundaries
+    return view.storage<1u>();
+}

+ 6 - 3
test/lib/view/shared/main.cpp

@@ -1,9 +1,12 @@
 #include <gtest/gtest.h>
 #include <entt/core/attribute.h>
+#include "../types.h"
 
-ENTT_API void do_nothing();
+ENTT_API const void *filter(const view_type &);
 
 TEST(Lib, View) {
-    do_nothing();
-	// TODO
+    view_type view{};
+    const void *storage = filter(view);
+
+    ASSERT_EQ(storage, nullptr);
 }

+ 10 - 0
test/lib/view/types.h

@@ -0,0 +1,10 @@
+#ifndef ENTT_LIB_VIEW_TYPE_H
+#define ENTT_LIB_VIEW_TYPE_H
+
+#include <entt/entity/storage.hpp>
+#include <entt/entity/view.hpp>
+#include "../../../common/empty.h"
+
+using view_type = entt::basic_view<entt::get_t<entt::storage<test::empty>>, entt::exclude_t<entt::storage<test::empty>>>;
+
+#endif