mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 01:54:20 +03:00
fix(ModFolderPage): prevent stale profile saves during tab switching
Signed-off-by: Vivek Kushwaha <notvivekkushwaha@gmail.com>
This commit is contained in:
parent
f9e8dbfcc0
commit
352b45bf5e
2 changed files with 45 additions and 33 deletions
|
|
@ -198,7 +198,10 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
|
||||||
// Install viewport filter so clicking blank space in the list clears selection.
|
// Install viewport filter so clicking blank space in the list clears selection.
|
||||||
ui->treeView->viewport()->installEventFilter(this);
|
ui->treeView->viewport()->installEventFilter(this);
|
||||||
|
|
||||||
connect(m_profileTabBar, &QTabBar::currentChanged, this, &ModFolderPage::onProfileTabChanged);
|
connect(m_profileTabBar, &QTabBar::currentChanged, this, [this](int index) {
|
||||||
|
++m_profileSwitchGeneration;
|
||||||
|
applyProfileSwitch(index, m_profileSwitchGeneration);
|
||||||
|
});
|
||||||
connect(m_profileTabBar, &QTabBar::customContextMenuRequested,
|
connect(m_profileTabBar, &QTabBar::customContextMenuRequested,
|
||||||
this, &ModFolderPage::onTabContextMenuRequested);
|
this, &ModFolderPage::onTabContextMenuRequested);
|
||||||
connect(m_newTabButton, &QToolButton::clicked, this, [this] {
|
connect(m_newTabButton, &QToolButton::clicked, this, [this] {
|
||||||
|
|
@ -279,30 +282,15 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
|
||||||
savedIndex = 0;
|
savedIndex = 0;
|
||||||
}
|
}
|
||||||
m_profileTabBar->setCurrentIndex(savedIndex);
|
m_profileTabBar->setCurrentIndex(savedIndex);
|
||||||
onProfileTabChanged(m_profileTabBar->currentIndex());
|
applyProfileSwitch(m_profileTabBar->currentIndex(), m_profileSwitchGeneration);
|
||||||
|
|
||||||
connect(m_model, &ResourceFolderModel::updateFinished, this, [this]() {
|
|
||||||
qDebug().noquote().nospace()
|
|
||||||
<< "[SAVE_TRIGGER]\n"
|
|
||||||
<< "source = updateFinished\n"
|
|
||||||
<< "currentProfile = " << m_currentProfile;
|
|
||||||
if (m_profileLoading) {
|
|
||||||
m_profileLoading = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
saveCurrentProfileState();
|
|
||||||
});
|
|
||||||
connect(m_model, &QAbstractItemModel::dataChanged, this, [this]() {
|
connect(m_model, &QAbstractItemModel::dataChanged, this, [this]() {
|
||||||
qDebug().noquote().nospace()
|
if (!m_applyingProfile) {
|
||||||
<< "[SAVE_TRIGGER]\n"
|
qDebug().noquote().nospace()
|
||||||
<< "source = dataChanged\n"
|
<< "[SAVE_TRIGGER]\n"
|
||||||
<< "currentProfile = " << m_currentProfile;
|
<< "source = dataChanged\n"
|
||||||
saveCurrentProfileState();
|
<< "currentProfile = " << m_currentProfile;
|
||||||
});
|
saveCurrentProfileState();
|
||||||
connect(m_model, &ResourceFolderModel::updateFinished, this, [this] {
|
|
||||||
if (!m_currentProfile.isEmpty()) {
|
|
||||||
QSet<QString> expectedMods = m_profileStates.value(m_currentProfile);
|
|
||||||
compareModelToProfileState("updateFinished() FIRED", m_model, expectedMods, ++g_logSequence);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -749,7 +737,7 @@ void ModFolderPage::saveCurrentProfileState()
|
||||||
<< "savedModsCount:" << enabledMods.size();
|
<< "savedModsCount:" << enabledMods.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ModFolderPage::onProfileTabChanged(int index) {
|
void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
||||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() START"
|
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() START"
|
||||||
<< "index:" << index
|
<< "index:" << index
|
||||||
<< "thread:" << QThread::currentThreadId()
|
<< "thread:" << QThread::currentThreadId()
|
||||||
|
|
@ -823,7 +811,23 @@ void ModFolderPage::onProfileTabChanged(int index) {
|
||||||
}
|
}
|
||||||
|
|
||||||
compareModelToProfileState("BEFORE update()", m_model, enabledMods, ++g_logSequence);
|
compareModelToProfileState("BEFORE update()", m_model, enabledMods, ++g_logSequence);
|
||||||
bool started = m_model->update();
|
|
||||||
|
// Capture generation token. If tab changes again before this update
|
||||||
|
// completes, the token will be stale and we discard the result.
|
||||||
|
int capturedGeneration = generation;
|
||||||
|
m_applyingProfile = true;
|
||||||
|
connect(m_model, &ResourceFolderModel::updateFinished, this,
|
||||||
|
[this, capturedGeneration] {
|
||||||
|
if (capturedGeneration == m_profileSwitchGeneration) {
|
||||||
|
saveCurrentProfileState();
|
||||||
|
}
|
||||||
|
m_applyingProfile = false;
|
||||||
|
},
|
||||||
|
Qt::SingleShotConnection);
|
||||||
|
|
||||||
|
m_model->update();
|
||||||
|
|
||||||
|
|
||||||
qDebug().noquote().nospace()
|
qDebug().noquote().nospace()
|
||||||
<< "[ProfileSwitch]\n"
|
<< "[ProfileSwitch]\n"
|
||||||
<< "Profile: " << tabName << "\n"
|
<< "Profile: " << tabName << "\n"
|
||||||
|
|
@ -842,6 +846,7 @@ void ModFolderPage::onProfileTabChanged(int index) {
|
||||||
setActiveProfileForModel(m_model, QStringLiteral("None"));
|
setActiveProfileForModel(m_model, QStringLiteral("None"));
|
||||||
m_profileTabBar->setProperty("currentProfileName", QString());
|
m_profileTabBar->setProperty("currentProfileName", QString());
|
||||||
m_profileLoading = false;
|
m_profileLoading = false;
|
||||||
|
m_applyingProfile = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() END"
|
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() END"
|
||||||
|
|
@ -1119,6 +1124,8 @@ void ModFolderPage::onTabEnableAll(int tabIndex)
|
||||||
{
|
{
|
||||||
if (m_profileTabBar->currentIndex() != tabIndex) {
|
if (m_profileTabBar->currentIndex() != tabIndex) {
|
||||||
m_profileTabBar->setCurrentIndex(tabIndex);
|
m_profileTabBar->setCurrentIndex(tabIndex);
|
||||||
|
} else {
|
||||||
|
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||||
}
|
}
|
||||||
// Build the full index list and enable every mod in the active profile.
|
// Build the full index list and enable every mod in the active profile.
|
||||||
QModelIndexList allIndices;
|
QModelIndexList allIndices;
|
||||||
|
|
@ -1136,6 +1143,8 @@ void ModFolderPage::onTabDisableAll(int tabIndex)
|
||||||
{
|
{
|
||||||
if (m_profileTabBar->currentIndex() != tabIndex) {
|
if (m_profileTabBar->currentIndex() != tabIndex) {
|
||||||
m_profileTabBar->setCurrentIndex(tabIndex);
|
m_profileTabBar->setCurrentIndex(tabIndex);
|
||||||
|
} else {
|
||||||
|
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||||
}
|
}
|
||||||
// Build the full index list and disable every mod in the active profile.
|
// Build the full index list and disable every mod in the active profile.
|
||||||
QModelIndexList allIndices;
|
QModelIndexList allIndices;
|
||||||
|
|
|
||||||
|
|
@ -48,25 +48,25 @@
|
||||||
|
|
||||||
class ModFolderPage : public ExternalResourcesPage {
|
class ModFolderPage : public ExternalResourcesPage {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
inline bool handleNoModLoader();
|
inline bool handleNoModLoader();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget* parent = nullptr);
|
explicit ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget* parent = nullptr);
|
||||||
virtual ~ModFolderPage();
|
virtual ~ModFolderPage();
|
||||||
|
|
||||||
void setFilter(const QString& filter) { m_fileSelectionFilter = filter; }
|
void setFilter(const QString& filter) { m_fileSelectionFilter = filter; }
|
||||||
|
|
||||||
virtual QString displayName() const override { return tr("Mods"); }
|
virtual QString displayName() const override { return tr("Mods"); }
|
||||||
virtual QIcon icon() const override { return QIcon::fromTheme("loadermods"); }
|
virtual QIcon icon() const override { return QIcon::fromTheme("loadermods"); }
|
||||||
virtual QString id() const override { return "mods"; }
|
virtual QString id() const override { return "mods"; }
|
||||||
virtual QString helpPage() const override { return "Loader-mods"; }
|
virtual QString helpPage() const override { return "Loader-mods"; }
|
||||||
|
|
||||||
virtual bool shouldDisplay() const override;
|
virtual bool shouldDisplay() const override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void updateFrame(const QModelIndex& current, const QModelIndex& previous) override;
|
void updateFrame(const QModelIndex& current, const QModelIndex& previous) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void removeItems(const QItemSelection& selection) override;
|
void removeItems(const QItemSelection& selection) override;
|
||||||
|
|
||||||
|
|
@ -76,7 +76,6 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||||
void deleteModMetadata();
|
void deleteModMetadata();
|
||||||
void exportModMetadata();
|
void exportModMetadata();
|
||||||
void changeModVersion();
|
void changeModVersion();
|
||||||
void onProfileTabChanged(int index);
|
|
||||||
void onAddProfileClicked();
|
void onAddProfileClicked();
|
||||||
void onRemoveProfileClicked();
|
void onRemoveProfileClicked();
|
||||||
void saveCurrentProfileState();
|
void saveCurrentProfileState();
|
||||||
|
|
@ -91,6 +90,8 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||||
void onTabDisableAll(int tabIndex);
|
void onTabDisableAll(int tabIndex);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void applyProfileSwitch(int index, int generation);
|
||||||
|
|
||||||
// Creates a new profile tab with the given initial mod-enable state.
|
// Creates a new profile tab with the given initial mod-enable state.
|
||||||
// Pass an empty QSet for a blank slate; pass a copied QSet for duplication.
|
// Pass an empty QSet for a blank slate; pass a copied QSet for duplication.
|
||||||
void createProfile(const QString& name, const QSet<QString>& initialState, int insertAfterIndex = -1);
|
void createProfile(const QString& name, const QSet<QString>& initialState, int insertAfterIndex = -1);
|
||||||
|
|
@ -120,6 +121,8 @@ class ModFolderPage : public ExternalResourcesPage {
|
||||||
QString m_settingsPrefix;
|
QString m_settingsPrefix;
|
||||||
bool m_destructorStarted = false;
|
bool m_destructorStarted = false;
|
||||||
bool m_profileLoading = false;
|
bool m_profileLoading = false;
|
||||||
|
int m_profileSwitchGeneration = 0;
|
||||||
|
bool m_applyingProfile = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CoreModFolderPage : public ModFolderPage {
|
class CoreModFolderPage : public ModFolderPage {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue