/* * Copyright 2016-present Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include namespace folly { namespace observer { template Snapshot Observer::getSnapshot() const { auto data = core_->getData(); return Snapshot( *core_, std::static_pointer_cast(std::move(data.data)), data.version); } template Observer::Observer(observer_detail::Core::Ptr core) : core_(std::move(core)) {} template Observer> makeObserver( F&& creator) { auto core = observer_detail::Core::create( [creator = std::forward(creator)]() mutable { return std::static_pointer_cast(creator()); }); observer_detail::ObserverManager::initCore(core); return Observer>(core); } template Observer> makeObserver(F&& creator) { return makeObserver([creator = std::forward(creator)]() mutable { return std::make_shared>(creator()); }); } template TLObserver::TLObserver(Observer observer) : observer_(observer), snapshot_([&] { return new Snapshot(observer_.getSnapshot()); }) {} template TLObserver::TLObserver(const TLObserver& other) : TLObserver(other.observer_) {} template const Snapshot& TLObserver::getSnapshotRef() const { auto& snapshot = *snapshot_; if (observer_.needRefresh(snapshot) || observer_detail::ObserverManager::inManagerThread()) { snapshot = observer_.getSnapshot(); } return snapshot; } struct CallbackHandle::Context { Optional> observer; Synchronized canceled{false}; }; inline CallbackHandle::CallbackHandle() {} template CallbackHandle::CallbackHandle( Observer observer, folly::Function)> callback) { context_ = std::make_shared(); context_->observer = makeObserver([observer = std::move(observer), callback = std::move(callback), context = context_]() mutable { auto rCanceled = context->canceled.rlock(); if (*rCanceled) { return folly::unit; } callback(*observer); return folly::unit; }); } inline CallbackHandle::~CallbackHandle() { cancel(); } inline void CallbackHandle::cancel() { if (!context_) { return; } context_->observer.reset(); context_->canceled = true; context_.reset(); } template CallbackHandle Observer::addCallback( folly::Function)> callback) const { return CallbackHandle(*this, std::move(callback)); } } // namespace observer } // namespace folly