// 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_