blob: e118dc898b2d3a6ee238c97e318e6031d96e1bf3 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
// Copyright 2016 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CORE_FXCRT_OBSERVABLE_H_
#define CORE_FXCRT_OBSERVABLE_H_
#include <set>
#include "core/fxcrt/fx_system.h"
#include "third_party/base/stl_util.h"
namespace fxcrt {
template <class T>
class Observable {
public:
// General-purpose interface for more complicated cleanup.
class Observer {
public:
virtual ~Observer() = default;
virtual void OnObservableDestroyed() = 0;
};
// Simple case of a self-nulling pointer.
class ObservedPtr final : public Observer {
public:
ObservedPtr() = default;
explicit ObservedPtr(T* pObservable) : m_pObservable(pObservable) {
if (m_pObservable)
m_pObservable->AddObserver(this);
}
ObservedPtr(const ObservedPtr& that) : ObservedPtr(that.Get()) {}
~ObservedPtr() override {
if (m_pObservable)
m_pObservable->RemoveObserver(this);
}
void Reset(T* pObservable = nullptr) {
if (m_pObservable)
m_pObservable->RemoveObserver(this);
m_pObservable = pObservable;
if (m_pObservable)
m_pObservable->AddObserver(this);
}
void OnObservableDestroyed() override {
ASSERT(m_pObservable);
m_pObservable = nullptr;
}
ObservedPtr& operator=(const ObservedPtr& that) {
Reset(that.Get());
return *this;
}
bool operator==(const ObservedPtr& that) const {
return m_pObservable == that.m_pObservable;
}
bool operator!=(const ObservedPtr& that) const { return !(*this == that); }
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_pObservable = nullptr;
};
Observable() = default;
Observable(const Observable& that) = delete;
~Observable() { NotifyObservers(); }
void AddObserver(Observer* pObserver) {
ASSERT(!pdfium::ContainsKey(m_Observers, pObserver));
m_Observers.insert(pObserver);
}
void RemoveObserver(Observer* pObserver) {
ASSERT(pdfium::ContainsKey(m_Observers, pObserver));
m_Observers.erase(pObserver);
}
void NotifyObservers() {
for (auto* pObserver : m_Observers)
pObserver->OnObservableDestroyed();
m_Observers.clear();
}
Observable& operator=(const Observable& that) = delete;
protected:
size_t ActiveObserversForTesting() const { return m_Observers.size(); }
private:
std::set<Observer*> m_Observers;
};
} // namespace fxcrt
using fxcrt::Observable;
#endif // CORE_FXCRT_OBSERVABLE_H_
|