diff options
author | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-31 03:32:06 +0000 |
---|---|---|
committer | sky@google.com <sky@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-10-31 03:32:06 +0000 |
commit | b3e2fad0a13695466c07ce4c982fa98448e407a0 (patch) | |
tree | 1a8a24741bd016446bafac5ff802590a430e3a2a /base/observer_list.h | |
parent | 13301121d7efad67b74f0e0b6a4c1f46d866c425 (diff) | |
download | chromium_src-b3e2fad0a13695466c07ce4c982fa98448e407a0.zip chromium_src-b3e2fad0a13695466c07ce4c982fa98448e407a0.tar.gz chromium_src-b3e2fad0a13695466c07ce4c982fa98448e407a0.tar.bz2 |
Adds the ability for ObserverList to not notify observers added during
notification. I need this for bookmarks. If a new observer is added
while the bookmark model is in the process of sending out notification
the newly added observer gets confused.
BUG=674
TEST=none
Review URL: http://codereview.chromium.org/8919
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@4267 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/observer_list.h')
-rw-r--r-- | base/observer_list.h | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/base/observer_list.h b/base/observer_list.h index 52571df..9f8b5cf 100644 --- a/base/observer_list.h +++ b/base/observer_list.h @@ -5,8 +5,9 @@ #ifndef BASE_OBSERVER_LIST_H__ #define BASE_OBSERVER_LIST_H__ -#include <vector> #include <algorithm> +#include <limits> +#include <vector> #include "base/basictypes.h" #include "base/logging.h" @@ -52,12 +53,25 @@ // ObserverList<Observer> observer_list_; // }; // +// /////////////////////////////////////////////////////////////////////////////// template <class ObserverType, bool check_empty = false> class ObserverList { public: - ObserverList() : notify_depth_(0) {} + // Enumeration of which observers are notified. + enum NotificationType { + // Specifies that any observers added during notification are notified. + // This is the default type if non type is provided to the constructor. + NOTIFY_ALL, + + // Specifies that observers added while sending out notification are not + // notified. + NOTIFY_EXISTING_ONLY + }; + + ObserverList() : notify_depth_(0), type_(NOTIFY_ALL) {} + ObserverList(NotificationType type) : notify_depth_(0), type_(type) {} ~ObserverList() { // When check_empty is true, assert that the list is empty on destruction. if (check_empty) { @@ -98,7 +112,12 @@ class ObserverList { // also the FOREACH_OBSERVER macro defined below. class Iterator { public: - Iterator(const ObserverList<ObserverType>& list) : list_(list), index_(0) { + Iterator(const ObserverList<ObserverType>& list) + : list_(list), + index_(0), + max_index_(list.type_ == NOTIFY_ALL ? + std::numeric_limits<size_t>::max() : + list.observers_.size()) { ++list_.notify_depth_; } @@ -110,14 +129,16 @@ class ObserverList { ObserverType* GetNext() { ListType& observers = list_.observers_; // Advance if the current element is null - while (index_ < observers.size() && !observers[index_]) + size_t max_index = std::min(max_index_, observers.size()); + while (index_ < max_index && !observers[index_]) ++index_; - return index_ < observers.size() ? observers[index_++] : NULL; + return index_ < max_index ? observers[index_++] : NULL; } private: const ObserverList<ObserverType>& list_; size_t index_; + size_t max_index_; }; private: @@ -137,6 +158,7 @@ class ObserverList { // These are marked mutable to facilitate having NotifyAll be const. mutable ListType observers_; mutable int notify_depth_; + NotificationType type_; friend class ObserverList::Iterator; |