diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/fxcrt/cfx_observable.h | 47 | ||||
-rw-r--r-- | core/fxcrt/cfx_observable_unittest.cpp | 72 |
2 files changed, 97 insertions, 22 deletions
diff --git a/core/fxcrt/cfx_observable.h b/core/fxcrt/cfx_observable.h index dc869b1766..8dc0907cae 100644 --- a/core/fxcrt/cfx_observable.h +++ b/core/fxcrt/cfx_observable.h @@ -15,39 +15,42 @@ class CFX_Observable { public: class ObservedPtr { public: - ObservedPtr() : m_pObservedPtr(nullptr) {} - explicit ObservedPtr(T* pObservedPtr) : m_pObservedPtr(pObservedPtr) { - if (m_pObservedPtr) - m_pObservedPtr->AddObservedPtr(this); + ObservedPtr() : m_pObservable(nullptr) {} + explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) { + if (m_pObservable) + m_pObservable->AddObservedPtr(this); } - ObservedPtr(const ObservedPtr& that) = delete; + ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {} ~ObservedPtr() { - if (m_pObservedPtr) - m_pObservedPtr->RemoveObservedPtr(this); + if (m_pObservable) + m_pObservable->RemoveObservedPtr(this); } - void Reset(T* pObservedPtr = nullptr) { - if (m_pObservedPtr) - m_pObservedPtr->RemoveObservedPtr(this); - m_pObservedPtr = pObservedPtr; - if (m_pObservedPtr) - m_pObservedPtr->AddObservedPtr(this); + void Reset(T* pObservable = nullptr) { + if (m_pObservable) + m_pObservable->RemoveObservedPtr(this); + m_pObservable = pObservable; + if (m_pObservable) + m_pObservable->AddObservedPtr(this); } void OnDestroy() { - ASSERT(m_pObservedPtr); - m_pObservedPtr = nullptr; + ASSERT(m_pObservable); + m_pObservable = nullptr; + } + ObservedPtr& operator=(const ObservedPtr& that) { + Reset(that.Get()); + return *this; } - ObservedPtr& operator=(const ObservedPtr& that) = delete; bool operator==(const ObservedPtr& that) const { - return m_pObservedPtr == that.m_pObservedPtr; + return m_pObservable == that.m_pObservable; } bool operator!=(const ObservedPtr& that) const { return !(*this == that); } - explicit operator bool() const { return !!m_pObservedPtr; } - T* Get() const { return m_pObservedPtr; } - T& operator*() const { return *m_pObservedPtr; } - T* operator->() const { return m_pObservedPtr; } + explicit operator bool() const { return !!m_pObservable; } + T* Get() const { return m_pObservable; } + T& operator*() const { return *m_pObservable; } + T* operator->() const { return m_pObservable; } private: - T* m_pObservedPtr; + T* m_pObservable; }; CFX_Observable() {} diff --git a/core/fxcrt/cfx_observable_unittest.cpp b/core/fxcrt/cfx_observable_unittest.cpp index 15c76495cf..3c0fabb13e 100644 --- a/core/fxcrt/cfx_observable_unittest.cpp +++ b/core/fxcrt/cfx_observable_unittest.cpp @@ -5,6 +5,7 @@ #include "core/fxcrt/cfx_observable.h" #include <utility> +#include <vector> #include "testing/fx_string_testhelpers.h" #include "testing/gtest/include/gtest/gtest.h" @@ -44,6 +45,77 @@ TEST(fxcrt, ObservePtrLivesShorter) { EXPECT_EQ(0u, obs.ActiveObservedPtrs()); } +TEST(fxcrt, ObserveCopyConstruct) { + PseudoObservable obs; + { + PseudoObservable::ObservedPtr ptr(&obs); + EXPECT_NE(nullptr, ptr.Get()); + EXPECT_EQ(1u, obs.ActiveObservedPtrs()); + { + PseudoObservable::ObservedPtr ptr2(ptr); + EXPECT_NE(nullptr, ptr2.Get()); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(1u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(0u, obs.ActiveObservedPtrs()); +} + +TEST(fxcrt, ObserveCopyAssign) { + PseudoObservable obs; + { + PseudoObservable::ObservedPtr ptr(&obs); + EXPECT_NE(nullptr, ptr.Get()); + EXPECT_EQ(1u, obs.ActiveObservedPtrs()); + { + PseudoObservable::ObservedPtr ptr2; + ptr2 = ptr; + EXPECT_NE(nullptr, ptr2.Get()); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(1u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(0u, obs.ActiveObservedPtrs()); +} + +TEST(fxcrt, ObserveVector) { + PseudoObservable obs; + { + std::vector<PseudoObservable::ObservedPtr> vec1; + std::vector<PseudoObservable::ObservedPtr> vec2; + vec1.emplace_back(&obs); + vec1.emplace_back(&obs); + EXPECT_NE(nullptr, vec1[0].Get()); + EXPECT_NE(nullptr, vec1[1].Get()); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + vec2 = vec1; + EXPECT_NE(nullptr, vec2[0].Get()); + EXPECT_NE(nullptr, vec2[1].Get()); + EXPECT_EQ(4u, obs.ActiveObservedPtrs()); + vec1.clear(); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + vec2.resize(10000); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + vec2.resize(0); + EXPECT_EQ(0u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(0u, obs.ActiveObservedPtrs()); +} + +TEST(fxcrt, ObserveVectorAutoClear) { + std::vector<PseudoObservable::ObservedPtr> vec1; + { + PseudoObservable obs; + vec1.emplace_back(&obs); + vec1.emplace_back(&obs); + EXPECT_NE(nullptr, vec1[0].Get()); + EXPECT_NE(nullptr, vec1[1].Get()); + EXPECT_EQ(2u, obs.ActiveObservedPtrs()); + } + EXPECT_EQ(nullptr, vec1[0].Get()); + EXPECT_EQ(nullptr, vec1[1].Get()); +} + TEST(fxcrt, ObservePtrResetNull) { PseudoObservable obs; PseudoObservable::ObservedPtr ptr(&obs); |