~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/third_party/chromium/src/base/observer_list.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) 2011 The Chromium 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 BASE_OBSERVER_LIST_H__
6
 
#define BASE_OBSERVER_LIST_H__
7
 
 
8
 
#include <algorithm>
9
 
#include <limits>
10
 
#include <vector>
11
 
 
12
 
#include "base/basictypes.h"
13
 
#include "base/logging.h"
14
 
#include "base/memory/weak_ptr.h"
15
 
 
16
 
///////////////////////////////////////////////////////////////////////////////
17
 
//
18
 
// OVERVIEW:
19
 
//
20
 
//   A container for a list of observers.  Unlike a normal STL vector or list,
21
 
//   this container can be modified during iteration without invalidating the
22
 
//   iterator.  So, it safely handles the case of an observer removing itself
23
 
//   or other observers from the list while observers are being notified.
24
 
//
25
 
// TYPICAL USAGE:
26
 
//
27
 
//   class MyWidget {
28
 
//    public:
29
 
//     ...
30
 
//
31
 
//     class Observer {
32
 
//      public:
33
 
//       virtual void OnFoo(MyWidget* w) = 0;
34
 
//       virtual void OnBar(MyWidget* w, int x, int y) = 0;
35
 
//     };
36
 
//
37
 
//     void AddObserver(Observer* obs) {
38
 
//       observer_list_.AddObserver(obs);
39
 
//     }
40
 
//
41
 
//     void RemoveObserver(Observer* obs) {
42
 
//       observer_list_.RemoveObserver(obs);
43
 
//     }
44
 
//
45
 
//     void NotifyFoo() {
46
 
//       FOR_EACH_OBSERVER(Observer, observer_list_, OnFoo(this));
47
 
//     }
48
 
//
49
 
//     void NotifyBar(int x, int y) {
50
 
//       FOR_EACH_OBSERVER(Observer, observer_list_, OnBar(this, x, y));
51
 
//     }
52
 
//
53
 
//    private:
54
 
//     ObserverList<Observer> observer_list_;
55
 
//   };
56
 
//
57
 
//
58
 
///////////////////////////////////////////////////////////////////////////////
59
 
 
60
 
template <typename ObserverType>
61
 
class ObserverListThreadSafe;
62
 
 
63
 
template <class ObserverType>
64
 
