From c64000777510e8b6c899475bf49fba31af9fda8b Mon Sep 17 00:00:00 2001 From: Diadlo Date: Tue, 31 Oct 2017 16:48:46 +0300 Subject: [PATCH] perf(smileys): Use shared_ptr to automaticaly count references --- src/chatlog/customtextdocument.cpp | 4 +++- src/chatlog/customtextdocument.h | 10 +++++++++- src/persistence/smileypack.cpp | 19 ++++++++++--------- src/persistence/smileypack.h | 9 +++++---- src/widget/emoticonswidget.cpp | 5 ++++- src/widget/emoticonswidget.h | 6 ++++++ .../form/settings/userinterfaceform.cpp | 9 +++++---- src/widget/form/settings/userinterfaceform.h | 3 +++ 8 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/chatlog/customtextdocument.cpp b/src/chatlog/customtextdocument.cpp index 26adc06e6..9ad384cfb 100644 --- a/src/chatlog/customtextdocument.cpp +++ b/src/chatlog/customtextdocument.cpp @@ -40,7 +40,9 @@ QVariant CustomTextDocument::loadResource(int type, const QUrl& name) Settings::getInstance().getEmojiFontPointSize()); QString fileName = QUrl::fromPercentEncoding(name.toEncoded()).mid(4).toHtmlEscaped(); - return SmileyPack::getInstance().getAsIcon(fileName).pixmap(size); + std::shared_ptr icon = SmileyPack::getInstance().getAsIcon(fileName); + emoticonIcons.append(icon); + return icon->pixmap(size); } return QTextDocument::loadResource(type, name); diff --git a/src/chatlog/customtextdocument.h b/src/chatlog/customtextdocument.h index 8f2a9f89c..498f9e868 100644 --- a/src/chatlog/customtextdocument.h +++ b/src/chatlog/customtextdocument.h @@ -21,15 +21,23 @@ #define CUSTOMTEXTDOCUMENT_H #include +#include + +#include + +class QIcon; class CustomTextDocument : public QTextDocument { Q_OBJECT public: - explicit CustomTextDocument(QObject* parent = 0); + explicit CustomTextDocument(QObject* parent = nullptr); protected: virtual QVariant loadResource(int type, const QUrl& name); + +private: + QList> emoticonIcons; }; #endif // CUSTOMTEXTDOCUMENT_H diff --git a/src/persistence/smileypack.cpp b/src/persistence/smileypack.cpp index d29270958..02b0c238b 100644 --- a/src/persistence/smileypack.cpp +++ b/src/persistence/smileypack.cpp @@ -204,7 +204,6 @@ bool SmileyPack::load(const QString& filename) emoticons.clear(); emoticonToIcon.clear(); emoticonToPath.clear(); - icons.clear(); for (int i = 0; i < iconsCount; ++i) { QDomNode node = emoticonElements.at(i); @@ -267,19 +266,21 @@ QList SmileyPack::getEmoticons() const * @param emoticon Passed emoticon * @return Returns cached icon according to passed emoticon, null if no icon mapped to this emoticon */ -QIcon SmileyPack::getAsIcon(const QString& emoticon) +std::shared_ptr SmileyPack::getAsIcon(const QString& emoticon) { QMutexLocker locker(&loadingMutex); if (emoticonToIcon.contains(emoticon)) - return *(emoticonToIcon[emoticon]); + return emoticonToIcon[emoticon]; - if (!emoticonToPath.contains(emoticon)) - return QIcon{}; + const auto iconPathIt = emoticonToPath.find(emoticon); + if (iconPathIt == emoticonToPath.end()) { + return std::make_shared(); + } - const QString& iconPath = emoticonToPath[emoticon]; - icons.append(QIcon{iconPath}); - emoticonToIcon.insert(emoticon, &icons.last()); - return icons.last(); + const QString& iconPath = iconPathIt.value(); + auto icon = std::make_shared(iconPath); + emoticonToIcon.insert(emoticon, icon); + return icon; } void SmileyPack::onSmileyPackChanged() diff --git a/src/persistence/smileypack.h b/src/persistence/smileypack.h index e47486ec6..9591b67a2 100644 --- a/src/persistence/smileypack.h +++ b/src/persistence/smileypack.h @@ -24,6 +24,8 @@ #include #include +#include + class SmileyPack : public QObject { Q_OBJECT @@ -35,7 +37,7 @@ public: QString smileyfied(const QString& msg); QList getEmoticons() const; - QIcon getAsIcon(const QString& key); + std::shared_ptr getAsIcon(const QString& key); private slots: void onSmileyPackChanged(); @@ -47,9 +49,8 @@ private: bool load(const QString& filename); - QVector icons; - QMap emoticonToIcon; - QMap emoticonToPath; + QMap> emoticonToIcon; + QHash emoticonToPath; QList emoticons; QString path; mutable QMutex loadingMutex; diff --git a/src/widget/emoticonswidget.cpp b/src/widget/emoticonswidget.cpp index 55a34a354..1b5ffb8a1 100644 --- a/src/widget/emoticonswidget.cpp +++ b/src/widget/emoticonswidget.cpp @@ -86,9 +86,12 @@ EmoticonsWidget::EmoticonsWidget(QWidget* parent) } buttonLayout->addStretch(); + SmileyPack& smileyPack = SmileyPack::getInstance(); for (const QStringList& set : emoticons) { QPushButton* button = new QPushButton; - button->setIcon(SmileyPack::getInstance().getAsIcon(set[0]).pixmap(size)); + std::shared_ptr icon = smileyPack.getAsIcon(set[0]); + emoticonsIcons.append(icon); + button->setIcon(icon->pixmap(size)); button->setToolTip(set.join(" ")); button->setProperty("sequence", set[0]); button->setCursor(Qt::PointingHandCursor); diff --git a/src/widget/emoticonswidget.h b/src/widget/emoticonswidget.h index d2471ca00..615813b4a 100644 --- a/src/widget/emoticonswidget.h +++ b/src/widget/emoticonswidget.h @@ -23,6 +23,11 @@ #include #include #include +#include + +#include + +class QIcon; class EmoticonsWidget : public QMenu { @@ -47,6 +52,7 @@ protected: private: QStackedWidget stack; QVBoxLayout layout; + QList> emoticonsIcons; public: QSize sizeHint() const override; diff --git a/src/widget/form/settings/userinterfaceform.cpp b/src/widget/form/settings/userinterfaceform.cpp index 5d532cf02..b77c404dc 100644 --- a/src/widget/form/settings/userinterfaceform.cpp +++ b/src/widget/form/settings/userinterfaceform.cpp @@ -239,10 +239,12 @@ void UserInterfaceForm::reloadSmileys() for (int i = 0; i < emoticons.size(); ++i) smileys.push_front(emoticons.at(i).first()); + emoticonsIcons.clear(); const QSize size(18, 18); for (int i = 0; i < smileLabels.size(); ++i) { - QIcon icon = SmileyPack::getInstance().getAsIcon(smileys[i]); - smileLabels[i]->setPixmap(icon.pixmap(size)); + std::shared_ptr icon = SmileyPack::getInstance().getAsIcon(smileys[i]); + emoticonsIcons.append(icon); + smileLabels[i]->setPixmap(icon->pixmap(size)); smileLabels[i]->setToolTip(smileys[i]); } @@ -253,8 +255,7 @@ void UserInterfaceForm::reloadSmileys() int maxSide = qMin(desktop.geometry().height() / sideSize, desktop.geometry().width() / sideSize); QSize maxSize(maxSide, maxSide); - QIcon icon = SmileyPack::getInstance().getAsIcon(smileys[0]); - QSize actualSize = icon.actualSize(maxSize); + QSize actualSize = emoticonsIcons.first()->actualSize(maxSize); bodyUI->emoticonSize->setMaximum(actualSize.width()); } diff --git a/src/widget/form/settings/userinterfaceform.h b/src/widget/form/settings/userinterfaceform.h index 185c553a4..4b4e56f7b 100644 --- a/src/widget/form/settings/userinterfaceform.h +++ b/src/widget/form/settings/userinterfaceform.h @@ -23,6 +23,8 @@ #include "genericsettings.h" #include "src/widget/form/settingswidget.h" +#include + namespace Ui { class UserInterfaceSettings; } @@ -65,6 +67,7 @@ private: private: QList smileLabels; + QList> emoticonsIcons; SettingsWidget* parent; Ui::UserInterfaceSettings* bodyUI; const int MAX_FORMAT_LENGTH = 128;