diff --git a/include/hyprutils/memory/Atomic.hpp b/include/hyprutils/memory/Atomic.hpp index 813bae3..c8fd033 100644 --- a/include/hyprutils/memory/Atomic.hpp +++ b/include/hyprutils/memory/Atomic.hpp @@ -285,6 +285,10 @@ namespace Hyprutils::Memory { CAtomicWeakPointer() noexcept = default; + CAtomicWeakPointer(Impl_::impl_base* implementation, void* data) noexcept : m_ptr(implementation, data) { + ; + } + CAtomicWeakPointer(std::nullptr_t) noexcept { ; // empty } @@ -434,4 +438,14 @@ namespace Hyprutils::Memory { return nullptr; return CAtomicSharedPointer(ref.impl(), newPtr); } + + template + CAtomicWeakPointer dynamicPointerCast(const CAtomicWeakPointer& ref) { + if (!ref) + return nullptr; + T* newPtr = dynamic_cast(sc(ref.impl()->getData())); + if (!newPtr) + return nullptr; + return CAtomicWeakPointer(ref.impl(), newPtr); + } } diff --git a/include/hyprutils/memory/WeakPtr.hpp b/include/hyprutils/memory/WeakPtr.hpp index e062a49..44e2a27 100644 --- a/include/hyprutils/memory/WeakPtr.hpp +++ b/include/hyprutils/memory/WeakPtr.hpp @@ -62,6 +62,14 @@ namespace Hyprutils { incrementWeak(); } + CWeakPointer(Impl_::impl_base* implementation, void* data) noexcept : impl_(implementation), m_data(data) { + incrementWeak(); + } + + CWeakPointer(std::nullptr_t) noexcept { + ; // empty + } + template > CWeakPointer(CWeakPointer&& ref) noexcept { std::swap(impl_, ref.impl_); diff --git a/src/signal/Signal.cpp b/src/signal/Signal.cpp index 685f819..bcc4922 100644 --- a/src/signal/Signal.cpp +++ b/src/signal/Signal.cpp @@ -10,10 +10,10 @@ using namespace Hyprutils::Memory; #define WP CWeakPointer void Hyprutils::Signal::CSignalBase::emitInternal(void* args) { - + // Save, an event can destroy thisptr const auto STATICS = m_vStaticListeners; - + if (!m_vListeners.empty()) { std::vector> listeners; listeners.reserve(m_vListeners.size()); diff --git a/tests/memory/Memory.cpp b/tests/memory/Memory.cpp index 99d91e2..bdbbf50 100644 --- a/tests/memory/Memory.cpp +++ b/tests/memory/Memory.cpp @@ -156,8 +156,10 @@ static void testHierarchy() { EXPECT_TRUE(ifaceA); EXPECT_EQ(ifaceA->m_ifaceAInt, 69); - auto ifaceB = dynamicPointerCast(SP{}); + auto ifaceB = dynamicPointerCast(SP{}); + auto ifaceB2 = dynamicPointerCast(WP{}); EXPECT_TRUE(!ifaceB); + EXPECT_TRUE(!ifaceB2); } { @@ -171,9 +173,11 @@ static void testHierarchy() { EXPECT_EQ(ifaceB->m_ifaceBInt, 2); WP ifaceAWeak = ifaceA; + WP ifaceBWeak = dynamicPointerCast(WP{child}); child.reset(); EXPECT_TRUE(ifaceAWeak); + EXPECT_TRUE(ifaceBWeak); EXPECT_TRUE(ifaceA); EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69); EXPECT_EQ(ifaceA->m_ifaceAInt, 69); @@ -182,8 +186,10 @@ static void testHierarchy() { EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69); EXPECT_TRUE(ifaceB); EXPECT_EQ(ifaceB->m_ifaceBInt, 2); + EXPECT_EQ(ifaceBWeak->m_ifaceBInt, 2); ifaceB.reset(); EXPECT_TRUE(!ifaceAWeak); + EXPECT_TRUE(!ifaceBWeak); } // @@ -194,8 +200,10 @@ static void testHierarchy() { EXPECT_TRUE(ifaceA); EXPECT_EQ(ifaceA->m_ifaceAInt, 69); - auto ifaceB = dynamicPointerCast(ASP{}); + auto ifaceB = dynamicPointerCast(SP{}); + auto ifaceB2 = dynamicPointerCast(WP{}); EXPECT_TRUE(!ifaceB); + EXPECT_TRUE(!ifaceB2); } { @@ -209,7 +217,7 @@ static void testHierarchy() { EXPECT_EQ(ifaceB->m_ifaceBInt, 2); AWP ifaceAWeak = ifaceA; - AWP ifaceBWeak = dynamicPointerCast(ifaceA); + AWP ifaceBWeak = dynamicPointerCast(AWP{child}); child.reset(); EXPECT_TRUE(ifaceAWeak); @@ -217,7 +225,6 @@ static void testHierarchy() { EXPECT_TRUE(ifaceA); EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69); EXPECT_EQ(ifaceA->m_ifaceAInt, 69); - EXPECT_EQ(ifaceBWeak->m_ifaceBInt, 2); ifaceA.reset(); EXPECT_TRUE(ifaceAWeak); EXPECT_EQ(ifaceAWeak->m_ifaceAInt, 69);