diff options
| author | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-05-24 23:33:21 +0200 |
|---|---|---|
| committer | Mikaël Capelle <capelle.mikael@gmail.com> | 2020-05-24 23:33:21 +0200 |
| commit | 238e233c18d22d01e966efaa86975f5f37bb7fa2 (patch) | |
| tree | 3c4eb7af80d4e47fa85f296e5c5aafbed0b5e415 | |
| parent | 0aac4f3291d65ebc1b0bbee744fca347ecef7022 (diff) | |
Use memoization for file tree, contents and validity of ModInfo.
| -rw-r--r-- | src/modinforegular.cpp | 3 | ||||
| -rw-r--r-- | src/modinforegular.h | 4 | ||||
| -rw-r--r-- | src/modinfowithconflictinfo.cpp | 25 | ||||
| -rw-r--r-- | src/modinfowithconflictinfo.h | 31 |
4 files changed, 43 insertions, 20 deletions
diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp index 87483a64..d8e42383 100644 --- a/src/modinforegular.cpp +++ b/src/modinforegular.cpp @@ -653,7 +653,7 @@ std::vector<ModInfo::EFlag> ModInfoRegular::getFlags() const } -std::vector<ModInfo::EContent> ModInfoRegular::getContents() const +std::vector<ModInfo::EContent> ModInfoRegular::doGetContents() const { auto tree = contentFileTree(); std::vector<ModInfo::EContent> contents; @@ -707,7 +707,6 @@ std::vector<ModInfo::EContent> ModInfoRegular::getContents() const } return contents; - } diff --git a/src/modinforegular.h b/src/modinforegular.h index 08546c69..e63e7570 100644 --- a/src/modinforegular.h +++ b/src/modinforegular.h @@ -289,8 +289,6 @@ public: */ virtual std::vector<EFlag> getFlags() const override; - virtual std::vector<EContent> getContents() const override; - /** * @return an indicator if and how this mod should be highlighted by the UI */ @@ -418,6 +416,8 @@ private slots: protected: + virtual std::vector<EContent> doGetContents() const override; + ModInfoRegular(PluginContainer *pluginContainer, const MOBase::IPluginGame *game, const QDir &path, MOShared::DirectoryEntry **directoryStructure); private: diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp index d2202c3d..d2a0ca51 100644 --- a/src/modinfowithconflictinfo.cpp +++ b/src/modinfowithconflictinfo.cpp @@ -14,7 +14,9 @@ namespace fs = std::filesystem; ModInfoWithConflictInfo::ModInfoWithConflictInfo( PluginContainer *pluginContainer, const MOBase::IPluginGame* gamePlugin, DirectoryEntry **directoryStructure) - : ModInfo(pluginContainer), m_GamePlugin(gamePlugin), m_DirectoryStructure(directoryStructure), m_HasLooseOverwrite(false), m_HasHiddenFiles(false) {} + : ModInfo(pluginContainer), m_GamePlugin(gamePlugin), + m_FileTree(&ModInfoWithConflictInfo::updateFileTree), m_Valid(&ModInfoWithConflictInfo::doTestValid), m_Contents(&ModInfoWithConflictInfo::doGetContents), + m_DirectoryStructure(directoryStructure), m_HasLooseOverwrite(false), m_HasHiddenFiles(false) {} void ModInfoWithConflictInfo::clearCaches() { @@ -297,16 +299,17 @@ bool ModInfoWithConflictInfo::hasHiddenFiles() const } void ModInfoWithConflictInfo::diskContentModified() { - std::unique_lock lock(m_Mutex); - m_FileTree = nullptr; + m_FileTree.invalidate(); + m_Valid.invalidate(); + m_Contents.invalidate(); +} + +std::shared_ptr<const IFileTree> ModInfoWithConflictInfo::updateFileTree() const { + return QDirFileTree::makeTree(absolutePath()); } std::shared_ptr<const IFileTree> ModInfoWithConflictInfo::contentFileTree() const { - std::unique_lock lock(m_Mutex); - if (!m_FileTree) { - m_FileTree = QDirFileTree::makeTree(absolutePath()); - } - return m_FileTree; + return m_FileTree.value(this); } void ModInfoWithConflictInfo::prefetch() { @@ -326,5 +329,9 @@ bool ModInfoWithConflictInfo::doTestValid() const { } bool ModInfoWithConflictInfo::isValid() const { - return doTestValid(); + return m_Valid.value(this); +} + +std::vector<ModInfo::EContent> ModInfoWithConflictInfo::getContents() const { + return m_Contents.value(this); } diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h index 68675397..3adbb998 100644 --- a/src/modinfowithconflictinfo.h +++ b/src/modinfowithconflictinfo.h @@ -3,6 +3,7 @@ #include <ifiletree.h> +#include "thread_utils.h" #include "modinfo.h" #include <QTime> @@ -21,6 +22,11 @@ public: virtual bool isValid() const override; /** + * @return a list of content types contained in a mod + */ + virtual std::vector<EContent> getContents() const override; + + /** * @brief clear all caches held for this mod */ virtual void clearCaches() override; @@ -49,13 +55,20 @@ public slots: protected: /** - * @brief check if the content of this mod is valid. + * @brief Check if the content of this mod is valid. * - * @return true if the content is valid, false otherwize. + * @return true if the content is valid, false otherwise. **/ virtual bool doTestValid() const; /** + * @brief Compute the contents for this mod. + * + * @return the contents for this mod. + **/ + virtual std::vector<EContent> doGetContents() const { return {}; } + + /** * @brief Retrieve a file tree corresponding to the underlying disk content * of this mod. * @@ -122,12 +135,16 @@ protected: private: - // Mutex: - mutable std::mutex m_Mutex; + /** + * @return a file tree for this mod. + */ + std::shared_ptr<const MOBase::IFileTree> updateFileTree() const; - // File tree representing the content of the disk. A null pointer indicates - // that the content needs to be loaded from the disk: - mutable std::shared_ptr<const MOBase::IFileTree> m_FileTree = nullptr; + MOShared::MemoizedLocked< + std::shared_ptr<const MOBase::IFileTree>, + decltype(&ModInfoWithConflictInfo::updateFileTree)> m_FileTree; + MOShared::MemoizedLocked<bool, decltype(&ModInfoWithConflictInfo::doTestValid)> m_Valid; + MOShared::MemoizedLocked<std::vector<EContent>, decltype(&ModInfoWithConflictInfo::doGetContents)> m_Contents; MOShared::DirectoryEntry **m_DirectoryStructure; |
