Selaa lähdekoodia

meta: prepare internal::try_cast for lazy load on nodes

skypjack 6 kuukautta sitten
vanhempi
commit
1f53d163b7
3 muutettua tiedostoa jossa 9 lisäystä ja 12 poistoa
  1. 1 1
      TODO
  2. 4 5
      src/entt/meta/meta.hpp
  3. 4 6
      src/entt/meta/node.hpp

+ 1 - 1
TODO

@@ -32,5 +32,5 @@ TODO:
 * avoid copying meta_type nodes, and use unique_ptr for meta_custom
 * paged vector as a standalone class
 * resource: shared_from_this?
-* meta perf: the node in the meta_any is pretty much irrelevant, but it affects perf a lot
+* meta perf: the node in the meta_any is pretty much irrelevant, but it affects perf a lot (also fix natvis after this)
 * change meta_any::base name, it's confusing due to meta_base_node and base types in meta

+ 4 - 5
src/entt/meta/meta.hpp

@@ -422,7 +422,7 @@ public:
     template<typename Type>
     [[nodiscard]] const Type *try_cast() const {
         const auto *elem = any_cast<const Type>(&storage);
-        return (elem != nullptr) ? elem : static_cast<const Type *>(internal::try_cast(internal::meta_context::from(*ctx), node, type_id<std::remove_cv_t<Type>>(), storage.data()));
+        return (elem != nullptr) ? elem : static_cast<const Type *>(internal::try_cast(internal::meta_context::from(*ctx), node, type_id<std::remove_cv_t<Type>>().hash(), storage.data()));
     }
 
     /*! @copydoc try_cast */
@@ -433,7 +433,7 @@ public:
         } else {
             auto *elem = any_cast<Type>(&storage);
             // NOLINTNEXTLINE(bugprone-casting-through-void)
-            return (elem != nullptr) ? elem : static_cast<Type *>(const_cast<void *>(internal::try_cast(internal::meta_context::from(*ctx), node, type_id<Type>(), storage.data())));
+            return (elem != nullptr) ? elem : static_cast<Type *>(const_cast<void *>(internal::try_cast(internal::meta_context::from(*ctx), node, type_id<Type>().hash(), storage.data())));
         }
     }
 
@@ -1326,7 +1326,7 @@ public:
      */
     [[nodiscard]] bool can_cast(const meta_type &other) const noexcept {
         // casting this is UB in all cases but we aren't going to use the resulting pointer, so...
-        return other && (internal::try_cast(internal::meta_context::from(*ctx), node, *other.node.info, this) != nullptr);
+        return other && ((*this == other) || (internal::try_cast(internal::meta_context::from(*ctx), node, other.node.info->hash(), this) != nullptr));
     }
 
     /**
@@ -1524,8 +1524,7 @@ public:
 
     /*! @copydoc meta_data::operator== */
     [[nodiscard]] bool operator==(const meta_type &other) const noexcept {
-        // NOLINTNEXTLINE(clang-analyzer-core.NonNullParamChecker)
-        return (ctx == other.ctx) && ((node.info == nullptr) == (other.node.info == nullptr)) && (node.info == nullptr || (*node.info == *other.node.info));
+        return (ctx == other.ctx) && (node.id == other.node.id);
     }
 
 private:

+ 4 - 6
src/entt/meta/node.hpp

@@ -199,14 +199,12 @@ template<typename... Args>
     return value(context);
 }
 
-[[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const type_info &to, const void *instance) noexcept {
-    if((from.info != nullptr) && *from.info == to) {
-        return instance;
-    }
-
+[[nodiscard]] inline const void *try_cast(const meta_context &context, const meta_type_node &from, const id_type to, const void *instance) noexcept {
     if(from.details) {
         for(auto &&curr: from.details->base) {
-            if(const void *elem = try_cast(context, curr.resolve(context), to, curr.cast(instance)); elem) {
+            if(const void *other = curr.cast(instance); curr.type == to) {
+                return other;
+            } else if(const void *elem = try_cast(context, curr.resolve(context), to, other); elem) {
                 return elem;
             }
         }