scoped_multi_source_observation.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  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.
  4. #ifndef BASE_SCOPED_MULTI_SOURCE_OBSERVATION_H_
  5. #define BASE_SCOPED_MULTI_SOURCE_OBSERVATION_H_
  6. #include <stddef.h>
  7. #include <vector>
  8. #include "base/check.h"
  9. #include "base/containers/contains.h"
  10. #include "base/memory/raw_ptr.h"
  11. #include "base/ranges/algorithm.h"
  12. namespace base {
  13. // ScopedMultiSourceObservation is used to keep track of plural observation,
  14. // e.g. where an observer observes more than a single source.
  15. //
  16. // Use base::ScopedObservation for objects that observe only a single source.
  17. //
  18. // When ScopedMultiSourceObservation is destroyed, it removes the object as an
  19. // observer from all sources it has been added to.
  20. // Basic example (as a member variable):
  21. //
  22. // class MyFooObserver : public FooObserver {
  23. // ...
  24. // private:
  25. // ScopedMultiSourceObservation<Foo, FooObserver> foo_observations_{this};
  26. // };
  27. //
  28. // MyFooObserver::OnFooCreated(Foo* foo) {
  29. // foo_observations_.AddObservation(foo);
  30. // }
  31. //
  32. // For cases with methods not named AddObserver/RemoveObserver:
  33. //
  34. // class MyFooStateObserver : public FooStateObserver {
  35. // ...
  36. // private:
  37. // ScopedMultiSourceObservation<Foo,
  38. // FooStateObserver,
  39. // &Foo::AddStateObserver,
  40. // &Foo::RemoveStateObserver>
  41. // foo_observations_{this};
  42. // };
  43. template <class Source,
  44. class Observer,
  45. void (Source::*AddObsFn)(Observer*) = &Source::AddObserver,
  46. void (Source::*RemoveObsFn)(Observer*) = &Source::RemoveObserver>
  47. class ScopedMultiSourceObservation {
  48. public:
  49. explicit ScopedMultiSourceObservation(Observer* observer)
  50. : observer_(observer) {}
  51. ScopedMultiSourceObservation(const ScopedMultiSourceObservation&) = delete;
  52. ScopedMultiSourceObservation& operator=(const ScopedMultiSourceObservation&) =
  53. delete;
  54. ~ScopedMultiSourceObservation() { RemoveAllObservations(); }
  55. // Adds the object passed to the constructor as an observer on |source|.
  56. void AddObservation(Source* source) {
  57. sources_.push_back(source);
  58. (source->*AddObsFn)(observer_);
  59. }
  60. // Remove the object passed to the constructor as an observer from |source|.
  61. void RemoveObservation(Source* source) {
  62. auto it = base::ranges::find(sources_, source);
  63. DCHECK(it != sources_.end());
  64. sources_.erase(it);
  65. (source->*RemoveObsFn)(observer_);
  66. }
  67. // Remove the object passed to the constructor as an observer from all sources
  68. // it's observing.
  69. void RemoveAllObservations() {
  70. for (Source* source : sources_)
  71. (source->*RemoveObsFn)(observer_);
  72. sources_.clear();
  73. }
  74. // Returns true if any source is being observed.
  75. bool IsObservingAnySource() const { return !sources_.empty(); }
  76. // Returns true if |source| is being observed.
  77. bool IsObservingSource(Source* source) const {
  78. DCHECK(source);
  79. return base::Contains(sources_, source);
  80. }
  81. // Returns the number of sources being observed.
  82. size_t GetSourcesCount() const { return sources_.size(); }
  83. private:
  84. const raw_ptr<Observer> observer_;
  85. std::vector<Source*> sources_;
  86. };
  87. } // namespace base
  88. #endif // BASE_SCOPED_MULTI_SOURCE_OBSERVATION_H_