• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_OBSERVABLE_H_
6 #define CORE_FXCRT_OBSERVABLE_H_
7 
8 #include <set>
9 
10 #include "core/fxcrt/fx_system.h"
11 #include "third_party/base/stl_util.h"
12 
13 namespace fxcrt {
14 
15 template <class T>
16 class Observable {
17  public:
18   class ObservedPtr {
19    public:
ObservedPtr()20     ObservedPtr() : m_pObservable(nullptr) {}
ObservedPtr(T * pObservable)21     explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) {
22       if (m_pObservable)
23         m_pObservable->AddObservedPtr(this);
24     }
ObservedPtr(const ObservedPtr & that)25     ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {}
~ObservedPtr()26     ~ObservedPtr() {
27       if (m_pObservable)
28         m_pObservable->RemoveObservedPtr(this);
29     }
30     void Reset(T* pObservable = nullptr) {
31       if (m_pObservable)
32         m_pObservable->RemoveObservedPtr(this);
33       m_pObservable = pObservable;
34       if (m_pObservable)
35         m_pObservable->AddObservedPtr(this);
36     }
OnDestroy()37     void OnDestroy() {
38       ASSERT(m_pObservable);
39       m_pObservable = nullptr;
40     }
41     ObservedPtr& operator=(const ObservedPtr& that) {
42       Reset(that.Get());
43       return *this;
44     }
45     bool operator==(const ObservedPtr& that) const {
46       return m_pObservable == that.m_pObservable;
47     }
48     bool operator!=(const ObservedPtr& that) const { return !(*this == that); }
49     explicit operator bool() const { return !!m_pObservable; }
Get()50     T* Get() const { return m_pObservable; }
51     T& operator*() const { return *m_pObservable; }
52     T* operator->() const { return m_pObservable; }
53 
54    private:
55     T* m_pObservable;
56   };
57 
58   Observable() = default;
59   Observable(const Observable& that) = delete;
~Observable()60   ~Observable() { NotifyObservedPtrs(); }
AddObservedPtr(ObservedPtr * pObservedPtr)61   void AddObservedPtr(ObservedPtr* pObservedPtr) {
62     ASSERT(!pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
63     m_ObservedPtrs.insert(pObservedPtr);
64   }
RemoveObservedPtr(ObservedPtr * pObservedPtr)65   void RemoveObservedPtr(ObservedPtr* pObservedPtr) {
66     ASSERT(pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
67     m_ObservedPtrs.erase(pObservedPtr);
68   }
NotifyObservedPtrs()69   void NotifyObservedPtrs() {
70     for (auto* pObservedPtr : m_ObservedPtrs)
71       pObservedPtr->OnDestroy();
72     m_ObservedPtrs.clear();
73   }
74   Observable& operator=(const Observable& that) = delete;
75 
76  protected:
ActiveObservedPtrsForTesting()77   size_t ActiveObservedPtrsForTesting() const { return m_ObservedPtrs.size(); }
78 
79  private:
80   std::set<ObservedPtr*> m_ObservedPtrs;
81 };
82 
83 }  // namespace fxcrt
84 
85 using fxcrt::Observable;
86 
87 #endif  // CORE_FXCRT_OBSERVABLE_H_
88