diff --git a/panda/src/express/weakPointerToBase.I b/panda/src/express/weakPointerToBase.I index 8c6de65523..5673114764 100644 --- a/panda/src/express/weakPointerToBase.I +++ b/panda/src/express/weakPointerToBase.I @@ -72,6 +72,26 @@ WeakPointerToBase(WeakPointerToBase &&from) noexcept { from._weak_ref = nullptr; } +/** + * Copies a weak pointer from a cast-convertible weak pointer type. + */ +template +template +INLINE WeakPointerToBase:: +WeakPointerToBase(const WeakPointerToBase &r) { + // If this next line gives an error, you are trying to convert a WeakPointerTo + // from an incompatible type of another WeakPointerTo. + To *ptr = (Y *)r._void_ptr; + + this->_void_ptr = ptr; + + WeakReferenceList *weak_ref = r._weak_ref; + if (weak_ref != nullptr) { + _weak_ref = weak_ref; + weak_ref->ref(); + } +} + /** * Moves a weak pointer from a cast-convertible weak pointer type. */ @@ -190,6 +210,34 @@ reassign(WeakPointerToBase &&from) noexcept { } } +/** + * Like above, but casts from a compatible pointer type. + */ +template +template +INLINE void WeakPointerToBase:: +reassign(const WeakPointerToBase ©) { + // If there is a compile error on this line, it means you tried to assign + // an incompatible type. + To *new_ptr = (Y *)copy._void_ptr; + + if (new_ptr != (To *)_void_ptr) { + WeakReferenceList *old_ref = (WeakReferenceList *)_weak_ref; + WeakReferenceList *new_ref = copy._weak_ref; + _void_ptr = new_ptr; + _weak_ref = new_ref; + + if (new_ref != nullptr) { + new_ref->ref(); + } + + // Now remove the old reference. + if (old_ref != nullptr && !old_ref->unref()) { + delete old_ref; + } + } +} + /** * Like above, but casts from a compatible pointer type. */ diff --git a/panda/src/express/weakPointerToBase.h b/panda/src/express/weakPointerToBase.h index 474514b055..291cd587e4 100644 --- a/panda/src/express/weakPointerToBase.h +++ b/panda/src/express/weakPointerToBase.h @@ -34,6 +34,8 @@ protected: INLINE WeakPointerToBase(const WeakPointerToBase ©); INLINE WeakPointerToBase(WeakPointerToBase &&from) noexcept; template + INLINE WeakPointerToBase(const WeakPointerToBase &r); + template INLINE WeakPointerToBase(WeakPointerToBase &&r) noexcept; INLINE ~WeakPointerToBase(); @@ -43,6 +45,8 @@ protected: INLINE void reassign(const WeakPointerToBase ©); INLINE void reassign(WeakPointerToBase &&from) noexcept; template + INLINE void reassign(const WeakPointerToBase ©); + template INLINE void reassign(WeakPointerToBase &&from) noexcept; INLINE void update_type(To *ptr); @@ -96,6 +100,9 @@ public: template INLINE bool owner_before(const PointerToBase &other) const noexcept; + // This is needed to be able to access the privates of other instantiations. + template friend class WeakPointerToBase; + PUBLISHED: INLINE void clear(); INLINE void refresh() const;