Code Monkey home page Code Monkey logo

Comments (12)

skypjack avatar skypjack commented on May 18, 2024 1

This is part of the realm of works as expected.

Whenever you try to access a type the meta type of which doesn't exist (either because you never registered it or because you've unregistered it), the system implicitly generates an underlying meta node to fill the gap and to make things work properly.
That's why you can invoke eg a function like void(int) even though you've never registered int with the meta system.

Of course, if you use a type A after you unregistered it and before it's registered again, the re-registration fails because of the implicitly generated meta type.
Note that you can unregister these types in exactly the same way you unregister explicitly generated types.

from meta.

skypjack avatar skypjack commented on May 18, 2024

Sorry, I completely missed this issue. My fault.
Good point on unregistering a type. It shouldn't be difficult to do.
I'll adapt your snippet and include it in the codebase. Thanks.

from meta.

skypjack avatar skypjack commented on May 18, 2024

Sorry @yabadabu how can your snippet work without errors? Shouldn't it fail here if yout try to register again a type you've just unregistered?

assert(!internal::type_info<Type>::type);

You don't reset this variable that is therefore different from nullptr. The assert should fail as a consequence. Isn't it?

from meta.

yabadabu avatar yabadabu commented on May 18, 2024

I think it works for me because the type was defined and registered from a external dll, added to the linked list which lives in the main .exe. unlinked, then the dll is unloaded, and a new dll instanced loaded, which brings a new copy of the static var you are referring.

I think the lib requires a better unregister than my snippet.
I'm not even taking into account if some other types still depend on the unregistered type, and if I reregister the type, the old references are not refreshed. In my case I enforce this as each dll brings it's own types and subtypes, but it's not a general solution.

from meta.

yabadabu avatar yabadabu commented on May 18, 2024

We can reset the pointer if the given type is found in the linked list.

template<typename Type>
bool unregister() noexcept {
  auto type_to_unregister = meta::internal::type_info<Type>::resolve();
  auto* addr_t = &meta::internal::info_node<>::type;
  while (addr_t && *addr_t) {
    auto t = *addr_t;
    if (t == type_to_unregister) {
      *addr_t = t->next;
      meta::internal::type_info<Type>::type = nullptr;
      return true;
    }
    addr_t = (meta::internal::type_node **) &t->next;
    t = t->next;
  }
  return false;
}

from meta.

skypjack avatar skypjack commented on May 18, 2024

Yeah, it's a bit more complicated than this, just because the same applies also to the data members, member functions, and so on...

from meta.

skypjack avatar skypjack commented on May 18, 2024

Pushed a draft of the unregister function on branch experimental.
I've still to test it, but I'd be glad if you want to review it and give me your feedback in the meantime.
I think I'll write tests and merge everything upstream during the week.


Ok, well, I've already found some bugs, but the basic idea is the one in that commit at least. 😄

from meta.

yabadabu avatar yabadabu commented on May 18, 2024

Hi
It looks really good!! I had some problems compiling under vc2017. Here is a small patch to make it compile and work. I added the return type bool, the friend declaration for the global function and the template argument which at least vc was complaining about. (there must be a better way to send you a patch)

---
 src/meta/factory.hpp | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/meta/factory.hpp b/src/meta/factory.hpp
index 417f029..02bbe51 100644
--- a/src/meta/factory.hpp
+++ b/src/meta/factory.hpp
@@ -138,7 +138,7 @@ class factory {
         }
     }

-    template<auto *Member>
+    template<auto Member>
     void unregister_all(char) {
         while(internal::type_info<Type>::type->*Member) {
             auto node = internal::type_info<Type>::type->*Member;
@@ -148,7 +148,7 @@ class factory {
         }
     }

-    void unregister() noexcept {
+    bool unregister() noexcept {
         if(internal::type_info<Type>::type) {
             if(auto **curr = &internal::type_info<>::type; *curr == internal::type_info<Type>::type) {
                 *curr = internal::type_info<Type>::type->next;
@@ -172,11 +172,16 @@ class factory {
             internal::type_info<Type>::type->name = nullptr;
             internal::type_info<Type>::type->next = nullptr;
             internal::type_info<Type>::type = nullptr;
+            return true;
         }
+        return false;
     }

     factory() noexcept = default;

+    template<typename Other>
+    friend bool unregister() noexcept;
+
 public:
     template<typename Other, typename... Property>
     friend factory<Other> reflect(const char *str, Property &&... property) noexcept;
@@ -579,8 +584,8 @@ inline factory<Type> reflect() noexcept {
  * @return True if the type to unregister exists, false otherwise.
  */
 template<typename Type>
-inline void unregister() noexcept {
-    factory<Type>().unregister();
+inline bool unregister() noexcept {
+    return factory<Type>().unregister();
 }


--

from meta.

skypjack avatar skypjack commented on May 18, 2024

I'm pushing an updated version. Would you try it and let me know if the errors are still there? Thanks.

from meta.

skypjack avatar skypjack commented on May 18, 2024

Ready to go for me. Can you confirm it? Thanks.

from meta.

yabadabu avatar yabadabu commented on May 18, 2024

Yes, it's working!!!

from meta.

yabadabu avatar yabadabu commented on May 18, 2024

Hi
One minor problem I found, is that if we reflect

  • define reflection of class A,
  • define reflection of class B which has a member data of type class A.
  • unregister class A
  • Scan data member's of class B, you get a reference to clazz A, but the type is null.
  • Try to register A again
  • The assert in line 114 assert(!internal::type_info::type);

It seems that referencing type A while scanning data members of B has reregistered the type A, and the second register fails.

Thanks

from meta.

Related Issues (5)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.