mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-01-11 09:19:35 +00:00
Don't restart animations timer.
This commit is contained in:
parent
7808620764
commit
392d90dc1d
@ -14,7 +14,7 @@ namespace Ui {
|
||||
namespace Animations {
|
||||
namespace {
|
||||
|
||||
constexpr auto kAnimationTimeout = crl::time(1000) / 60;
|
||||
constexpr auto kAnimationTick = crl::time(1000) / 60;
|
||||
constexpr auto kIgnoreUpdatesTimeout = crl::time(4);
|
||||
|
||||
} // namespace
|
||||
@ -53,21 +53,22 @@ void Basic::markStopped() {
|
||||
|
||||
Manager::Manager() {
|
||||
Core::Sandbox::Instance().widgetUpdateRequests(
|
||||
) | rpl::filter([=] {
|
||||
/*) | rpl::filter([=] {
|
||||
return (_lastUpdateTime + kIgnoreUpdatesTimeout < crl::now());
|
||||
}) | rpl::start_with_next([=] {
|
||||
update();
|
||||
}*/) | rpl::start_with_next([=] {
|
||||
update(UpdateSource::RepaintRequest);
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
void Manager::start(not_null<Basic*> animation) {
|
||||
_forceImmediateUpdate = true;
|
||||
_forceUpdateProcessing = true;
|
||||
if (_updating) {
|
||||
_starting.emplace_back(animation.get());
|
||||
} else {
|
||||
schedule();
|
||||
_active.emplace_back(animation.get());
|
||||
return;
|
||||
}
|
||||
_active.emplace_back(animation.get());
|
||||
startTimer();
|
||||
updateQueued();
|
||||
}
|
||||
|
||||
void Manager::stop(not_null<Basic*> animation) {
|
||||
@ -89,15 +90,16 @@ void Manager::stop(not_null<Basic*> animation) {
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::update() {
|
||||
if (_active.empty() || _updating || _scheduled) {
|
||||
void Manager::update(UpdateSource source) {
|
||||
if (_active.empty() || _updating) {
|
||||
return;
|
||||
}
|
||||
const auto now = crl::now();
|
||||
if (_forceImmediateUpdate) {
|
||||
_forceImmediateUpdate = false;
|
||||
if (_forceUpdateProcessing) {
|
||||
_forceUpdateProcessing = false;
|
||||
} else if (now < _lastUpdateTime + kIgnoreUpdatesTimeout) {
|
||||
return;
|
||||
}
|
||||
schedule();
|
||||
|
||||
_updating = true;
|
||||
const auto guard = gsl::finally([&] { _updating = false; });
|
||||
@ -108,48 +110,30 @@ void Manager::update() {
|
||||
};
|
||||
_active.erase(ranges::remove_if(_active, isFinished), end(_active));
|
||||
|
||||
if (!empty(_starting)) {
|
||||
_active.insert(
|
||||
end(_active),
|
||||
std::make_move_iterator(begin(_starting)),
|
||||
std::make_move_iterator(end(_starting)));
|
||||
_starting.clear();
|
||||
if (empty(_starting)) {
|
||||
if (empty(_active)) {
|
||||
stopTimer();
|
||||
}
|
||||
return;
|
||||
}
|
||||
_active.insert(
|
||||
end(_active),
|
||||
std::make_move_iterator(begin(_starting)),
|
||||
std::make_move_iterator(end(_starting)));
|
||||
_starting.clear();
|
||||
if (_forceUpdateProcessing) {
|
||||
updateQueued();
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::updateQueued() {
|
||||
Expects(_timerId == 0);
|
||||
|
||||
_timerId = -1;
|
||||
crl::on_main(delayedCallGuard(), [=] {
|
||||
Expects(_timerId < 0);
|
||||
|
||||
_timerId = 0;
|
||||
update();
|
||||
});
|
||||
}
|
||||
|
||||
void Manager::schedule() {
|
||||
if (_scheduled || _timerId < 0) {
|
||||
if (_queued) {
|
||||
return;
|
||||
}
|
||||
stopTimer();
|
||||
|
||||
_scheduled = true;
|
||||
Ui::PostponeCall(delayedCallGuard(), [=] {
|
||||
_scheduled = false;
|
||||
if (_forceImmediateUpdate) {
|
||||
_forceImmediateUpdate = false;
|
||||
updateQueued();
|
||||
} else {
|
||||
const auto next = _lastUpdateTime + kAnimationTimeout;
|
||||
const auto now = crl::now();
|
||||
if (now < next) {
|
||||
_timerId = startTimer(next - now, Qt::PreciseTimer);
|
||||
} else {
|
||||
updateQueued();
|
||||
}
|
||||
}
|
||||
_queued = true;
|
||||
crl::on_main(delayedCallGuard(), [=] {
|
||||
_queued = false;
|
||||
update(UpdateSource::Queued);
|
||||
});
|
||||
}
|
||||
|
||||
@ -157,14 +141,22 @@ not_null<const QObject*> Manager::delayedCallGuard() const {
|
||||
return static_cast<const QObject*>(this);
|
||||
}
|
||||
|
||||
void Manager::stopTimer() {
|
||||
if (_timerId > 0) {
|
||||
killTimer(base::take(_timerId));
|
||||
void Manager::startTimer() {
|
||||
if (_timerId) {
|
||||
return;
|
||||
}
|
||||
_timerId = QObject::startTimer(kAnimationTick, Qt::PreciseTimer);
|
||||
}
|
||||
|
||||
void Manager::stopTimer() {
|
||||
if (!_timerId) {
|
||||
return;
|
||||
}
|
||||
killTimer(base::take(_timerId));
|
||||
}
|
||||
|
||||
void Manager::timerEvent(QTimerEvent *e) {
|
||||
update();
|
||||
update(UpdateSource::TimerEvent);
|
||||
}
|
||||
|
||||
} // namespace Animations
|
||||
|
@ -101,9 +101,13 @@ class Manager final : private QObject {
|
||||
public:
|
||||
Manager();
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
enum class UpdateSource {
|
||||
Queued,
|
||||
TimerEvent,
|
||||
RepaintRequest,
|
||||
};
|
||||
|
||||
class ActiveBasicPointer {
|
||||
public:
|
||||
ActiveBasicPointer(Basic *value = nullptr) : _value(value) {
|
||||
@ -151,20 +155,21 @@ private:
|
||||
friend class Basic;
|
||||
|
||||
void timerEvent(QTimerEvent *e) override;
|
||||
void update(UpdateSource source);
|
||||
|
||||
void start(not_null<Basic*> animation);
|
||||
void stop(not_null<Basic*> animation);
|
||||
|
||||
void schedule();
|
||||
void updateQueued();
|
||||
void startTimer();
|
||||
void stopTimer();
|
||||
not_null<const QObject*> delayedCallGuard() const;
|
||||
|
||||
crl::time _lastUpdateTime = 0;
|
||||
int _timerId = 0;
|
||||
bool _updating = false;
|
||||
bool _scheduled = false;
|
||||
bool _forceImmediateUpdate = false;
|
||||
bool _queued = false;
|
||||
bool _forceUpdateProcessing = false;
|
||||
std::vector<ActiveBasicPointer> _active;
|
||||
std::vector<ActiveBasicPointer> _starting;
|
||||
rpl::lifetime _lifetime;
|
||||
|
Loading…
Reference in New Issue
Block a user