fix perf issue #LINQT-2491)

start by looking for chat in list instead of recreating a chatcore for every event
do not create event log core if not handled
This commit is contained in:
Gaelle Braud 2026-04-15 16:39:54 +02:00
parent 7127e27278
commit 9e4d65a533
7 changed files with 127 additions and 28 deletions

View file

@ -212,12 +212,12 @@ void ChatCore::setSelf(const QSharedPointer<ChatCore> &me) {
const std::shared_ptr<const linphone::EventLog> &eventLog) { const std::shared_ptr<const linphone::EventLog> &eventLog) {
if (mChatModel->getMonitor() != chatRoom) return; if (mChatModel->getMonitor() != chatRoom) return;
if (!eventLog) return; if (!eventLog) return;
if (EventLogCore::isEventHandled(eventLog, chatRoom)) {
lDebug() << log().arg("EVENT LOG RECEIVED IN CHATROOM") << this << mChatModel->getTitle(); lDebug() << log().arg("EVENT LOG RECEIVED IN CHATROOM") << this << mChatModel->getTitle();
auto event = EventLogCore::create(eventLog, chatRoom); auto event = EventLogCore::create(eventLog, chatRoom);
if (event->isHandled()) {
mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); });
} }
mChatModelConnection->invokeToCore([this, event]() { emit lUpdateLastUpdatedTime(); }); mChatModelConnection->invokeToCore([this]() { emit lUpdateLastUpdatedTime(); });
}); });
// Chat messages // Chat messages
@ -322,6 +322,7 @@ void ChatCore::setSelf(const QSharedPointer<ChatCore> &me) {
mChatModelConnection->makeConnectToModel( mChatModelConnection->makeConnectToModel(
&ChatModel::chatMessageSending, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom, &ChatModel::chatMessageSending, [this](const std::shared_ptr<linphone::ChatRoom> &chatRoom,
const std::shared_ptr<const linphone::EventLog> &eventLog) { const std::shared_ptr<const linphone::EventLog> &eventLog) {
lInfo() << "Chat message sending in chatroom" << this << mChatModel->getTitle();
auto event = EventLogCore::create(eventLog, chatRoom); auto event = EventLogCore::create(eventLog, chatRoom);
mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); }); mChatModelConnection->invokeToCore([this, event]() { emit eventsInserted({event}); });
}); });

View file

@ -116,6 +116,11 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount(); auto currentAccount = CoreModel::getInstance()->getCore()->getDefaultAccount();
if (!currentAccount) { if (!currentAccount) {
mModelConnection->invokeToCore([this, chats]() { mModelConnection->invokeToCore([this, chats]() {
for (auto &chat : getSharedList<ChatCore>()) {
if (chat) {
disconnectItem(chat);
}
}
beginResetModel(); beginResetModel();
mList.clear(); mList.clear();
endResetModel(); endResetModel();
@ -137,13 +142,13 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
} }
mModelConnection->invokeToCore([this, chats]() { mModelConnection->invokeToCore([this, chats]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());
beginResetModel();
mList.clear();
for (auto &chat : getSharedList<ChatCore>()) { for (auto &chat : getSharedList<ChatCore>()) {
if (chat) { if (chat) {
disconnectItem(chat); disconnectItem(chat);
} }
} }
beginResetModel();
mList.clear();
for (auto &chat : *chats) { for (auto &chat : *chats) {
connectItem(chat); connectItem(chat);
mList.append(chat); mList.append(chat);
@ -184,8 +189,15 @@ void ChatList::setSelf(QSharedPointer<ChatList> me) {
lInfo() << log().arg("Chat room to add does not match the current filter, return"); lInfo() << log().arg("Chat room to add does not match the current filter, return");
return; return;
} }
auto identifier = Utils::coreStringToAppString(room->getIdentifier());
auto chatList = getSharedList<ChatCore>();
auto it = std::find_if(chatList.begin(), chatList.end(), [identifier](const QSharedPointer<ChatCore> item) {
return item && item->getIdentifier() == identifier;
});
if (it == chatList.end()) {
auto chatCore = ChatCore::create(room); auto chatCore = ChatCore::create(room);
mModelConnection->invokeToCore([this, chatCore, sendAddSignal] { addChatInList(chatCore, sendAddSignal); }); mModelConnection->invokeToCore([this, chatCore, sendAddSignal] { addChatInList(chatCore, sendAddSignal); });
}
}; };
mModelConnection->makeConnectToModel( mModelConnection->makeConnectToModel(
&CoreModel::messageReceived, &CoreModel::messageReceived,
@ -239,17 +251,19 @@ int ChatList::findChatIndex(ChatGui *chatGui) {
return it == chatList.end() ? -1 : std::distance(chatList.begin(), it); return it == chatList.end() ? -1 : std::distance(chatList.begin(), it);
} }
QSharedPointer<ChatCore> ChatList::findChatById(const QString &id) {
auto chatList = getSharedList<ChatCore>();
auto it = std::find_if(chatList.begin(), chatList.end(),
[id](const QSharedPointer<ChatCore> item) { return item->getIdentifier() == id; });
return it == chatList.end() ? nullptr : *it;
}
bool ChatList::addChatInList(QSharedPointer<ChatCore> chatCore, bool emitAddSignal) { bool ChatList::addChatInList(QSharedPointer<ChatCore> chatCore, bool emitAddSignal) {
mustBeInMainThread(log().arg(Q_FUNC_INFO)); mustBeInMainThread(log().arg(Q_FUNC_INFO));
if (chatCore->getIdentifier().isEmpty()) { if (chatCore->getIdentifier().isEmpty()) {
lWarning() << "ChatRoom with invalid identifier cannot be added to the list, return"; lWarning() << "ChatRoom with invalid identifier cannot be added to the list, return";
return false; return false;
} }
auto chatList = getSharedList<ChatCore>();
auto it = std::find_if(chatList.begin(), chatList.end(), [chatCore](const QSharedPointer<ChatCore> item) {
return item && chatCore && item->getIdentifier() == chatCore->getIdentifier();
});
if (it == chatList.end()) {
connectItem(chatCore); connectItem(chatCore);
lInfo() << "Add ChatRoom" << chatCore->getTitle(); lInfo() << "Add ChatRoom" << chatCore->getTitle();
add(chatCore); add(chatCore);
@ -258,7 +272,6 @@ bool ChatList::addChatInList(QSharedPointer<ChatCore> chatCore, bool emitAddSign
emit chatAdded(chatCore); emit chatAdded(chatCore);
} }
return true; return true;
}
return false; return false;
} }

View file

@ -43,6 +43,7 @@ public:
void disconnectItem(QSharedPointer<ChatCore> chat); void disconnectItem(QSharedPointer<ChatCore> chat);
int findChatIndex(ChatGui *chat); int findChatIndex(ChatGui *chat);
QSharedPointer<ChatCore> findChatById(const QString &id);
bool addChatInList(QSharedPointer<ChatCore> chatCore, bool emitAddSignal); bool addChatInList(QSharedPointer<ChatCore> chatCore, bool emitAddSignal);
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;

View file

@ -171,3 +171,49 @@ void EventLogCore::computeEvent(const std::shared_ptr<const linphone::EventLog>
mHandled = false; mHandled = false;
} }
} }
bool EventLogCore::isEventHandled(const std::shared_ptr<const linphone::EventLog> &eventLog,
const std::shared_ptr<linphone::ChatRoom> &chatRoom) {
mustBeInLinphoneThread("EventLogCore::isEventHandled");
auto handled = true;
auto participantAddress = eventLog->getParticipantAddress() ? eventLog->getParticipantAddress() : nullptr;
switch (eventLog->getType()) {
case linphone::EventLog::Type::ConferenceCreated:
if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) ||
!chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference))
handled = false;
break;
case linphone::EventLog::Type::ConferenceTerminated:
if (chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::OneToOne) ||
!chatRoom->hasCapability((int)linphone::ChatRoom::Capabilities::Conference))
handled = false;
break;
case linphone::EventLog::Type::ConferenceParticipantAdded:
break;
case linphone::EventLog::Type::ConferenceParticipantRemoved:
break;
case linphone::EventLog::Type::ConferenceSecurityEvent: {
if (eventLog->getSecurityEventType() != linphone::EventLog::SecurityEventType::SecurityLevelDowngraded) {
handled = false;
}
break;
}
case linphone::EventLog::Type::ConferenceEphemeralMessageEnabled:
break;
case linphone::EventLog::Type::ConferenceEphemeralMessageLifetimeChanged:
handled = eventLog->getEphemeralMessageLifetime() != 0; // Disabled is sent in case of 0.
break;
case linphone::EventLog::Type::ConferenceEphemeralMessageDisabled:
break;
case linphone::EventLog::Type::ConferenceSubjectChanged:
break;
case linphone::EventLog::Type::ConferenceParticipantSetAdmin:
break;
case linphone::EventLog::Type::ConferenceParticipantUnsetAdmin:
break;
default:
handled = false;
}
return handled;
}

View file

@ -73,6 +73,9 @@ public:
std::shared_ptr<EventLogModel> getModel() const; std::shared_ptr<EventLogModel> getModel() const;
static bool isEventHandled(const std::shared_ptr<const linphone::EventLog> &eventLog,
const std::shared_ptr<linphone::ChatRoom> &chatRoom);
private: private:
DECLARE_ABSTRACT_OBJECT DECLARE_ABSTRACT_OBJECT
QString mEventId; QString mEventId;

View file

