verdnatura-chat/ios/Pods/Flipper-RSocket/yarpl/observable/ObservableConcatOperators.h

155 lines
4.4 KiB
C++

// Copyright (c) Facebook, Inc. and its affiliates.
//
// 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 "yarpl/observable/ObservableOperator.h"
namespace yarpl {
namespace observable {
namespace details {
template <typename T>
class ConcatWithOperator : public ObservableOperator<T, T> {
using Super = ObservableOperator<T, T>;
public:
ConcatWithOperator(
std::shared_ptr<Observable<T>> first,
std::shared_ptr<Observable<T>> second)
: first_(std::move(first)), second_(std::move(second)) {
CHECK(first_);
CHECK(second_);
}
std::shared_ptr<Subscription> subscribe(
std::shared_ptr<Observer<T>> observer) override {
auto subscription =
std::make_shared<ConcatWithSubscription>(observer, first_, second_);
subscription->init();
return subscription;
}
private:
class ForwardObserver;
// Downstream will always point to this subscription
class ConcatWithSubscription
: public yarpl::observable::Subscription,
public std::enable_shared_from_this<ConcatWithSubscription> {
public:
ConcatWithSubscription(
std::shared_ptr<Observer<T>> observer,
std::shared_ptr<Observable<T>> first,
std::shared_ptr<Observable<T>> second)
: downObserver_(std::move(observer)),
first_(std::move(first)),
second_(std::move(second)) {}
void init() {
upObserver_ = std::make_shared<ForwardObserver>(this->shared_from_this());
downObserver_->onSubscribe(this->shared_from_this());
if (upObserver_) {
first_->subscribe(upObserver_);
}
}
void cancel() override {
if (auto observer = std::move(upObserver_)) {
observer->cancel();
}
first_.reset();
second_.reset();
upObserver_.reset();
downObserver_.reset();
}
void onNext(T value) {
downObserver_->onNext(std::move(value));
}
void onComplete() {
if (auto first = std::move(first_)) {
upObserver_ =
std::make_shared<ForwardObserver>(this->shared_from_this());
second_->subscribe(upObserver_);
second_.reset();
} else {
downObserver_->onComplete();
downObserver_.reset();
}
}
void onError(folly::exception_wrapper ew) {
downObserver_->onError(std::move(ew));
first_.reset();
second_.reset();
upObserver_.reset();
downObserver_.reset();
}
private:
std::shared_ptr<Observer<T>> downObserver_;
std::shared_ptr<Observable<T>> first_;
std::shared_ptr<Observable<T>> second_;
std::shared_ptr<ForwardObserver> upObserver_;
};
class ForwardObserver : public yarpl::observable::Observer<T>,
public yarpl::observable::Subscription {
public:
ForwardObserver(
std::shared_ptr<ConcatWithSubscription> concatWithSubscription)
: concatWithSubscription_(std::move(concatWithSubscription)) {}
void cancel() override {
if (auto subs = std::move(subscription_)) {
subs->cancel();
}
}
void onSubscribe(std::shared_ptr<Subscription> subscription) override {
// Don't forward the subscription to downstream observer
subscription_ = std::move(subscription);
}
void onComplete() override {
concatWithSubscription_->onComplete();
concatWithSubscription_.reset();
}
void onError(folly::exception_wrapper ew) override {
concatWithSubscription_->onError(std::move(ew));
concatWithSubscription_.reset();
}
void onNext(T value) override {
concatWithSubscription_->onNext(std::move(value));
}
private:
std::shared_ptr<ConcatWithSubscription> concatWithSubscription_;
std::shared_ptr<observable::Subscription> subscription_;
};
private:
const std::shared_ptr<Observable<T>> first_;
const std::shared_ptr<Observable<T>> second_;
};
} // namespace details
} // namespace observable
} // namespace yarpl