chromium/base/scoped_observation.h

// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef BASE_SCOPED_OBSERVATION_H_
#define BASE_SCOPED_OBSERVATION_H_

#include <utility>

#include "base/check.h"
#include "base/check_op.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_observation_traits.h"

namespace base {

// `ScopedObservation` is used to keep track of a singular observation, i.e.,
// where an observer observes a single source only. Use
// `base::ScopedMultiSourceObservation` for objects that observe multiple
// sources.
//
// When a `ScopedObservation` is destroyed, it unregisters the observer from the
// observable if it was currently observing something. Otherwise it does
// nothing.
//
// Using a `ScopedObservation` instead of manually observing and unobserving has
// the following benefits:
// - The observer cannot accidentally forget to stop observing when it is
//   destroyed.
// - By calling `Reset`, an ongoing observation can be stopped before the
//   `ScopedObservation` is destroyed. If nothing was currently observed, then
//   calling `Reset` does nothing. This can be useful for when the observable is
//   destroyed before the observer is destroyed, because it prevents the
//   observer from accidentally unregistering itself from the destroyed
//   observable a second time when it itself is destroyed. Without
//   `ScopedObservation`, one might need to keep track of whether one has
//   already stopped observing in a separate boolean.
//
// A complete usage example can be found below.
//
// `observer.h`:
//   class Observer {
//    public:
//     virtual ~Observer() {}
//
//     virtual void OnEvent() {}
//   };
//
// `source.h`:
//   class Observer;
//   class Source {
//    public:
//     void AddObserver(Observer* observer);
//     void RemoveObserver(Observer* observer);
//   };
//
// `observer_impl.h`:
//   #include "observer.h"
//
//   class Source;
//
//   class ObserverImpl: public Observer {
//    public:
//     ObserverImpl(Source* source);
//     // Note how there is no need to stop observing in the destructor.
//     ~ObserverImpl() override {}
//
//     void OnEvent() override {
//       ...
//     }
//
//    private:
//     // Note that |obs_| can be instantiated with forward-declared Source.
//     base::ScopedObservation<Source, Observer> obs_{this};
//   };
//
// `observer_impl.cc`:
//   #include "observer_impl.h"
//   #include "source.h"
//
//   ObserverImpl::ObserverImpl(Source* source) {
//     // After the call |this| starts listening to events from |source|.
//     obs_.Observe(source);
//   }
//
////////////////////////////////////////////////////////////////////////////////
//
// By default `ScopedObservation` only works with sources that expose
// `AddObserver` and `RemoveObserver`. However, it's also possible to
// adapt it to custom function names (say `AddFoo` and `RemoveFoo` accordingly)
// by tailoring ScopedObservationTraits<> for the given Source and Observer --
// see `base/scoped_observation_traits.h` for details.
//

template <class Source, class Observer>
class ScopedObservation {};

}  // namespace base

#endif  // BASE_SCOPED_OBSERVATION_H_