scoped_observer.h 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. // Copyright (c) 2012 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_OBSERVER_H_
  5. #define BASE_SCOPED_OBSERVER_H_
  6. #include <stddef.h>
  7. #include <algorithm>
  8. #include <vector>
  9. #include "base/check.h"
  10. #include "base/stl_util.h"
  11. // ScopedObserver is used to keep track of the set of sources an object has
  12. // attached itself to as an observer. When ScopedObserver is destroyed it
  13. // removes the object as an observer from all sources it has been added to.
  14. // Basic example (as a member variable):
  15. //
  16. // class MyFooObserver : public FooObserver {
  17. // ...
  18. // private:
  19. // ScopedObserver<Foo, FooObserver> observed_foo_{this};
  20. // };
  21. //
  22. // For cases with methods not named AddObserver/RemoveObserver:
  23. //
  24. // class MyFooStateObserver : public FooStateObserver {
  25. // ...
  26. // private:
  27. // ScopedObserver<Foo,
  28. // FooStateObserver,
  29. // &Foo::AddStateObserver,
  30. // &Foo::RemoveStateObserver>
  31. // observed_foo_{this};
  32. // };
  33. template <class Source,
  34. class Observer,
  35. void (Source::*AddObsFn)(Observer*) = &Source::AddObserver,
  36. void (Source::*RemoveObsFn)(Observer*) = &Source::RemoveObserver>
  37. class ScopedObserver {
  38. public:
  39. explicit ScopedObserver(Observer* observer) : observer_(observer) {}
  40. ScopedObserver(const ScopedObserver&) = delete;
  41. ScopedObserver& operator=(const ScopedObserver&) = delete;
  42. ~ScopedObserver() {
  43. RemoveAll();
  44. }
  45. // Adds the object passed to the constructor as an observer on |source|.
  46. void Add(Source* source) {
  47. sources_.push_back(source);
  48. (source->*AddObsFn)(observer_);
  49. }
  50. // Remove the object passed to the constructor as an observer from |source|.
  51. void Remove(Source* source) {
  52. auto it = std::find(sources_.begin(), sources_.end(), source);
  53. DCHECK(it != sources_.end());
  54. sources_.erase(it);
  55. (source->*RemoveObsFn)(observer_);
  56. }
  57. void RemoveAll() {
  58. for (size_t i = 0; i < sources_.size(); ++i)
  59. (sources_[i]->*RemoveObsFn)(observer_);
  60. sources_.clear();
  61. }
  62. bool IsObserving(Source* source) const {
  63. return base::Contains(sources_, source);
  64. }
  65. bool IsObservingSources() const { return !sources_.empty(); }
  66. size_t GetSourcesCount() const { return sources_.size(); }
  67. private:
  68. Observer* observer_;
  69. std::vector<Source*> sources_;
  70. };
  71. #endif // BASE_SCOPED_OBSERVER_H_