1 // Copyright 2016 PDFium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CORE_FXCRT_CFX_OBSERVABLE_H_ 6 #define CORE_FXCRT_CFX_OBSERVABLE_H_ 7 8 #include <set> 9 10 #include "core/fxcrt/fx_system.h" 11 #include "third_party/base/stl_util.h" 12 13 template <class T> 14 class CFX_Observable { 15 public: 16 class ObservedPtr { 17 public: 18 ObservedPtr() : m_pObservable(nullptr) {} 19 explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) { 20 if (m_pObservable) 21 m_pObservable->AddObservedPtr(this); 22 } 23 ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {} 24 ~ObservedPtr() { 25 if (m_pObservable) 26 m_pObservable->RemoveObservedPtr(this); 27 } 28 void Reset(T* pObservable = nullptr) { 29 if (m_pObservable) 30 m_pObservable->RemoveObservedPtr(this); 31 m_pObservable = pObservable; 32 if (m_pObservable) 33 m_pObservable->AddObservedPtr(this); 34 } 35 void OnDestroy() { 36 ASSERT(m_pObservable); 37 m_pObservable = nullptr; 38 } 39 ObservedPtr& operator=(const ObservedPtr& that) { 40 Reset(that.Get()); 41 return *this; 42 } 43 bool operator==(const ObservedPtr& that) const { 44 return m_pObservable == that.m_pObservable; 45 } 46 bool operator!=(const ObservedPtr& that) const { return !(*this == that); } 47 explicit operator bool() const { return !!m_pObservable; } 48 T* Get() const { return m_pObservable; } 49 T& operator*() const { return *m_pObservable; } 50 T* operator->() const { return m_pObservable; } 51 52 private: 53 T* m_pObservable; 54 }; 55 56 CFX_Observable() {} 57 CFX_Observable(const CFX_Observable& that) = delete; 58 ~CFX_Observable() { NotifyObservedPtrs(); } 59 void AddObservedPtr(ObservedPtr* pObservedPtr) { 60 ASSERT(!pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr)); 61 m_ObservedPtrs.insert(pObservedPtr); 62 } 63 void RemoveObservedPtr(ObservedPtr* pObservedPtr) { 64 ASSERT(pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr)); 65 m_ObservedPtrs.erase(pObservedPtr); 66 } 67 void NotifyObservedPtrs() { 68 for (auto* pObservedPtr : m_ObservedPtrs) 69 pObservedPtr->OnDestroy(); 70 m_ObservedPtrs.clear(); 71 } 72 CFX_Observable& operator=(const CFX_Observable& that) = delete; 73 74 protected: 75 size_t ActiveObservedPtrsForTesting() const { return m_ObservedPtrs.size(); } 76 77 private: 78 std::set<ObservedPtr*> m_ObservedPtrs; 79 }; 80 81 #endif // CORE_FXCRT_CFX_OBSERVABLE_H_ 82