class ObserverListBase
65
 
    : public base::SupportsWeakPtr<ObserverListBase<ObserverType> > {
66
 
 public:
67
 
  // Enumeration of which observers are notified.
68
 
  enum NotificationType {
69
 
    // Specifies that any observers added during notification are notified.
70
 
    // This is the default type if non type is provided to the constructor.
71
 
    NOTIFY_ALL,
72
 
 
73
 
    // Specifies that observers added while sending out notification are not
74
 
    // notified.
75
 
    NOTIFY_EXISTING_ONLY
76
 
  };
77
 
 
78
 
  // An iterator class that can be used to access the list of observers.  See
79
 
  // also the FOR_EACH_OBSERVER macro defined below.
80
 
  class Iterator {
81
 
   public:
82
 
    Iterator(ObserverListBase<ObserverType>& list)
83
 
        : list_(list.AsWeakPtr()),
84
 
          index_(0),
85
 
          max_index_(list.type_ == NOTIFY_ALL ?
86
 
                     std::numeric_limits<size_t>::max() :
87
 
                     list.observers_.size()) {
88
 
      ++list_->notify_depth_;
89
 
    }
90
 
 
91
 
    ~Iterator() {
92
 
      if (list_.get() && --list_->notify_depth_ == 0)
93
 
        list_->Compact();
94
 
    }
95
 
 
96
 
    ObserverType* GetNext() {
97
 
      if (!list_.get())
98
 
        return NULL;
99
 
      ListType& observers = list_->observers_;
100
 
      // Advance if the current element is null
101
 
      size_t max_index = std::min(max_index_, observers.size());
102
 
      while (index_ < max_index && !observers[index_])
103
 
        ++index_;
104
 
      return index_ < max_index ? observers[index_++] : NULL;
105
 
    }
106
 
 
107
 
   private:
108
 
    base::WeakPtr<ObserverListBase<ObserverType> > list_;
109
 
    size_t index_;
110
 
    size_t max_index_;
111
 
  };
112
 
 
113
 
  ObserverListBase() : notify_depth_(0), type_(NOTIFY_ALL) {}
114
 
  explicit ObserverListBase(NotificationType type)
115
 
      : notify_depth_(0), type_(type) {}
116
 
 
117
 
  // Add an observer to the list.  An observer should not be added to
118
 
  // the same list more than once.
119
 
  void AddObserver(ObserverType* obs) {
120
 
    if (std::find(observers_.begin(), observers_.end(), obs)
121
 
        != observers_.end()) {
122
 
      NOTREACHED() << "Observers can only be added once!";
123
 
      return;
124
 
    }
125
 
    observers_.push_back(obs);
126
 
  }
127
 
 
128
 
  // Remove an observer from the list if it is in the list.
129
 
  void RemoveObserver(ObserverType* obs) {
130
 
    typename ListType::iterator it =
131
 
      std::find(observers_.begin(), observers_.end(), obs);
132
 
    if (it != observers_.end()) {
133
 
      if (notify_depth_) {
134
 
        *it = 0;
135
 
      } else {
136
 
        observers_.erase(it);
137
 
      }
138
 
    }
139
 
  }
140
 
 
141
 
  bool HasObserver(ObserverType* observer) const {
142
 
    for (size_t i = 0; i < observers_.size(); ++i) {
143
 
      if (observers_[i] == observer)
144
 
        return true;
145
 
    }
146
 
    return false;
147
 
  }
148
 
 
149
 
  void Clear() {
150
 
    if (notify_depth_) {
151
 
      for (typename ListType::iterator it = observers_.begin();
152
 
           it != observers_.end(); ++it) {
153
 
        *it = 0;
154
 
      }
155
 
    } else {
156
 
      observers_.clear();
157
 
    }
158
 
  }
159
 
 
160
 
 protected:
161
 
  size_t size() const { return observers_.size(); }
162
 
 
163
 
  void Compact() {
164
 
    observers_.erase(
165
 
        std::remove(observers_.begin(), observers_.end(),
166
 
                    static_cast<ObserverType*>(NULL)), observers_.end());
167
 
  }
168
 
 
169
 
 private:
170
 
  friend class ObserverListThreadSafe<ObserverType>;
171
 
 
172
 
  typedef std::vector<ObserverType*> ListType;
173
 
 
174
 
  ListType observers_;
175
 
  int notify_depth_;
176
 
  NotificationType type_;
177
 
 
178
 
  friend class ObserverListBase::Iterator;
179
 
 
180
 
  DISALLOW_COPY_AND_ASSIGN(ObserverListBase);
181
 
};
182
 
 
183
 
template <class ObserverType, bool check_empty = false>
184
 
class ObserverList : public ObserverListBase<ObserverType> {
185
 
 public:
186
 
  typedef typename ObserverListBase<ObserverType>::NotificationType
187
 
      NotificationType;
188
 
 
189
 
  ObserverList() {}
190
 
  explicit ObserverList(NotificationType type)
191
 
      : ObserverListBase<ObserverType>(type) {}
192
 
 
193
 
  ~ObserverList() {
194
 
    // When check_empty is true, assert that the list is empty on destruction.
195
 
    if (check_empty) {
196
 
      ObserverListBase<ObserverType>::Compact();
197
 
      DCHECK_EQ(ObserverListBase<ObserverType>::size(), 0U);
198
 
    }
199
 
  }
200
 
 
201
 
  bool might_have_observers() const {
202
 
    return ObserverListBase<ObserverType>::size() != 0;
203
 
  }
204
 
};
205
 
 
206
 
#define FOR_EACH_OBSERVER(ObserverType, observer_list, func)               \
207
 
  do {                                                                     \
208
 
    if ((observer_list).might_have_observers()) {                          \
209
 
      ObserverListBase<ObserverType>::Iterator                             \
210
 
          it_inside_observer_macro(observer_list);                         \
211
 
      ObserverType* obs;                                                   \
212
 
      while ((obs = it_inside_observer_macro.GetNext()) != NULL)           \
213
 
        obs->func;                                                         \
214
 
    }                                                                      \
215
 
  } while (0)
216
 
 
217
 
#endif  // BASE_OBSERVER_LIST_H__