Home | History | Annotate | Download | only in fxcrt
      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