1 // Copyright 2020 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 BASE_SCOPED_OBSERVATION_H_
6 #define BASE_SCOPED_OBSERVATION_H_
10 #include "base/check_op.h"
14 // ScopedObservation is used to keep track of singular observation, e.g.
15 // where an observer observes a single source only.
17 // Use base::ScopedMultiSourceObservation for objects that observe multiple
20 // When ScopedObservation is destroyed, it removes the registered observation,
21 // if any. Basic example (as a member variable):
23 // class MyFooObserver : public FooObserver {
26 // ScopedObservation<Foo, FooObserver> foo_observation_{this};
29 // MyFooObserver::MyFooObserver(Foo* foo) {
30 // foo_observation_.Observe(foo);
33 // For cases with methods not named AddObserver/RemoveObserver:
35 // class MyFooStateObserver : public FooStateObserver {
38 // ScopedObservation<Foo,
40 // &Foo::AddStateObserver,
41 // &Foo::RemoveStateObserver>
42 // foo_observation_{this};
44 template <class Source,
46 void (Source::*AddObsFn)(Observer*) = &Source::AddObserver,
47 void (Source::*RemoveObsFn)(Observer*) = &Source::RemoveObserver>
48 class ScopedObservation {
50 explicit ScopedObservation(Observer* observer) : observer_(observer) {}
51 ScopedObservation(const ScopedObservation&) = delete;
52 ScopedObservation& operator=(const ScopedObservation&) = delete;
53 ~ScopedObservation() { Reset(); }
55 // Adds the object passed to the constructor as an observer on |source|.
56 // IsObserving() must be false.
57 void Observe(Source* source) {
58 // TODO(https://crbug.com/1145565): Make this a DCHECK once ScopedObserver
59 // has been fully retired.
60 CHECK_EQ(source_, nullptr);
62 (source_->*AddObsFn)(observer_);
65 // Remove the object passed to the constructor as an observer from |source_|
66 // if currently observing. Does nothing otherwise.
69 (source_->*RemoveObsFn)(observer_);
74 // Returns true if any source is being observed.
75 bool IsObserving() const { return source_ != nullptr; }
77 // Returns true if |source| is being observed.
78 bool IsObservingSource(Source* source) const {
80 return source_ == source;
84 Observer* const observer_;
86 // The observed source, if any.
87 Source* source_ = nullptr;
92 #endif // BASE_SCOPED_OBSERVATION_H_