From 3c0d046b3fa99bf3f8e7b73c73076323c729a7e2 Mon Sep 17 00:00:00 2001 From: Slava Monich Date: Sun, 27 Sep 2020 17:11:14 +0300 Subject: [PATCH] Handle updateChatPosition And a bit of optimization: 1. Lookup handlers from hashtable 2. Pre-initialize commonly used strings 3. Avoid unnecessary QVariantMap lookups 4. Shortened logging statements --- src/tdlibreceiver.cpp | 210 +++++++++++++++++++++++++++--------------- src/tdlibreceiver.h | 4 + 2 files changed, 141 insertions(+), 73 deletions(-) diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp index 61bc0c0..6c06030 100644 --- a/src/tdlibreceiver.cpp +++ b/src/tdlibreceiver.cpp @@ -18,25 +18,93 @@ */ #include "tdlibreceiver.h" +#define LOG(x) qDebug() << "[TDLibReceiver]" << x + +namespace { + const QString ID("id"); + const QString LIST("list"); + const QString CHAT_ID("chat_id"); + const QString POSITION("position"); + const QString POSITIONS("positions"); + const QString ORDER("order"); + const QString LAST_MESSAGE("last_message"); + const QString UNREAD_COUNT("unread_count"); + const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id"); + const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id"); + + const QString TYPE("@type"); + const QString TYPE_CHAT_POSITION("chatPosition"); + const QString TYPE_CHAT_LIST_MAIN("chatListMain"); +} + +static QString getChatPositionOrder(const QVariantMap &position) +{ + if (position.value(TYPE).toString() == TYPE_CHAT_POSITION && + position.value(LIST).toMap().value(TYPE) == TYPE_CHAT_LIST_MAIN) { + return position.value(ORDER).toString(); + } + return QString(); +} + +static QString findChatPositionOrder(const QVariantList &positions) +{ + const int n = positions.count(); + for (int i = 0; i < n; i++) { + const QString order(getChatPositionOrder(positions.at(i).toMap())); + if (!order.isEmpty()) { + return order; + } + } + return QString(); +} + TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(parent) { this->tdLibClient = tdLibClient; this->isActive = true; + + handlers.insert("updateOption", &TDLibReceiver::processUpdateOption); + handlers.insert("updateAuthorizationState", &TDLibReceiver::processUpdateAuthorizationState); + handlers.insert("updateConnectionState", &TDLibReceiver::processUpdateConnectionState); + handlers.insert("updateUser", &TDLibReceiver::processUpdateUser); + handlers.insert("updateUserStatus", &TDLibReceiver::processUpdateUserStatus); + handlers.insert("updateFile", &TDLibReceiver::processUpdateFile); + handlers.insert("file", &TDLibReceiver::processFile); + handlers.insert("updateNewChat", &TDLibReceiver::processUpdateNewChat); + handlers.insert("updateUnreadMessageCount", &TDLibReceiver::processUpdateUnreadMessageCount); + handlers.insert("updateUnreadChatCount", &TDLibReceiver::processUpdateUnreadChatCount); + handlers.insert("updateChatLastMessage", &TDLibReceiver::processUpdateChatLastMessage); + handlers.insert("updateChatOrder", &TDLibReceiver::processUpdateChatOrder); + handlers.insert("updateChatPosition", &TDLibReceiver::processUpdateChatPosition); + handlers.insert("updateChatReadInbox", &TDLibReceiver::processUpdateChatReadInbox); + handlers.insert("updateChatReadOutbox", &TDLibReceiver::processUpdateChatReadOutbox); + handlers.insert("updateBasicGroup", &TDLibReceiver::processUpdateBasicGroup); + handlers.insert("updateSupergroup", &TDLibReceiver::processUpdateSuperGroup); + handlers.insert("updateChatOnlineMemberCount", &TDLibReceiver::processChatOnlineMemberCountUpdated); + handlers.insert("messages", &TDLibReceiver::processMessages); + handlers.insert("updateNewMessage", &TDLibReceiver::processUpdateNewMessage); + handlers.insert("message", &TDLibReceiver::processMessage); + handlers.insert("updateMessageSendSucceeded", &TDLibReceiver::processMessageSendSucceeded); + handlers.insert("updateActiveNotifications", &TDLibReceiver::processUpdateActiveNotifications); + handlers.insert("updateNotificationGroup", &TDLibReceiver::processUpdateNotificationGroup); + handlers.insert("updateChatNotificationSettings", &TDLibReceiver::processUpdateChatNotificationSettings); + handlers.insert("updateMessageContent", &TDLibReceiver::processUpdateMessageContent); + handlers.insert("updateDeleteMessages", &TDLibReceiver::processUpdateDeleteMessages); } void TDLibReceiver::setActive(const bool &active) { if (active) { - qDebug() << "[TDLibReceiver] Activating receiver loop..."; + LOG("Activating receiver loop..."); } else { - qDebug() << "[TDLibReceiver] Deactivating receiver loop, this may take a while..."; + LOG("Deactivating receiver loop, this may take a while..."); } this->isActive = active; } void TDLibReceiver::receiverLoop() { - qDebug() << "[TDLibReceiver] Starting receiver loop"; + LOG("Starting receiver loop"); const double WAIT_TIMEOUT = 5.0; while (this->isActive) { const char *result = td_json_client_receive(this->tdLibClient, WAIT_TIMEOUT); @@ -46,7 +114,7 @@ void TDLibReceiver::receiverLoop() processReceivedDocument(receivedJsonDocument); } } - qDebug() << "[TDLibReceiver] Stopping receiver loop"; + LOG("Stopping receiver loop"); } void TDLibReceiver::processReceivedDocument(const QJsonDocument &receivedJsonDocument) @@ -54,32 +122,12 @@ void TDLibReceiver::processReceivedDocument(const QJsonDocument &receivedJsonDoc QVariantMap receivedInformation = receivedJsonDocument.object().toVariantMap(); QString objectTypeName = receivedInformation.value("@type").toString(); - if (objectTypeName == "updateOption") { this->processUpdateOption(receivedInformation); } - if (objectTypeName == "updateAuthorizationState") { this->processUpdateAuthorizationState(receivedInformation); } - if (objectTypeName == "updateConnectionState") { this->processUpdateConnectionState(receivedInformation); } - if (objectTypeName == "updateUser") { this->processUpdateUser(receivedInformation); } - if (objectTypeName == "updateUserStatus") { this->processUpdateUserStatus(receivedInformation); } - if (objectTypeName == "updateFile") { this->processUpdateFile(receivedInformation); } - if (objectTypeName == "file") { this->processFile(receivedInformation); } - if (objectTypeName == "updateNewChat") { this->processUpdateNewChat(receivedInformation); } - if (objectTypeName == "updateUnreadMessageCount") { this->processUpdateUnreadMessageCount(receivedInformation); } - if (objectTypeName == "updateUnreadChatCount") { this->processUpdateUnreadChatCount(receivedInformation); } - if (objectTypeName == "updateChatLastMessage") { this->processUpdateChatLastMessage(receivedInformation); } - if (objectTypeName == "updateChatOrder") { this->processUpdateChatOrder(receivedInformation); } - if (objectTypeName == "updateChatReadInbox") { this->processUpdateChatReadInbox(receivedInformation); } - if (objectTypeName == "updateChatReadOutbox") { this->processUpdateChatReadOutbox(receivedInformation); } - if (objectTypeName == "updateBasicGroup") { this->processUpdateBasicGroup(receivedInformation); } - if (objectTypeName == "updateSupergroup") { this->processUpdateSuperGroup(receivedInformation); } - if (objectTypeName == "updateChatOnlineMemberCount") { this->processChatOnlineMemberCountUpdated(receivedInformation); } - if (objectTypeName == "messages") { this->processMessages(receivedInformation); } - if (objectTypeName == "updateNewMessage") { this->processUpdateNewMessage(receivedInformation); } - if (objectTypeName == "message") { this->processMessage(receivedInformation); } - if (objectTypeName == "updateMessageSendSucceeded") { this->processMessageSendSucceeded(receivedInformation); } - if (objectTypeName == "updateActiveNotifications") { this->processUpdateActiveNotifications(receivedInformation); } - if (objectTypeName == "updateNotificationGroup") { this->processUpdateNotificationGroup(receivedInformation); } - if (objectTypeName == "updateChatNotificationSettings") { this->processUpdateChatNotificationSettings(receivedInformation); } - if (objectTypeName == "updateMessageContent") { this->processUpdateMessageContent(receivedInformation); } - if (objectTypeName == "updateDeleteMessages") { this->processUpdateDeleteMessages(receivedInformation); } + Handler handler = handlers.value(objectTypeName); + if (handler) { + (this->*handler)(receivedInformation); + } else { + LOG("Unhandled object type" << objectTypeName); + } } void TDLibReceiver::processUpdateOption(const QVariantMap &receivedInformation) @@ -87,11 +135,11 @@ void TDLibReceiver::processUpdateOption(const QVariantMap &receivedInformation) QString currentOption = receivedInformation.value("name").toString(); if (currentOption == "version") { QString detectedVersion = receivedInformation.value("value").toMap().value("value").toString(); - qDebug() << "[TDLibReceiver] TD Lib version detected: " << detectedVersion; + LOG("TD Lib version detected: " << detectedVersion); emit versionDetected(detectedVersion); } else { QVariant currentValue = receivedInformation.value("value").toMap().value("value"); - qDebug() << "[TDLibReceiver] Option updated: " << currentOption << currentValue; + LOG("Option updated: " << currentOption << currentValue); emit optionUpdated(currentOption, currentValue); } } @@ -99,21 +147,21 @@ void TDLibReceiver::processUpdateOption(const QVariantMap &receivedInformation) void TDLibReceiver::processUpdateAuthorizationState(const QVariantMap &receivedInformation) { QString authorizationState = receivedInformation.value("authorization_state").toMap().value("@type").toString(); - qDebug() << "[TDLibReceiver] Authorization state changed: " << authorizationState; + LOG("Authorization state changed: " << authorizationState); emit authorizationStateChanged(authorizationState); } void TDLibReceiver::processUpdateConnectionState(const QVariantMap &receivedInformation) { QString connectionState = receivedInformation.value("state").toMap().value("@type").toString(); - qDebug() << "[TDLibReceiver] Connection state changed: " << connectionState; + LOG("Connection state changed: " << connectionState); emit connectionStateChanged(connectionState); } void TDLibReceiver::processUpdateUser(const QVariantMap &receivedInformation) { QVariantMap userInformation = receivedInformation.value("user").toMap(); - // qDebug() << "[TDLibReceiver] User was updated: " << userInformation.value("username").toString() << userInformation.value("first_name").toString() << userInformation.value("last_name").toString(); + // LOG("User was updated: " << userInformation.value("username").toString() << userInformation.value("first_name").toString() << userInformation.value("last_name").toString()); emit userUpdated(userInformation); } @@ -121,27 +169,27 @@ void TDLibReceiver::processUpdateUserStatus(const QVariantMap &receivedInformati { QString userId = receivedInformation.value("user_id").toString(); QVariantMap userStatusInformation = receivedInformation.value("status").toMap(); - // qDebug() << "[TDLibReceiver] User status was updated: " << receivedInformation.value("user_id").toString() << userStatusInformation.value("@type").toString(); + // LOG("User status was updated: " << receivedInformation.value("user_id").toString() << userStatusInformation.value("@type").toString()); emit userStatusUpdated(userId, userStatusInformation); } void TDLibReceiver::processUpdateFile(const QVariantMap &receivedInformation) { QVariantMap fileInformation = receivedInformation.value("file").toMap(); - qDebug() << "[TDLibReceiver] File was updated: " << fileInformation.value("id").toString(); + LOG("File was updated: " << fileInformation.value(ID).toString()); emit fileUpdated(fileInformation); } void TDLibReceiver::processFile(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] File was updated: " << receivedInformation.value("id").toString(); + LOG("File was updated: " << receivedInformation.value(ID).toString()); emit fileUpdated(receivedInformation); } void TDLibReceiver::processUpdateNewChat(const QVariantMap &receivedInformation) { QVariantMap chatInformation = receivedInformation.value("chat").toMap(); - qDebug() << "[TDLibReceiver] New chat discovered: " << chatInformation.value("id").toString() << chatInformation.value("title").toString(); + LOG("New chat discovered: " << chatInformation.value(ID).toString() << chatInformation.value("title").toString()); emit newChatDiscovered(chatInformation); } @@ -151,7 +199,7 @@ void TDLibReceiver::processUpdateUnreadMessageCount(const QVariantMap &receivedI messageCountInformation.insert("chat_list_type", receivedInformation.value("chat_list").toMap().value("@type")); messageCountInformation.insert("unread_count", receivedInformation.value("unread_count")); messageCountInformation.insert("unread_unmuted_count", receivedInformation.value("unread_unmuted_count")); - qDebug() << "[TDLibReceiver] Unread message count updated: " << messageCountInformation.value("chat_list_type").toString() << messageCountInformation.value("unread_count").toString(); + LOG("Unread message count updated: " << messageCountInformation.value("chat_list_type").toString() << messageCountInformation.value("unread_count").toString()); emit unreadMessageCountUpdated(messageCountInformation); } @@ -164,74 +212,90 @@ void TDLibReceiver::processUpdateUnreadChatCount(const QVariantMap &receivedInfo chatCountInformation.insert("total_count", receivedInformation.value("total_count")); chatCountInformation.insert("unread_count", receivedInformation.value("unread_count")); chatCountInformation.insert("unread_unmuted_count", receivedInformation.value("unread_unmuted_count")); - qDebug() << "[TDLibReceiver] Unread chat count updated: " << chatCountInformation.value("chat_list_type").toString() << chatCountInformation.value("unread_count").toString(); + LOG("Unread chat count updated: " << chatCountInformation.value("chat_list_type").toString() << chatCountInformation.value("unread_count").toString()); emit unreadChatCountUpdated(chatCountInformation); } void TDLibReceiver::processUpdateChatLastMessage(const QVariantMap &receivedInformation) { - QVariantMap lastMessage = receivedInformation.value("last_message").toMap(); - qDebug() << "[TDLibReceiver] Last message of chat " << receivedInformation.value("chat_id").toString() << " updated, order " << receivedInformation.value("order").toString() << " content: " << lastMessage.value("content").toString(); - emit chatLastMessageUpdated(receivedInformation.value("chat_id").toString(), receivedInformation.value("order").toString(), lastMessage); + const QString chat_id(receivedInformation.value(CHAT_ID).toString()); + const QString order(findChatPositionOrder(receivedInformation.value(POSITIONS).toList())); + const QVariantMap lastMessage = receivedInformation.value(LAST_MESSAGE).toMap(); + LOG("Last message of chat" << chat_id << "updated, order" << order << "type" << lastMessage.value("@type").toString()); + emit chatLastMessageUpdated(chat_id, order, lastMessage); } void TDLibReceiver::processUpdateChatOrder(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Chat order updated for ID " << receivedInformation.value("chat_id").toString() << " new order: " << receivedInformation.value("order").toString(); - emit chatOrderUpdated(receivedInformation.value("chat_id").toString(), receivedInformation.value("order").toString()); + const QString chat_id(receivedInformation.value(CHAT_ID).toString()); + const QString order(receivedInformation.value(ORDER).toString()); + LOG("Chat order updated for ID" << chat_id << "to" << order); + emit chatOrderUpdated(chat_id, order); +} + +void TDLibReceiver::processUpdateChatPosition(const QVariantMap &receivedInformation) +{ + const QString chat_id(receivedInformation.value(CHAT_ID).toString()); + const QString order(receivedInformation.value(POSITION).toMap().value(ORDER).toString()); + LOG("Chat position updated for ID" << chat_id << "new order" << order); + emit chatOrderUpdated(chat_id, order); } void TDLibReceiver::processUpdateChatReadInbox(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Chat read information updated for " << receivedInformation.value("chat_id").toString() << " unread count: " << receivedInformation.value("unread_count").toString(); - emit chatReadInboxUpdated(receivedInformation.value("chat_id").toString(), receivedInformation.value("last_read_inbox_message_id").toString(), receivedInformation.value("unread_count").toInt()); + const QString chat_id(receivedInformation.value(CHAT_ID).toString()); + const QString unread_count(receivedInformation.value(UNREAD_COUNT).toString()); + LOG("Chat read information updated for" << chat_id << "unread count:" << unread_count); + emit chatReadInboxUpdated(chat_id, receivedInformation.value(LAST_READ_INBOX_MESSAGE_ID).toString(), unread_count.toInt()); } void TDLibReceiver::processUpdateChatReadOutbox(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Sent messages read information updated for " << receivedInformation.value("chat_id").toString() << " last read message ID: " << receivedInformation.value("last_read_outbox_message_id").toString(); - emit chatReadOutboxUpdated(receivedInformation.value("chat_id").toString(), receivedInformation.value("last_read_outbox_message_id").toString()); + const QString chat_id(receivedInformation.value(CHAT_ID).toString()); + const QString last_read_outbox_message_id(receivedInformation.value(LAST_READ_OUTBOX_MESSAGE_ID).toString()); + LOG("Sent messages read information updated for" << chat_id << "last read message ID:" << last_read_outbox_message_id); + emit chatReadOutboxUpdated(chat_id, last_read_outbox_message_id); } void TDLibReceiver::processUpdateBasicGroup(const QVariantMap &receivedInformation) { - QString basicGroupId = receivedInformation.value("basic_group").toMap().value("id").toString(); - qDebug() << "[TDLibReceiver] Basic group information updated for " << basicGroupId; + QString basicGroupId = receivedInformation.value("basic_group").toMap().value(ID).toString(); + LOG("Basic group information updated for " << basicGroupId); emit basicGroupUpdated(basicGroupId, receivedInformation.value("basic_group").toMap()); } void TDLibReceiver::processUpdateSuperGroup(const QVariantMap &receivedInformation) { - QString superGroupId = receivedInformation.value("supergroup").toMap().value("id").toString(); - qDebug() << "[TDLibReceiver] Super group information updated for " << superGroupId; + QString superGroupId = receivedInformation.value("supergroup").toMap().value(ID).toString(); + LOG("Super group information updated for " << superGroupId); emit superGroupUpdated(superGroupId, receivedInformation.value("supergroup").toMap()); } void TDLibReceiver::processChatOnlineMemberCountUpdated(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("chat_id").toString(); - qDebug() << "[TDLibReceiver] Online member count updated for chat " << chatId; + const QString chatId = receivedInformation.value(CHAT_ID).toString(); + LOG("Online member count updated for chat " << chatId); emit chatOnlineMemberCountUpdated(chatId, receivedInformation.value("online_member_count").toInt()); } void TDLibReceiver::processMessages(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Received new messages, amount: " << receivedInformation.value("total_count").toString(); + LOG("Received new messages, amount: " << receivedInformation.value("total_count").toString()); emit messagesReceived(receivedInformation.value("messages").toList()); } void TDLibReceiver::processUpdateNewMessage(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("message").toMap().value("chat_id").toString(); - qDebug() << "[TDLibReceiver] Received new message for chat " << chatId; + const QString chatId = receivedInformation.value("message").toMap().value(CHAT_ID).toString(); + LOG("Received new message for chat " << chatId); emit newMessageReceived(chatId, receivedInformation.value("message").toMap()); } void TDLibReceiver::processMessage(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("chat_id").toString(); - QString messageId = receivedInformation.value("id").toString(); - qDebug() << "[TDLibReceiver] Received message " << chatId << messageId; + const QString chatId = receivedInformation.value(CHAT_ID).toString(); + const QString messageId = receivedInformation.value(ID).toString(); + LOG("Received message " << chatId << messageId); emit messageInformation(messageId, receivedInformation); } @@ -239,48 +303,48 @@ void TDLibReceiver::processMessageSendSucceeded(const QVariantMap &receivedInfor { QString oldMessageId = receivedInformation.value("old_message_id").toString(); QVariantMap message = receivedInformation.value("message").toMap(); - QString messageId = message.value("id").toString(); - qDebug() << "[TDLibReceiver] Message send succeeded " << messageId << oldMessageId; + const QString messageId = message.value(ID).toString(); + LOG("Message send succeeded " << messageId << oldMessageId); emit messageSendSucceeded(messageId, oldMessageId, message); } void TDLibReceiver::processUpdateActiveNotifications(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Received active notification groups"; + LOG("Received active notification groups"); emit activeNotificationsUpdated(receivedInformation.value("groups").toList()); } void TDLibReceiver::processUpdateNotificationGroup(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Received updated notification group"; + LOG("Received updated notification group"); emit notificationGroupUpdated(receivedInformation); } void TDLibReceiver::processUpdateNotification(const QVariantMap &receivedInformation) { - qDebug() << "[TDLibReceiver] Received notification update"; + LOG("Received notification update"); emit notificationUpdated(receivedInformation); } void TDLibReceiver::processUpdateChatNotificationSettings(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("chat_id").toString(); - qDebug() << "[TDLibReceiver] Received new notification settings for chat " << chatId; + const QString chatId = receivedInformation.value(CHAT_ID).toString(); + LOG("Received new notification settings for chat " << chatId); emit chatNotificationSettingsUpdated(chatId, receivedInformation.value("notification_settings").toMap()); } void TDLibReceiver::processUpdateMessageContent(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("chat_id").toString(); + const QString chatId = receivedInformation.value(CHAT_ID).toString(); QString messageId = receivedInformation.value("message_id").toString(); - qDebug() << "[TDLibReceiver] Message content updated " << chatId << messageId; + LOG("Message content updated " << chatId << messageId); emit messageContentUpdated(chatId, messageId, receivedInformation.value("new_content").toMap()); } void TDLibReceiver::processUpdateDeleteMessages(const QVariantMap &receivedInformation) { - QString chatId = receivedInformation.value("chat_id").toString(); + const QString chatId = receivedInformation.value(CHAT_ID).toString(); QVariantList messageIds = receivedInformation.value("message_ids").toList(); - qDebug() << "[TDLibReceiver] Some messages were deleted " << chatId; + LOG("Some messages were deleted " << chatId); emit messagesDeleted(chatId, messageIds); } diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h index eda9838..3434710 100644 --- a/src/tdlibreceiver.h +++ b/src/tdlibreceiver.h @@ -65,6 +65,9 @@ signals: void messagesDeleted(const QString &chatId, const QVariantList &messageIds); private: + typedef void (TDLibReceiver::*Handler)(const QVariantMap &); + + QHash handlers; void *tdLibClient; bool isActive; @@ -82,6 +85,7 @@ private: void processUpdateUnreadChatCount(const QVariantMap &receivedInformation); void processUpdateChatLastMessage(const QVariantMap &receivedInformation); void processUpdateChatOrder(const QVariantMap &receivedInformation); + void processUpdateChatPosition(const QVariantMap &receivedInformation); void processUpdateChatReadInbox(const QVariantMap &receivedInformation); void processUpdateChatReadOutbox(const QVariantMap &receivedInformation); void processUpdateBasicGroup(const QVariantMap &receivedInformation);