summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2020-05-24 23:33:21 +0200
committerMikaël Capelle <capelle.mikael@gmail.com>2020-05-24 23:33:21 +0200
commit238e233c18d22d01e966efaa86975f5f37bb7fa2 (patch)
tree3c4eb7af80d4e47fa85f296e5c5aafbed0b5e415
parent0aac4f3291d65ebc1b0bbee744fca347ecef7022 (diff)
Use memoization for file tree, contents and validity of ModInfo.
-rw-r--r--src/modinforegular.cpp3
-rw-r--r--src/modinforegular.h4
-rw-r--r--src/modinfowithconflictinfo.cpp25
-rw-r--r--src/modinfowithconflictinfo.h31
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;