1 // Copyright 2013 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.
5 #ifndef ASH_SHELF_SCOPED_OBSERVER_WITH_DUPLICATED_SOURCES_H_
6 #define ASH_SHELF_SCOPED_OBSERVER_WITH_DUPLICATED_SOURCES_H_
10 #include "base/basictypes.h"
11 #include "base/logging.h"
13 // ScopedObserverWithDuplicatedSources is used to keep track of the set of
14 // sources an object has attached itself to as an observer. When
15 // ScopedObserverWithDuplicatedSources is destroyed it removes the object as an
16 // observer from all sources it has been added to.
17 // ScopedObserverWithDuplicatedSources adds |observer| once for a particular
18 // source, no matter how many times Add() is invoked. Additionaly |observer| is
19 // only removed once Remove() is invoked the same number of times as Add().
21 template <class Source
, class Observer
>
22 class ScopedObserverWithDuplicatedSources
{
24 explicit ScopedObserverWithDuplicatedSources(Observer
* observer
)
25 : observer_(observer
) {}
27 ~ScopedObserverWithDuplicatedSources() {
28 typename
SourceToAddCountMap::const_iterator iter
=
29 counted_sources_
.begin();
30 for (; iter
!= counted_sources_
.end(); ++iter
)
31 iter
->first
->RemoveObserver(observer_
);
34 // Adds the object passed to the constructor only once as an observer on
36 void Add(Source
* source
) {
37 if (counted_sources_
.find(source
) == counted_sources_
.end())
38 source
->AddObserver(observer_
);
39 counted_sources_
[source
]++;
42 // Only remove the object passed to the constructor as an observer from
43 // |source| when Remove() is invoked the same number of times as Add().
44 void Remove(Source
* source
) {
45 typename
SourceToAddCountMap::iterator iter
=
46 counted_sources_
.find(source
);
47 DCHECK(iter
!= counted_sources_
.end() && iter
->second
> 0);
49 if (--iter
->second
== 0) {
50 counted_sources_
.erase(source
);
51 source
->RemoveObserver(observer_
);
55 bool IsObserving(Source
* source
) const {
56 return counted_sources_
.find(source
) != counted_sources_
.end();
60 typedef std::map
<Source
*, int> SourceToAddCountMap
;
64 // Map Source and its adding count.
65 std::map
<Source
*, int> counted_sources_
;
67 DISALLOW_COPY_AND_ASSIGN(ScopedObserverWithDuplicatedSources
);
70 #endif // ASH_SHELF_SCOPED_OBSERVER_WITH_DUPLICATED_SOURCES_H_