Observer-inl.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /*
  2. * Copyright 2016-present Facebook, Inc.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #pragma once
  17. #include <folly/experimental/observer/detail/ObserverManager.h>
  18. namespace folly {
  19. namespace observer {
  20. template <typename T>
  21. Snapshot<T> Observer<T>::getSnapshot() const {
  22. auto data = core_->getData();
  23. return Snapshot<T>(
  24. *core_,
  25. std::static_pointer_cast<const T>(std::move(data.data)),
  26. data.version);
  27. }
  28. template <typename T>
  29. Observer<T>::Observer(observer_detail::Core::Ptr core)
  30. : core_(std::move(core)) {}
  31. template <typename F>
  32. Observer<observer_detail::ResultOfUnwrapSharedPtr<F>> makeObserver(
  33. F&& creator) {
  34. auto core = observer_detail::Core::create(
  35. [creator = std::forward<F>(creator)]() mutable {
  36. return std::static_pointer_cast<const void>(creator());
  37. });
  38. observer_detail::ObserverManager::initCore(core);
  39. return Observer<observer_detail::ResultOfUnwrapSharedPtr<F>>(core);
  40. }
  41. template <typename F>
  42. Observer<observer_detail::ResultOf<F>> makeObserver(F&& creator) {
  43. return makeObserver([creator = std::forward<F>(creator)]() mutable {
  44. return std::make_shared<observer_detail::ResultOf<F>>(creator());
  45. });
  46. }
  47. template <typename T>
  48. TLObserver<T>::TLObserver(Observer<T> observer)
  49. : observer_(observer),
  50. snapshot_([&] { return new Snapshot<T>(observer_.getSnapshot()); }) {}
  51. template <typename T>
  52. TLObserver<T>::TLObserver(const TLObserver<T>& other)
  53. : TLObserver(other.observer_) {}
  54. template <typename T>
  55. const Snapshot<T>& TLObserver<T>::getSnapshotRef() const {
  56. auto& snapshot = *snapshot_;
  57. if (observer_.needRefresh(snapshot) ||
  58. observer_detail::ObserverManager::inManagerThread()) {
  59. snapshot = observer_.getSnapshot();
  60. }
  61. return snapshot;
  62. }
  63. struct CallbackHandle::Context {
  64. Optional<Observer<folly::Unit>> observer;
  65. Synchronized<bool> canceled{false};
  66. };
  67. inline CallbackHandle::CallbackHandle() {}
  68. template <typename T>
  69. CallbackHandle::CallbackHandle(
  70. Observer<T> observer,
  71. folly::Function<void(Snapshot<T>)> callback) {
  72. context_ = std::make_shared<Context>();
  73. context_->observer = makeObserver([observer = std::move(observer),
  74. callback = std::move(callback),
  75. context = context_]() mutable {
  76. auto rCanceled = context->canceled.rlock();
  77. if (*rCanceled) {
  78. return folly::unit;
  79. }
  80. callback(*observer);
  81. return folly::unit;
  82. });
  83. }
  84. inline CallbackHandle::~CallbackHandle() {
  85. cancel();
  86. }
  87. inline void CallbackHandle::cancel() {
  88. if (!context_) {
  89. return;
  90. }
  91. context_->observer.reset();
  92. context_->canceled = true;
  93. context_.reset();
  94. }
  95. template <typename T>
  96. CallbackHandle Observer<T>::addCallback(
  97. folly::Function<void(Snapshot<T>)> callback) const {
  98. return CallbackHandle(*this, std::move(callback));
  99. }
  100. } // namespace observer
  101. } // namespace folly