summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMikaël Capelle <capelle.mikael@gmail.com>2021-02-09 20:14:03 +0100
committerMikaël Capelle <capelle.mikael@gmail.com>2021-02-09 20:23:42 +0100
commit595f6eccf615c0cf70c8d32e3edb515578efddc9 (patch)
tree2f5ebc24ccfd4a8e59eea6b896559c757375e62a /src
parent7d36bc20d0a6c327079141149a7f138c0f7726ac (diff)
Better refresh of override markers and conflicts.
Diffstat (limited to 'src')
-rw-r--r--src/modinfo.h5
-rw-r--r--src/modinfowithconflictinfo.cpp107
-rw-r--r--src/modinfowithconflictinfo.h53
-rw-r--r--src/modlist.cpp8
-rw-r--r--src/modlist.h4
-rw-r--r--src/modlistview.cpp5
-rw-r--r--src/organizercore.cpp77
-rw-r--r--src/organizercore.h5
8 files changed, 129 insertions, 135 deletions
diff --git a/src/modinfo.h b/src/modinfo.h
index f93296d2..b835f352 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -897,11 +897,6 @@ public: // Conflicts
//
virtual const std::set<unsigned int>& getModArchiveLooseOverwritten() const { return s_EmptySet; }
- /**
- * @brief Update conflict information.
- */
- virtual void doConflictCheck() const {}
-
public slots:
/**
diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp
index 7a51a727..7cdee6e6 100644
--- a/src/modinfowithconflictinfo.cpp
+++ b/src/modinfowithconflictinfo.cpp
@@ -19,11 +19,11 @@ ModInfoWithConflictInfo::ModInfoWithConflictInfo(OrganizerCore& core) :
m_FileTree([this]() { return QDirFileTree::makeTree(absolutePath()); }),
m_Valid([this]() { return doIsValid(); }),
m_Contents([this]() { return doGetContents(); }),
- m_HasLooseOverwrite(false), m_HasHiddenFiles(false) {}
+ m_Conflicts([this]() { return doConflictCheck(); }) { }
void ModInfoWithConflictInfo::clearCaches()
{
- m_LastConflictCheck = QTime();
+ m_Conflicts.invalidate();
}
std::vector<ModInfo::EFlag> ModInfoWithConflictInfo::getFlags() const
@@ -82,14 +82,9 @@ std::vector<ModInfo::EConflictFlag> ModInfoWithConflictInfo::getConflictFlags()
}
-void ModInfoWithConflictInfo::doConflictCheck() const
+ModInfoWithConflictInfo::Conflicts ModInfoWithConflictInfo::doConflictCheck() const
{
- m_OverwriteList.clear();
- m_OverwrittenList.clear();
- m_ArchiveOverwriteList.clear();
- m_ArchiveOverwrittenList.clear();
- m_ArchiveLooseOverwriteList.clear();
- m_ArchiveLooseOverwrittenList.clear();
+ Conflicts conflicts;
bool providesAnything = false;
bool hasHiddenFiles = false;
@@ -102,10 +97,6 @@ void ModInfoWithConflictInfo::doConflictCheck() const
std::wstring name = ToWString(this->name());
const std::wstring hideExt = ToWString(ModInfo::s_HiddenExt);
- m_CurrentConflictState = CONFLICT_NONE;
- m_ArchiveConflictState = CONFLICT_NONE;
- m_ArchiveConflictLooseState = CONFLICT_NONE;
-
if (m_Core.directoryStructure()->originExists(name)) {
FilesOrigin &origin = m_Core.directoryStructure()->getOriginByName(name);
std::vector<FileEntryPtr> files = origin.getFiles();
@@ -168,12 +159,12 @@ void ModInfoWithConflictInfo::doConflictCheck() const
unsigned int altIndex = ModInfo::getIndex(ToQString(altOrigin.getName()));
if (!file->isFromArchive()) {
if (!archiveData.isValid())
- m_OverwrittenList.insert(altIndex);
+ conflicts.m_OverwrittenList.insert(altIndex);
else
- m_ArchiveLooseOverwrittenList.insert(altIndex);
+ conflicts.m_ArchiveLooseOverwrittenList.insert(altIndex);
}
else {
- m_ArchiveOverwrittenList.insert(altIndex);
+ conflicts.m_ArchiveOverwrittenList.insert(altIndex);
}
} else {
providesAnything = true;
@@ -188,21 +179,21 @@ void ModInfoWithConflictInfo::doConflictCheck() const
if (!altInfo.isFromArchive()) {
if (!archiveData.isValid()) {
if (origin.getPriority() > altOrigin.getPriority()) {
- m_OverwriteList.insert(altIndex);
+ conflicts.m_OverwriteList.insert(altIndex);
} else {
- m_OverwrittenList.insert(altIndex);
+ conflicts.m_OverwrittenList.insert(altIndex);
}
} else {
- m_ArchiveLooseOverwrittenList.insert(altIndex);
+ conflicts.m_ArchiveLooseOverwrittenList.insert(altIndex);
}
} else {
if (!archiveData.isValid()) {
- m_ArchiveLooseOverwriteList.insert(altIndex);
+ conflicts.m_ArchiveLooseOverwriteList.insert(altIndex);
} else {
if (archiveData.order() > altInfo.archive().order()) {
- m_ArchiveOverwriteList.insert(altIndex);
+ conflicts.m_ArchiveOverwriteList.insert(altIndex);
} else if (archiveData.order() < altInfo.archive().order()) {
- m_ArchiveOverwrittenList.insert(altIndex);
+ conflicts.m_ArchiveOverwrittenList.insert(altIndex);
}
}
}
@@ -210,66 +201,51 @@ void ModInfoWithConflictInfo::doConflictCheck() const
}
}
}
- m_LastConflictCheck = QTime::currentTime();
if (files.size() != 0) {
if (!providesAnything)
- m_CurrentConflictState = CONFLICT_REDUNDANT;
- else if (!m_OverwriteList.empty() && !m_OverwrittenList.empty())
- m_CurrentConflictState = CONFLICT_MIXED;
- else if (!m_OverwriteList.empty())
- m_CurrentConflictState = CONFLICT_OVERWRITE;
- else if (!m_OverwrittenList.empty())
- m_CurrentConflictState = CONFLICT_OVERWRITTEN;
+ conflicts.m_CurrentConflictState = CONFLICT_REDUNDANT;
+ else if (!conflicts.m_OverwriteList.empty() && !conflicts.m_OverwrittenList.empty())
+ conflicts.m_CurrentConflictState = CONFLICT_MIXED;
+ else if (!conflicts.m_OverwriteList.empty())
+ conflicts.m_CurrentConflictState = CONFLICT_OVERWRITE;
+ else if (!conflicts.m_OverwrittenList.empty())
+ conflicts.m_CurrentConflictState = CONFLICT_OVERWRITTEN;
- if (!m_ArchiveOverwriteList.empty() && !m_ArchiveOverwrittenList.empty())
- m_ArchiveConflictState = CONFLICT_MIXED;
- else if (!m_ArchiveOverwriteList.empty())
- m_ArchiveConflictState = CONFLICT_OVERWRITE;
- else if (!m_ArchiveOverwrittenList.empty())
- m_ArchiveConflictState = CONFLICT_OVERWRITTEN;
+ if (!conflicts.m_ArchiveOverwriteList.empty() && !conflicts.m_ArchiveOverwrittenList.empty())
+ conflicts.m_ArchiveConflictState = CONFLICT_MIXED;
+ else if (!conflicts.m_ArchiveOverwriteList.empty())
+ conflicts.m_ArchiveConflictState = CONFLICT_OVERWRITE;
+ else if (!conflicts.m_ArchiveOverwrittenList.empty())
+ conflicts.m_ArchiveConflictState = CONFLICT_OVERWRITTEN;
- if (!m_ArchiveLooseOverwrittenList.empty() && !m_ArchiveLooseOverwriteList.empty())
- m_ArchiveConflictLooseState = CONFLICT_MIXED;
- else if (!m_ArchiveLooseOverwrittenList.empty())
- m_ArchiveConflictLooseState = CONFLICT_OVERWRITTEN;
- else if (!m_ArchiveLooseOverwriteList.empty())
- m_ArchiveConflictLooseState = CONFLICT_OVERWRITE;
+ if (!conflicts.m_ArchiveLooseOverwrittenList.empty() && !conflicts.m_ArchiveLooseOverwriteList.empty())
+ conflicts.m_ArchiveConflictLooseState = CONFLICT_MIXED;
+ else if (!conflicts.m_ArchiveLooseOverwrittenList.empty())
+ conflicts.m_ArchiveConflictLooseState = CONFLICT_OVERWRITTEN;
+ else if (!conflicts.m_ArchiveLooseOverwriteList.empty())
+ conflicts.m_ArchiveConflictLooseState = CONFLICT_OVERWRITE;
- m_HasHiddenFiles = hasHiddenFiles;
+ conflicts.m_HasHiddenFiles = hasHiddenFiles;
}
}
+
+ return conflicts;
}
ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isConflicted() const
{
- // this is costy so cache the result
- QTime now = QTime::currentTime();
- if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
- doConflictCheck();
- }
-
- return m_CurrentConflictState;
+ return m_Conflicts.value().m_CurrentConflictState;
}
ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isArchiveConflicted() const
{
- QTime now = QTime::currentTime();
- if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
- doConflictCheck();
- }
-
- return m_ArchiveConflictState;
+ return m_Conflicts.value().m_ArchiveConflictState;
}
ModInfoWithConflictInfo::EConflictType ModInfoWithConflictInfo::isLooseArchiveConflicted() const
{
- QTime now = QTime::currentTime();
- if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
- doConflictCheck();
- }
-
- return m_ArchiveConflictLooseState;
+ return m_Conflicts.value().m_ArchiveConflictLooseState;
}
@@ -294,12 +270,7 @@ bool ModInfoWithConflictInfo::isRedundant() const
bool ModInfoWithConflictInfo::hasHiddenFiles() const
{
- QTime now = QTime::currentTime();
- if (m_LastConflictCheck.isNull() || (m_LastConflictCheck.secsTo(now) > 10)) {
- doConflictCheck();
- }
-
- return m_HasHiddenFiles;
+ return m_Conflicts.value().m_HasHiddenFiles;
}
void ModInfoWithConflictInfo::diskContentModified() {
diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h
index c9cddb60..2136e093 100644
--- a/src/modinfowithconflictinfo.h
+++ b/src/modinfowithconflictinfo.h
@@ -54,14 +54,12 @@ public:
*/
void clearCaches() override;
- const std::set<unsigned int>& getModOverwrite() const override { return m_OverwriteList; }
- const std::set<unsigned int>& getModOverwritten() const override { return m_OverwrittenList; }
- const std::set<unsigned int>& getModArchiveOverwrite() const override { return m_ArchiveOverwriteList; }
- const std::set<unsigned int>& getModArchiveOverwritten() const override { return m_ArchiveOverwrittenList; }
- const std::set<unsigned int>& getModArchiveLooseOverwrite() const override { return m_ArchiveLooseOverwriteList; }
- const std::set<unsigned int>& getModArchiveLooseOverwritten() const override { return m_ArchiveLooseOverwrittenList; }
-
- void doConflictCheck() const override;
+ const std::set<unsigned int>& getModOverwrite() const override { return m_Conflicts.value().m_OverwriteList; }
+ const std::set<unsigned int>& getModOverwritten() const override { return m_Conflicts.value().m_OverwrittenList; }
+ const std::set<unsigned int>& getModArchiveOverwrite() const override { return m_Conflicts.value().m_ArchiveOverwriteList; }
+ const std::set<unsigned int>& getModArchiveOverwritten() const override { return m_Conflicts.value().m_ArchiveOverwrittenList; }
+ const std::set<unsigned int>& getModArchiveLooseOverwrite() const override { return m_Conflicts.value().m_ArchiveLooseOverwriteList; }
+ const std::set<unsigned int>& getModArchiveLooseOverwritten() const override { return m_Conflicts.value().m_ArchiveLooseOverwrittenList; }
public slots:
@@ -72,11 +70,8 @@ public slots:
protected:
- /**
- * @brief Check if the content of this mod is valid.
- *
- * @return true if the content is valid, false otherwise.
- **/
+ // check if the content of this mod is valid
+ //
virtual bool doIsValid() const;
/**
@@ -136,23 +131,27 @@ protected:
private:
+ struct Conflicts {
+ EConflictType m_CurrentConflictState = CONFLICT_NONE;
+ EConflictType m_ArchiveConflictState = CONFLICT_NONE;
+ EConflictType m_ArchiveConflictLooseState = CONFLICT_NONE;
+ bool m_HasLooseOverwrite = false;
+ bool m_HasHiddenFiles = false;
+
+ std::set<unsigned int> m_OverwriteList; // indices of mods overritten by this mod
+ std::set<unsigned int> m_OverwrittenList; // indices of mods overwriting this mod
+ std::set<unsigned int> m_ArchiveOverwriteList; // indices of mods with archive files overritten by this mod
+ std::set<unsigned int> m_ArchiveOverwrittenList; // indices of mods with archive files overwriting this mod
+ std::set<unsigned int> m_ArchiveLooseOverwriteList; // indices of mods with archives being overwritten by this mod's loose files
+ std::set<unsigned int> m_ArchiveLooseOverwrittenList; // indices of mods with loose files overwriting this mod's archive files
+ };
+
+ Conflicts doConflictCheck() const;
+
MOBase::MemoizedLocked<std::shared_ptr<const MOBase::IFileTree>> m_FileTree;
MOBase::MemoizedLocked<bool> m_Valid;
MOBase::MemoizedLocked<std::set<int>> m_Contents;
-
- mutable EConflictType m_CurrentConflictState;
- mutable EConflictType m_ArchiveConflictState;
- mutable EConflictType m_ArchiveConflictLooseState;
- mutable bool m_HasLooseOverwrite;
- mutable bool m_HasHiddenFiles;
- mutable QTime m_LastConflictCheck;
-
- mutable std::set<unsigned int> m_OverwriteList; // indices of mods overritten by this mod
- mutable std::set<unsigned int> m_OverwrittenList; // indices of mods overwriting this mod
- mutable std::set<unsigned int> m_ArchiveOverwriteList; // indices of mods with archive files overritten by this mod
- mutable std::set<unsigned int> m_ArchiveOverwrittenList; // indices of mods with archive files overwriting this mod
- mutable std::set<unsigned int> m_ArchiveLooseOverwriteList; // indices of mods with archives being overwritten by this mod's loose files
- mutable std::set<unsigned int> m_ArchiveLooseOverwrittenList; // indices of mods with loose files overwriting this mod's archive files
+ MOBase::MemoizedLocked<Conflicts> m_Conflicts;
};
diff --git a/src/modlist.cpp b/src/modlist.cpp
index de24fbbd..48f65d3a 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -549,7 +549,6 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
m_Profile->setModEnabled(modID, enabled);
m_Modified = true;
m_LastCheck.restart();
- emit modStatesChanged({ index });
emit tutorialModlistUpdate();
}
result = true;
@@ -997,11 +996,15 @@ void ModList::notifyModRemoved(QString const& modName) const
void ModList::notifyModStateChanged(QList<unsigned int> modIndices) const
{
+ QModelIndexList indices;
std::map<QString, IModList::ModStates> mods;
for (auto modIndex : modIndices) {
+ indices.append(index(modIndex, 0));
ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex);
mods.emplace(modInfo->name(), state(modIndex));
}
+
+ emit modStatesChanged(indices);
m_ModStateChanged(mods);
}
@@ -1404,7 +1407,6 @@ bool ModList::toggleState(const QModelIndexList& indices)
m_Profile->setModsEnabled(modsToEnable, modsToDisable);
- emit modStatesChanged(indices);
emit tutorialModlistUpdate();
m_Modified = true;
@@ -1430,6 +1432,4 @@ void ModList::setActive(const QModelIndexList& indices, bool active)
else {
m_Profile->setModsEnabled({}, mods);
}
-
- emit modStatesChanged(indices);
}
diff --git a/src/modlist.h b/src/modlist.h
index e201de27..6a3a2901 100644
--- a/src/modlist.h
+++ b/src/modlist.h
@@ -258,11 +258,11 @@ signals:
// the sorting of the list can only be manually changed if the list is sorted by priority
// in which case the move is intended to change the priority of a mod.
//
- void modPrioritiesChanged(const QModelIndexList& indices);
+ void modPrioritiesChanged(const QModelIndexList& indices) const;
// emitted when the state (active/inactive) of one or multiple mods have changed
//
- void modStatesChanged(const QModelIndexList& indices);
+ void modStatesChanged(const QModelIndexList& indices) const;
/**
* @brief emitted when the model wants a text to be displayed by the UI
diff --git a/src/modlistview.cpp b/src/modlistview.cpp
index d7f90c9f..cb4cb2fb 100644
--- a/src/modlistview.cpp
+++ b/src/modlistview.cpp
@@ -689,7 +689,10 @@ void ModListView::setup(OrganizerCore& core, CategoryFactory& factory, MainWindo
connect(m_core, &OrganizerCore::profileChanged, this, &ModListView::onProfileChanged);
connect(core.modList(), &ModList::modPrioritiesChanged, [=](auto&& indices) { onModPrioritiesChanged(indices); });
connect(core.modList(), &ModList::clearOverwrite, [=] { m_actions->clearOverwrite(); });
- connect(core.modList(), &ModList::modStatesChanged, [=] { updateModCount(); });
+ connect(core.modList(), &ModList::modStatesChanged, [=] {
+ updateModCount();
+ setOverwriteMarkers(selectionModel()->selectedRows());
+ });
connect(core.modList(), &ModList::modelReset, [=] { clearOverwriteMarkers(); });
// proxy for various group by
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 3874560b..e47a6e30 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -1565,6 +1565,45 @@ void OrganizerCore::profileRefresh()
refresh();
}
+void OrganizerCore::clearCaches(std::vector<unsigned int> const& indices) const
+{
+ const auto insert = [](auto& dest, const auto& from) {
+ dest.insert(from.begin(), from.end());
+ };
+ std::set<unsigned int> allIndices;
+ for (const auto index : indices) {
+ ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
+
+ if (m_CurrentProfile->modEnabled(index)) {
+ // if the mod is enabled, we need to first clear its cache so that
+ // getModOverwrite(), ..., returns the newly conflicting mods (in case
+ // the mod just got enabled)
+ modInfo->clearCaches();
+ insert(allIndices, modInfo->getModOverwrite());
+ insert(allIndices, modInfo->getModOverwritten());
+ insert(allIndices, modInfo->getModArchiveOverwrite());
+ insert(allIndices, modInfo->getModArchiveOverwritten());
+ insert(allIndices, modInfo->getModArchiveLooseOverwrite());
+ insert(allIndices, modInfo->getModArchiveLooseOverwritten());
+ }
+ else {
+ // if the mod is disabled, we need to first fetch the conflicting
+ // mods, and then clear the cache
+ insert(allIndices, modInfo->getModOverwrite());
+ insert(allIndices, modInfo->getModOverwritten());
+ insert(allIndices, modInfo->getModArchiveOverwrite());
+ insert(allIndices, modInfo->getModArchiveOverwritten());
+ insert(allIndices, modInfo->getModArchiveLooseOverwrite());
+ insert(allIndices, modInfo->getModArchiveLooseOverwritten());
+ modInfo->clearCaches();
+ }
+ }
+
+ for (auto& index : allIndices) {
+ ModInfo::getByIndex(index)->clearCaches();
+ }
+}
+
void OrganizerCore::modPrioritiesChanged(const QModelIndexList& indices)
{
for (unsigned int i = 0; i < currentProfile()->numMods(); ++i) {
@@ -1579,30 +1618,13 @@ void OrganizerCore::modPrioritiesChanged(const QModelIndexList& indices)
currentProfile()->writeModlist();
directoryStructure()->getFileRegister()->sortOrigins();
+ std::vector<unsigned int> vindices;
+
for (auto& idx : indices) {
- ModInfo::Ptr modInfo = ModInfo::getByIndex(idx.data(ModList::IndexRole).toInt());
- // clear caches on all mods conflicting with the moved mod
- for (int i : modInfo->getModOverwrite()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModOverwritten()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModArchiveOverwrite()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModArchiveOverwritten()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModArchiveLooseOverwrite()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- for (int i : modInfo->getModArchiveLooseOverwritten()) {
- ModInfo::getByIndex(i)->clearCaches();
- }
- // update conflict check on the moved mod
- modInfo->doConflictCheck();
+ vindices.push_back(idx.data(ModList::IndexRole).toInt());
}
+
+ clearCaches(vindices);
}
void OrganizerCore::modStatusChanged(unsigned int index)
@@ -1622,7 +1644,6 @@ void OrganizerCore::modStatusChanged(unsigned int index)
m_UserInterface->archivesWriter().write();
}
}
- modInfo->clearCaches();
for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) {
ModInfo::Ptr modInfo = ModInfo::getByIndex(i);
@@ -1637,7 +1658,7 @@ void OrganizerCore::modStatusChanged(unsigned int index)
m_DirectoryStructure->getFileRegister()->sortOrigins();
refreshLists();
-
+ clearCaches({ index });
m_ModList.notifyModStateChanged({ index });
} catch (const std::exception &e) {
@@ -1649,18 +1670,17 @@ void OrganizerCore::modStatusChanged(QList<unsigned int> index) {
try {
QMap<unsigned int, ModInfo::Ptr> modsToEnable;
QMap<unsigned int, ModInfo::Ptr> modsToDisable;
+ std::vector<unsigned int> vindices;
for (auto idx : index) {
if (m_CurrentProfile->modEnabled(idx)) {
modsToEnable[idx] = ModInfo::getByIndex(idx);
} else {
modsToDisable[idx] = ModInfo::getByIndex(idx);
}
+ vindices.push_back(idx);
}
if (!modsToEnable.isEmpty()) {
updateModsInDirectoryStructure(modsToEnable);
- for (auto modInfo : modsToEnable.values()) {
- modInfo->clearCaches();
- }
}
if (!modsToDisable.isEmpty()) {
updateModsActiveState(modsToDisable.keys(), false);
@@ -1689,8 +1709,9 @@ void OrganizerCore::modStatusChanged(QList<unsigned int> index) {
m_DirectoryStructure->getFileRegister()->sortOrigins();
refreshLists();
-
+ clearCaches(vindices);
m_ModList.notifyModStateChanged(index);
+
} catch (const std::exception &e) {
reportError(tr("failed to update mod list: %1").arg(e.what()));
}
diff --git a/src/organizercore.h b/src/organizercore.h
index c00d0d42..e6274e36 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -405,6 +405,11 @@ private:
void updateModActiveState(int index, bool active);
void updateModsActiveState(const QList<unsigned int> &modIndices, bool active);
+ // clear the conflict caches of all the given mods, and the mods in conflict
+ // with the given mods
+ //
+ void clearCaches(std::vector<unsigned int> const& indices) const;
+
bool createDirectory(const QString &path);
QString oldMO1HookDll() const;