@ -461,7 +461,12 @@ void Notifier::notifyReceivedMessages(const std::shared_ptr<linphone::ChatRoom>
} }
} }
auto chatCore = ChatCore::create(room); auto chatCore =
App::getInstance()->getChatList()->findChatById(Utils::coreStringToAppString(room->getIdentifier()));
if (!chatCore) {
lWarning() << "chat was not found in chat list, create one";
chatCore = ChatCore::create(room);
}
App::postCoreAsync([this, txt, chatCore, remoteAddress]() { App::postCoreAsync([this, txt, chatCore, remoteAddress]() {
mustBeInMainThread(getClassName()); mustBeInMainThread(getClassName());

View file

@ -1630,7 +1630,12 @@ VariantObject *Utils::getCurrentCallChat(CallGui *call) {
if (!callModel) return QVariant(); if (!callModel) return QVariant();
auto linphoneChatRoom = ToolModel::lookupCurrentCallChat(callModel); auto linphoneChatRoom = ToolModel::lookupCurrentCallChat(callModel);
if (linphoneChatRoom) { if (linphoneChatRoom) {
auto chatCore = ChatCore::create(linphoneChatRoom); auto chatCore = App::getInstance()->getChatList()->findChatById(
Utils::coreStringToAppString(linphoneChatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::getCurrentCallChat : chat was not found in chat list, create one";
chatCore = ChatCore::create(linphoneChatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
} else { } else {
// Only try to create chatroom if 1-1 call // Only try to create chatroom if 1-1 call
@ -1641,7 +1646,12 @@ VariantObject *Utils::getCurrentCallChat(CallGui *call) {
if (linphoneChatRoom != nullptr) { if (linphoneChatRoom != nullptr) {
lInfo() << "[Utils] Chatroom created with" << callModel->getRemoteAddress()->asStringUriOnly(); lInfo() << "[Utils] Chatroom created with" << callModel->getRemoteAddress()->asStringUriOnly();
auto id = linphoneChatRoom->getIdentifier(); auto id = linphoneChatRoom->getIdentifier();
auto chatCore = ChatCore::create(linphoneChatRoom); auto chatCore = App::getInstance()->getChatList()->findChatById(
Utils::coreStringToAppString(linphoneChatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::getCurrentCallChat : chat was not found in chat list, create one";
chatCore = ChatCore::create(linphoneChatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
} else { } else {
lWarning() << "[Utils] Failed to create 1-1 conversation with" lWarning() << "[Utils] Failed to create 1-1 conversation with"
@ -1663,14 +1673,24 @@ VariantObject *Utils::getChatForAddress(QString address) {
linAddr->clean(); linAddr->clean();
auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr); auto linphoneChatRoom = ToolModel::lookupChatForAddress(linAddr);
if (linphoneChatRoom) { if (linphoneChatRoom) {
auto chatCore = ChatCore::create(linphoneChatRoom); auto chatCore = App::getInstance()->getChatList()->findChatById(
Utils::coreStringToAppString(linphoneChatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::getChatForAddress : chat was not found in chat list, create one";
chatCore = ChatCore::create(linphoneChatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
} else { } else {
lInfo() << "[Utils] Did not find existing chat room, create one"; lInfo() << "[Utils] Did not find existing chat room, create one";
linphoneChatRoom = ToolModel::createChatForAddress(linAddr); linphoneChatRoom = ToolModel::createChatForAddress(linAddr);
if (linphoneChatRoom != nullptr) { if (linphoneChatRoom != nullptr) {
lInfo() << "[Utils] Chatroom created with" << linAddr->asStringUriOnly(); lInfo() << "[Utils] Chatroom created with" << linAddr->asStringUriOnly();
auto chatCore = ChatCore::create(linphoneChatRoom); auto chatCore = App::getInstance()->getChatList()->findChatById(
Utils::coreStringToAppString(linphoneChatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::getChatForAddress : chat was not found in chat list, create one";
chatCore = ChatCore::create(linphoneChatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
} else { } else {
lWarning() << "[Utils] Failed to create 1-1 conversation with" << linAddr->asStringUriOnly() << "!"; lWarning() << "[Utils] Failed to create 1-1 conversation with" << linAddr->asStringUriOnly() << "!";
@ -1700,7 +1720,12 @@ VariantObject *Utils::createGroupChat(QString subject, QStringList participantAd
} }
auto linphoneChatRoom = ToolModel::createGroupChatRoom(subject, addresses); auto linphoneChatRoom = ToolModel::createGroupChatRoom(subject, addresses);
if (linphoneChatRoom) { if (linphoneChatRoom) {
auto chatCore = ChatCore::create(linphoneChatRoom); auto chatCore = App::getInstance()->getChatList()->findChatById(
Utils::coreStringToAppString(linphoneChatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::createGroupChat : chat was not found in chat list, create one";
chatCore = ChatCore::create(linphoneChatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
} else { } else {
return QVariant(); return QVariant();
@ -1745,7 +1770,12 @@ VariantObject *Utils::getChatForCallLog(CallHistoryGui *callLog) {
if (!model) return QVariant(); if (!model) return QVariant();
auto chatRoom = model->getChatRoom(); auto chatRoom = model->getChatRoom();
if (!chatRoom) return QVariant(); if (!chatRoom) return QVariant();
auto chatCore = ChatCore::create(chatRoom); auto chatCore =
App::getInstance()->getChatList()->findChatById(Utils::coreStringToAppString(chatRoom->getIdentifier()));
if (!chatCore) {
lWarning() << "Utils::getChatForCallLog : chat was not found in chat list, create one";
chatCore = ChatCore::create(chatRoom);
}
return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant(); return chatCore ? QVariant::fromValue(new ChatGui(chatCore)) : QVariant();
}); });
data->requestValue(); data->requestValue();