Optimize InvokeQueued().

This commit is contained in:
John Preston 2019-07-10 17:03:15 +02:00
parent c3c6571835
commit 90fb9eccd4
6 changed files with 60 additions and 11 deletions

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QLatin1String>
namespace base {
template <typename Type>

View File

@ -0,0 +1,42 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include <QtCore/QEvent>
#include <QtCore/QCoreApplication>
#include "base/basic_types.h"
namespace base {
class InvokeQueuedEvent : public QEvent {
public:
static constexpr auto kType = QEvent::Type(60666);
explicit InvokeQueuedEvent(FnMut<void()> &&method)
: QEvent(kType)
, _method(std::move(method)) {
}
void invoke() {
_method();
}
private:
FnMut<void()> _method;
};
} // namespace base
template <typename Lambda>
inline void InvokeQueued(const QObject *context, Lambda &&lambda) {
QCoreApplication::postEvent(
const_cast<QObject*>(context),
new base::InvokeQueuedEvent(std::forward<Lambda>(lambda)));
}

View File

@ -20,6 +20,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/update_checker.h"
#include "base/timer.h"
#include "base/concurrent_timer.h"
#include "base/invoke_queued.h"
#include "base/qthelp_url.h"
#include "base/qthelp_regex.h"
#include "ui/effects/animations.h"
@ -494,21 +495,28 @@ void Sandbox::registerEnterFromEventLoop() {
}
}
bool Sandbox::notifyOrInvoke(QObject *receiver, QEvent *e) {
if (e->type() == base::InvokeQueuedEvent::kType) {
static_cast<base::InvokeQueuedEvent*>(e)->invoke();
return true;
}
return QApplication::notify(receiver, e);
}
bool Sandbox::notify(QObject *receiver, QEvent *e) {
if (QThread::currentThreadId() != _mainThreadId) {
return QApplication::notify(receiver, e);
return notifyOrInvoke(receiver, e);
}
const auto wrap = createEventNestingLevel();
const auto type = e->type();
if (type == QEvent::UpdateRequest) {
if (e->type() == QEvent::UpdateRequest) {
const auto weak = make_weak(receiver);
_widgetUpdateRequests.fire({});
if (!weak) {
return true;
}
}
return QApplication::notify(receiver, e);
return notifyOrInvoke(receiver, e);
}
void Sandbox::processPostponedCalls(int level) {

View File

@ -71,6 +71,8 @@ private:
FnMut<void()> callable;
};
bool notifyOrInvoke(QObject *receiver, QEvent *e);
void closeApplication(); // will be done in aboutToQuit()
void checkForQuit(); // will be done in exec()
void registerEnterFromEventLoop();

View File

@ -14,10 +14,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/assertion.h"
#include "base/bytes.h"
#include <crl/crl_time.h>
#include <QtCore/QReadWriteLock>
#include <QtCore/QRegularExpression>
#include <QtNetwork/QNetworkProxy>
#include <cmath>
#include <set>
@ -55,12 +55,6 @@ inline bool in_range(Value &&value, From &&from, Till &&till) {
// while "for_const (T *p, v)" won't and "for_const (T *&p, v)" won't compile
#define for_const(range_declaration, range_expression) for (range_declaration : std::as_const(range_expression))
template <typename Lambda>
inline void InvokeQueued(const QObject *context, Lambda &&lambda) {
QObject proxy;
QObject::connect(&proxy, &QObject::destroyed, context, std::forward<Lambda>(lambda), Qt::QueuedConnection);
}
static const int32 ScrollMax = INT_MAX;
extern uint64 _SharedMemoryLocation[];

View File

@ -68,6 +68,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/variant.h"
#include "base/optional.h"
#include "base/algorithm.h"
#include "base/invoke_queued.h"
#include "base/flat_set.h"
#include "base/flat_map.h"
#include "base/weak_ptr.h"