scoped_observer.h 2.4 KB

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