1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #ifndef BASE_SCOPED_OBSERVATION_TRAITS_H_ 6*6777b538SAndroid Build Coastguard Worker #define BASE_SCOPED_OBSERVATION_TRAITS_H_ 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker namespace base { 9*6777b538SAndroid Build Coastguard Worker 10*6777b538SAndroid Build Coastguard Worker // `ScopedObservationTraits` is used to control the behavior of 11*6777b538SAndroid Build Coastguard Worker // `ScopedObservation` on sources without AddObserver()/RemoveObserver() 12*6777b538SAndroid Build Coastguard Worker // methods. 13*6777b538SAndroid Build Coastguard Worker // 14*6777b538SAndroid Build Coastguard Worker // The implementation of `ScopedObservation<Source, Observer>` will look up the 15*6777b538SAndroid Build Coastguard Worker // most specialized version of `ScopedObservationTraits<Source, Observer>` and 16*6777b538SAndroid Build Coastguard Worker // use the corresponding `Traits::AddObserver` and `Traits::RemoveObserver`. 17*6777b538SAndroid Build Coastguard Worker // 18*6777b538SAndroid Build Coastguard Worker // The default specialization takes care of any Source that exposes 19*6777b538SAndroid Build Coastguard Worker // `AddObserver(Observer*)` and `RemoveObserver(Observer*)` methods -- if that's 20*6777b538SAndroid Build Coastguard Worker // the case, then `ScopedObservation<Source, Observer>` will work out of the 21*6777b538SAndroid Build Coastguard Worker // box. 22*6777b538SAndroid Build Coastguard Worker // 23*6777b538SAndroid Build Coastguard Worker // However, if your `CustomSource` features custom method names -- say, 24*6777b538SAndroid Build Coastguard Worker // `AddFoo(FooObserver*)` and `RemoveFoo(FooObserver*)`, then you'll have to 25*6777b538SAndroid Build Coastguard Worker // define a new traits specialization like this: 26*6777b538SAndroid Build Coastguard Worker // 27*6777b538SAndroid Build Coastguard Worker // `custom_source.h`: 28*6777b538SAndroid Build Coastguard Worker // #include "base/scoped_observation_traits.h" 29*6777b538SAndroid Build Coastguard Worker // 30*6777b538SAndroid Build Coastguard Worker // class FooObserver; 31*6777b538SAndroid Build Coastguard Worker // class CustomSource { 32*6777b538SAndroid Build Coastguard Worker // public: 33*6777b538SAndroid Build Coastguard Worker // void AddFoo(FooObserver*); 34*6777b538SAndroid Build Coastguard Worker // void RemoveFoo(FooObserver*); 35*6777b538SAndroid Build Coastguard Worker // }; 36*6777b538SAndroid Build Coastguard Worker // 37*6777b538SAndroid Build Coastguard Worker // namespace base { 38*6777b538SAndroid Build Coastguard Worker // 39*6777b538SAndroid Build Coastguard Worker // template<> 40*6777b538SAndroid Build Coastguard Worker // struct ScopedObservationTraits<CustomSource, FooObserver> { 41*6777b538SAndroid Build Coastguard Worker // static void AddObserver(CustomSource* source, 42*6777b538SAndroid Build Coastguard Worker // FooObserver* observer) { 43*6777b538SAndroid Build Coastguard Worker // source->AddFoo(observer); 44*6777b538SAndroid Build Coastguard Worker // } 45*6777b538SAndroid Build Coastguard Worker // static void RemoveObserver(CustomSource* source, 46*6777b538SAndroid Build Coastguard Worker // FooObserver* observer) { 47*6777b538SAndroid Build Coastguard Worker // source->RemoveFoo(observer); 48*6777b538SAndroid Build Coastguard Worker // } 49*6777b538SAndroid Build Coastguard Worker // }; 50*6777b538SAndroid Build Coastguard Worker // 51*6777b538SAndroid Build Coastguard Worker // } // namespace base 52*6777b538SAndroid Build Coastguard Worker // 53*6777b538SAndroid Build Coastguard Worker // `some_important_file.cc`: 54*6777b538SAndroid Build Coastguard Worker // // Now this works out of the box. 55*6777b538SAndroid Build Coastguard Worker // base::ScopedObservation<CustomSource, FooObserver> obs... 56*6777b538SAndroid Build Coastguard Worker // 57*6777b538SAndroid Build Coastguard Worker 58*6777b538SAndroid Build Coastguard Worker template <class Source, class Observer> 59*6777b538SAndroid Build Coastguard Worker struct ScopedObservationTraits { 60*6777b538SAndroid Build Coastguard Worker static_assert( 61*6777b538SAndroid Build Coastguard Worker requires(Source& source, Observer* observer) { 62*6777b538SAndroid Build Coastguard Worker source.AddObserver(observer); 63*6777b538SAndroid Build Coastguard Worker source.RemoveObserver(observer); 64*6777b538SAndroid Build Coastguard Worker }, 65*6777b538SAndroid Build Coastguard Worker "The given Source is missing " 66*6777b538SAndroid Build Coastguard Worker "AddObserver(Observer*) and/or RemoveObserver(Observer*) " 67*6777b538SAndroid Build Coastguard Worker "methods. Please provide a custom specialization of " 68*6777b538SAndroid Build Coastguard Worker "ScopedObservationTraits<> for this Source/Observer pair."); 69*6777b538SAndroid Build Coastguard Worker AddObserverScopedObservationTraits70*6777b538SAndroid Build Coastguard Worker static void AddObserver(Source* source, Observer* observer) { 71*6777b538SAndroid Build Coastguard Worker source->AddObserver(observer); 72*6777b538SAndroid Build Coastguard Worker } RemoveObserverScopedObservationTraits73*6777b538SAndroid Build Coastguard Worker static void RemoveObserver(Source* source, Observer* observer) { 74*6777b538SAndroid Build Coastguard Worker source->RemoveObserver(observer); 75*6777b538SAndroid Build Coastguard Worker } 76*6777b538SAndroid Build Coastguard Worker }; 77*6777b538SAndroid Build Coastguard Worker 78*6777b538SAndroid Build Coastguard Worker } // namespace base 79*6777b538SAndroid Build Coastguard Worker 80*6777b538SAndroid Build Coastguard Worker #endif // BASE_SCOPED_OBSERVATION_TRAITS_H_ 81