• 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_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:
ObservedPtr()18     ObservedPtr() : m_pObservable(nullptr) {}
ObservedPtr(T * pObservable)19     explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) {
20       if (m_pObservable)
21         m_pObservable->AddObservedPtr(this);
22     }
ObservedPtr(const ObservedPtr & that)23     ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {}
~ObservedPtr()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     }
OnDestroy()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; }
Get()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 
CFX_Observable()56   CFX_Observable() {}
57   CFX_Observable(const CFX_Observable& that) = delete;
~CFX_Observable()58   ~CFX_Observable() { NotifyObservedPtrs(); }
AddObservedPtr(ObservedPtr * pObservedPtr)59   void AddObservedPtr(ObservedPtr* pObservedPtr) {
60     ASSERT(!pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
61     m_ObservedPtrs.insert(pObservedPtr);
62   }
RemoveObservedPtr(ObservedPtr * pObservedPtr)63   void RemoveObservedPtr(ObservedPtr* pObservedPtr) {
64     ASSERT(pdfium::ContainsKey(m_ObservedPtrs, pObservedPtr));
65     m_ObservedPtrs.erase(pObservedPtr);
66   }
NotifyObservedPtrs()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:
ActiveObservedPtrsForTesting()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