mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-22 03:08:48 +00:00
Add rpl::take(count).
This commit is contained in:
parent
f0ad78d808
commit
c4d33f9986
@ -20,6 +20,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "boxes/change_phone_box.h"
|
||||
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/mappers.h>
|
||||
#include <rpl/take.h>
|
||||
#include "lang/lang_keys.h"
|
||||
#include "styles/style_boxes.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
@ -39,13 +42,19 @@ void createErrorLabel(
|
||||
int y) {
|
||||
if (label) {
|
||||
label->hide(anim::type::normal);
|
||||
auto context = label.data();
|
||||
App::CallDelayed(
|
||||
st::fadeWrapDuration,
|
||||
context,
|
||||
[old = std::move(label)]() mutable {
|
||||
old.destroy();
|
||||
});
|
||||
|
||||
auto saved = label.data();
|
||||
auto destroy = [old = std::move(label)]() mutable {
|
||||
old.destroyDelayed();
|
||||
};
|
||||
|
||||
using namespace rpl::mappers;
|
||||
saved->shownValue()
|
||||
| rpl::filter($1 == false)
|
||||
| rpl::take(1)
|
||||
| rpl::start_with_done(
|
||||
std::move(destroy),
|
||||
saved->lifetime());
|
||||
}
|
||||
if (!text.isEmpty()) {
|
||||
label.create(
|
||||
|
@ -388,4 +388,18 @@ TEST_CASE("basic operators tests", "[rpl::operators]") {
|
||||
}
|
||||
REQUIRE(*sum == "0-11-22-3");
|
||||
}
|
||||
|
||||
SECTION("take test") {
|
||||
auto sum = std::make_shared<std::string>("");
|
||||
{
|
||||
rpl::lifetime lifetime;
|
||||
rpl::ints(10) | take(3)
|
||||
| start_with_next_done([=](int value) {
|
||||
*sum += std::to_string(value);
|
||||
}, [=] {
|
||||
*sum += "done";
|
||||
}, lifetime);
|
||||
}
|
||||
REQUIRE(*sum == "012done");
|
||||
}
|
||||
}
|
||||
|
@ -30,6 +30,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
#include <rpl/fail.h>
|
||||
#include <rpl/never.h>
|
||||
|
||||
#include <rpl/take.h>
|
||||
#include <rpl/then.h>
|
||||
#include <rpl/deferred.h>
|
||||
#include <rpl/map.h>
|
||||
|
74
Telegram/SourceFiles/rpl/take.h
Normal file
74
Telegram/SourceFiles/rpl/take.h
Normal file
@ -0,0 +1,74 @@
|
||||
/*
|
||||
This file is part of Telegram Desktop,
|
||||
the official desktop version of Telegram messaging app, see https://telegram.org
|
||||
|
||||
Telegram Desktop is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
It is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
In addition, as a special exception, the copyright holders give permission
|
||||
to link the code of portions of this program with the OpenSSL library.
|
||||
|
||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace rpl {
|
||||
namespace details {
|
||||
|
||||
class take_helper {
|
||||
public:
|
||||
take_helper(int count) : _count(count) {
|
||||
}
|
||||
|
||||
template <
|
||||
typename Value,
|
||||
typename Error,
|
||||
typename Generator>
|
||||
auto operator()(producer<Value, Error, Generator> &&initial) {
|
||||
return make_producer<Value, Error>([
|
||||
initial = std::move(initial),
|
||||
limit = _count
|
||||
](const auto &consumer) mutable {
|
||||
auto count = consumer.template make_state<int>(limit);
|
||||
return std::move(initial).start(
|
||||
[consumer, count](auto &&value) {
|
||||
auto left = (*count)--;
|
||||
if (left) {
|
||||
consumer.put_next_forward(
|
||||
std::forward<decltype(value)>(value));
|
||||
--left;
|
||||
}
|
||||
if (!left) {
|
||||
consumer.put_done();
|
||||
}
|
||||
}, [consumer](auto &&error) {
|
||||
consumer.put_error_forward(
|
||||
std::forward<decltype(error)>(error));
|
||||
}, [consumer] {
|
||||
consumer.put_done();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
int _count = 0;
|
||||
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
inline auto take(int count)
|
||||
-> details::take_helper {
|
||||
Expects(count >= 0);
|
||||
return details::take_helper(count);
|
||||
}
|
||||
|
||||
|
||||
} // namespace rpl
|
@ -20,8 +20,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "ui/abstract_button.h"
|
||||
|
||||
#include <rpl/filter.h>
|
||||
#include <rpl/mappers.h>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
AbstractButton::AbstractButton(QWidget *parent) : RpWidget(parent) {
|
||||
setMouseTracking(true);
|
||||
|
||||
using namespace rpl::mappers;
|
||||
shownValue()
|
||||
| rpl::filter($1 == false)
|
||||
| rpl::start_with_next([this] { clearState(); }, lifetime());
|
||||
}
|
||||
|
||||
void AbstractButton::leaveEventHook(QEvent *e) {
|
||||
if (_state & StateFlag::Down) return;
|
||||
|
||||
|
@ -30,9 +30,7 @@ class AbstractButton : public RpWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
AbstractButton(QWidget *parent) : RpWidget(parent) {
|
||||
setMouseTracking(true);
|
||||
}
|
||||
AbstractButton(QWidget *parent);
|
||||
|
||||
Qt::KeyboardModifiers clickModifiers() const {
|
||||
return _modifiers;
|
||||
@ -58,13 +56,6 @@ public:
|
||||
_clickedCallback = std::move(callback);
|
||||
}
|
||||
|
||||
void setVisible(bool visible) override {
|
||||
TWidget::setVisible(visible);
|
||||
if (!visible) {
|
||||
clearState();
|
||||
}
|
||||
}
|
||||
|
||||
auto clicks() const {
|
||||
return _clicks.events();
|
||||
}
|
||||
|
@ -100,7 +100,6 @@ void FadeAnimation::stopAnimation() {
|
||||
_animation.finish();
|
||||
if (!_cache.isNull()) {
|
||||
_cache = QPixmap();
|
||||
updateCallback();
|
||||
if (_visible) {
|
||||
_widget->showChildren();
|
||||
}
|
||||
|
@ -76,6 +76,10 @@ public:
|
||||
virtual rpl::producer<int> desiredHeightValue() const {
|
||||
return heightValue();
|
||||
}
|
||||
auto shownValue() const {
|
||||
auto &stream = eventStreams().shown;
|
||||
return stream.events_starting_with(!this->isHidden());
|
||||
}
|
||||
|
||||
auto paintRequest() const {
|
||||
return eventStreams().paint.events();
|
||||
@ -85,6 +89,17 @@ public:
|
||||
return eventStreams().alive.events();
|
||||
}
|
||||
|
||||
void setVisible(bool visible) final override {
|
||||
auto wasVisible = !this->isHidden();
|
||||
Parent::setVisible(visible);
|
||||
auto nowVisible = !this->isHidden();
|
||||
if (nowVisible != wasVisible) {
|
||||
if (auto streams = _eventStreams.get()) {
|
||||
streams->shown.fire_copy(nowVisible);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Error, typename Generator>
|
||||
void showOn(rpl::producer<bool, Error, Generator> &&shown) {
|
||||
std::move(shown)
|
||||
@ -133,6 +148,7 @@ private:
|
||||
struct EventStreams {
|
||||
rpl::event_stream<QRect> geometry;
|
||||
rpl::event_stream<QRect> paint;
|
||||
rpl::event_stream<bool> shown;
|
||||
rpl::event_stream<> alive;
|
||||
};
|
||||
struct LifetimeHolder {
|
||||
|
@ -121,6 +121,7 @@
|
||||
'<(src_loc)/rpl/producer_tests.cpp',
|
||||
'<(src_loc)/rpl/range.h',
|
||||
'<(src_loc)/rpl/rpl.h',
|
||||
'<(src_loc)/rpl/take.h',
|
||||
'<(src_loc)/rpl/then.h',
|
||||
'<(src_loc)/rpl/type_erased.h',
|
||||
'<(src_loc)/rpl/variable.h',
|
||||
|
Loading…
Reference in New Issue
Block a user