mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2026-06-29 09:59:59 +03:00
fix(ModFolderPage): preserve profile state synchronization during cleanup
Signed-off-by: Vivek Kushwaha <notvivekkushwaha@gmail.com>
This commit is contained in:
parent
352b45bf5e
commit
8e85ecfd43
4 changed files with 12 additions and 348 deletions
|
|
@ -40,20 +40,10 @@
|
|||
#include "minecraft/MinecraftInstance.h"
|
||||
#include "minecraft/mod/ModFolderModel.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QAtomicInt>
|
||||
#include <QDebug>
|
||||
|
||||
extern QAtomicInt g_logSequence;
|
||||
extern QString getActiveProfileForModel(void* modelPtr);
|
||||
|
||||
ScanModFolders::ScanModFolders(LaunchTask* parent) : LaunchStep(parent) {}
|
||||
|
||||
ScanModFolders::~ScanModFolders()
|
||||
{
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "ScanModFolders::~ScanModFolders()"
|
||||
<< "thread:" << QThread::currentThreadId();
|
||||
}
|
||||
|
||||
void ScanModFolders::executeTask()
|
||||
|
|
@ -64,13 +54,6 @@ void ScanModFolders::executeTask()
|
|||
auto cores = m_inst->coreModList();
|
||||
auto nils = m_inst->nilModList();
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "ScanModFolders::executeTask() START"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "loaderModel:" << loaders << "profile:" << getActiveProfileForModel(loaders)
|
||||
<< "coreModel:" << cores << "profile:" << getActiveProfileForModel(cores)
|
||||
<< "nilModel:" << nils << "profile:" << getActiveProfileForModel(nils);
|
||||
|
||||
m_modsConnection = connect(loaders, &ModFolderModel::updateFinished, this, &ScanModFolders::modsDone);
|
||||
if (!loaders->update()) {
|
||||
m_modsDone = true;
|
||||
|
|
@ -109,17 +92,6 @@ void ScanModFolders::nilModsDone()
|
|||
void ScanModFolders::checkDone()
|
||||
{
|
||||
if (m_modsDone && m_coreModsDone && m_nilModsDone) {
|
||||
auto m_inst = m_parent->instance();
|
||||
auto loaders = m_inst->loaderModList();
|
||||
auto cores = m_inst->coreModList();
|
||||
auto nils = m_inst->nilModList();
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "ScanModFolders::checkDone() END"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "loaderModel:" << loaders << "profile:" << getActiveProfileForModel(loaders)
|
||||
<< "coreModel:" << cores << "profile:" << getActiveProfileForModel(cores)
|
||||
<< "nilModel:" << nils << "profile:" << getActiveProfileForModel(nils);
|
||||
|
||||
// Sever the connections to the persistent ModFolderModel singletons.
|
||||
// Without this, updateFinished() would re-invoke these slots the next
|
||||
|
|
|
|||
|
|
@ -1,12 +1,6 @@
|
|||
#include "ResourceFolderModel.h"
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QThread>
|
||||
#include <QAtomicInt>
|
||||
|
||||
extern QAtomicInt g_logSequence;
|
||||
extern QString getActiveProfileForModel(void* modelPtr);
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QFileInfo>
|
||||
|
|
@ -308,29 +302,9 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena
|
|||
|
||||
auto& resource = m_resources[row];
|
||||
|
||||
QString originalName = resource->getOriginalFileName();
|
||||
QString oldPath = resource->fileinfo().absoluteFilePath();
|
||||
bool wasEnabled = resource->enabled();
|
||||
|
||||
qDebug() << "[INSTRUMENTATION-MUTATION]" << ++g_logSequence
|
||||
<< "setResourceEnabled() START"
|
||||
<< "resource:" << originalName
|
||||
<< "wasEnabled:" << wasEnabled
|
||||
<< "oldPath:" << oldPath
|
||||
<< "action:" << (action == EnableAction::ENABLE ? "ENABLE" : (action == EnableAction::DISABLE ? "DISABLE" : "TOGGLE"));
|
||||
|
||||
// Preserve the row, but change its ID
|
||||
auto oldId = resource->internalId();
|
||||
bool ok = resource->enable(action);
|
||||
|
||||
qDebug() << "[INSTRUMENTATION-MUTATION]" << ++g_logSequence
|
||||
<< "setResourceEnabled() END"
|
||||
<< "resource:" << originalName
|
||||
<< "nowEnabled:" << resource->enabled()
|
||||
<< "newPath:" << resource->fileinfo().absoluteFilePath()
|
||||
<< "succeeded:" << ok;
|
||||
|
||||
if (!ok) {
|
||||
if (!resource->enable(action)) {
|
||||
succeeded = false;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -340,12 +314,6 @@ bool ResourceFolderModel::setResourceEnabled(const QModelIndexList& indexes, Ena
|
|||
m_resourcesIndex.remove(oldId);
|
||||
m_resourcesIndex[newId] = row;
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT dataChanged() (setResourceEnabled)"
|
||||
<< "row:" << row
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << this
|
||||
<< "profile:" << getActiveProfileForModel(this);
|
||||
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
|
||||
|
|
@ -380,11 +348,6 @@ bool ResourceFolderModel::update()
|
|||
m_scheduledUpdate = false;
|
||||
update();
|
||||
} else {
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT updateFinished()"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << this
|
||||
<< "profile:" << getActiveProfileForModel(this);
|
||||
emit updateFinished();
|
||||
}
|
||||
},
|
||||
|
|
@ -469,12 +432,6 @@ void ResourceFolderModel::onParseSucceeded(int ticket, const QString& resourceId
|
|||
}
|
||||
|
||||
int row = m_resourcesIndex[resourceId];
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT dataChanged() (onParseSucceeded)"
|
||||
<< "row:" << row
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << this
|
||||
<< "profile:" << getActiveProfileForModel(this);
|
||||
emit dataChanged(index(row), index(row, columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
|
||||
|
|
@ -899,21 +856,6 @@ void ResourceFolderModel::onParseFailed(int ticket, const QString& resourceId)
|
|||
|
||||
void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>& newSet, QMap<QString, Resource::Ptr>& newResources)
|
||||
{
|
||||
{
|
||||
QSet<QString> enabledBefore;
|
||||
for (const auto& res : m_resources) {
|
||||
if (res->enabled()) {
|
||||
enabledBefore.insert(res->getOriginalFileName());
|
||||
}
|
||||
}
|
||||
qDebug() << "[INSTRUMENTATION-APPLYUPDATES] START"
|
||||
<< "seq:" << ++g_logSequence
|
||||
<< "profile:" << getActiveProfileForModel(this)
|
||||
<< "enabledBefore:" << enabledBefore
|
||||
<< "currentSet:" << currentSet
|
||||
<< "newSet:" << newSet;
|
||||
}
|
||||
|
||||
// see if the kept resources changed in some way
|
||||
{
|
||||
QSet<QString> keptSet = currentSet;
|
||||
|
|
@ -933,12 +875,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
|
|||
currentResource->updateIssues(m_instance);
|
||||
|
||||
if (hadIssues != currentResource->hasIssues()) {
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT dataChanged() (applyUpdates unchanged file)"
|
||||
<< "row:" << row
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << this
|
||||
<< "profile:" << getActiveProfileForModel(this);
|
||||
emit dataChanged(index(row, 0), index(row, columnCount({}) - 1));
|
||||
}
|
||||
continue;
|
||||
|
|
@ -958,12 +894,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
|
|||
newResource->updateIssues(m_instance);
|
||||
|
||||
resolveResource(m_resources.at(row));
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT dataChanged() (applyUpdates changed file)"
|
||||
<< "row:" << row
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << this
|
||||
<< "profile:" << getActiveProfileForModel(this);
|
||||
emit dataChanged(index(row, 0), index(row, columnCount(QModelIndex()) - 1));
|
||||
}
|
||||
}
|
||||
|
|
@ -1029,42 +959,6 @@ void ResourceFolderModel::applyUpdates(QSet<QString>& currentSet, QSet<QString>&
|
|||
idx++;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
QSet<QString> enabledAfter;
|
||||
for (const auto& res : m_resources) {
|
||||
if (res->enabled()) {
|
||||
enabledAfter.insert(res->getOriginalFileName());
|
||||
}
|
||||
}
|
||||
|
||||
QSet<QString> keptSet = currentSet;
|
||||
keptSet.intersect(newSet);
|
||||
QSet<QString> removedSet = currentSet;
|
||||
removedSet.subtract(newSet);
|
||||
QSet<QString> addedSet = newSet;
|
||||
addedSet.subtract(currentSet);
|
||||
|
||||
qDebug() << "[INSTRUMENTATION-APPLYUPDATES] END"
|
||||
<< "seq:" << ++g_logSequence
|
||||
<< "profile:" << getActiveProfileForModel(this)
|
||||
<< "enabledAfter:" << enabledAfter
|
||||
<< "added:" << addedSet
|
||||
<< "removed:" << removedSet;
|
||||
for (const auto& kept : keptSet) {
|
||||
auto rowIt = m_resourcesIndex.constFind(kept);
|
||||
if (rowIt != m_resourcesIndex.constEnd()) {
|
||||
auto row = rowIt.value();
|
||||
auto& newResource = newResources[kept];
|
||||
const auto& currentResource = m_resources.at(row);
|
||||
if (newResource->enabled() != currentResource->enabled()) {
|
||||
qDebug() << " -> kept resource changed enabled state:" << kept
|
||||
<< "before:" << currentResource->enabled()
|
||||
<< "after:" << newResource->enabled();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Resource::Ptr ResourceFolderModel::find(QString id)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -73,66 +73,9 @@
|
|||
#include "tasks/Task.h"
|
||||
#include "ui/dialogs/ProgressDialog.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <QMap>
|
||||
#include <QThread>
|
||||
#include <QAtomicInt>
|
||||
|
||||
QMutex g_activeProfilesMutex;
|
||||
QMap<void*, QString> g_activeProfiles;
|
||||
QAtomicInt g_logSequence(0);
|
||||
|
||||
QString getActiveProfileForModel(void* modelPtr) {
|
||||
QMutexLocker locker(&g_activeProfilesMutex);
|
||||
return g_activeProfiles.value(modelPtr, QStringLiteral("Unknown/None"));
|
||||
}
|
||||
|
||||
void setActiveProfileForModel(void* modelPtr, const QString& profile) {
|
||||
QMutexLocker locker(&g_activeProfilesMutex);
|
||||
g_activeProfiles[modelPtr] = profile;
|
||||
}
|
||||
|
||||
void compareModelToProfileState(const QString& stage, ModFolderModel* model, const QSet<QString>& expectedMods, int seq) {
|
||||
QSet<QString> actualMods;
|
||||
for (int i = 0; i < model->rowCount(); ++i) {
|
||||
const Resource& res = model->at(i);
|
||||
if (res.enabled()) {
|
||||
actualMods.insert(res.getOriginalFileName());
|
||||
}
|
||||
}
|
||||
|
||||
bool match = (expectedMods == actualMods);
|
||||
qDebug() << "[INSTRUMENTATION-DIVERGE]" << seq << stage
|
||||
<< "expectedCount:" << expectedMods.size()
|
||||
<< "actualCount:" << actualMods.size()
|
||||
<< "match:" << match;
|
||||
|
||||
if (!match) {
|
||||
QSet<QString> missing = expectedMods;
|
||||
missing.subtract(actualMods);
|
||||
QSet<QString> unexpected = actualMods;
|
||||
unexpected.subtract(expectedMods);
|
||||
|
||||
qDebug() << " -> Expected Set:" << expectedMods;
|
||||
qDebug() << " -> Actual Set:" << actualMods;
|
||||
qDebug() << " -> Missing mods:" << missing;
|
||||
qDebug() << " -> Unexpected enabled mods:" << unexpected;
|
||||
}
|
||||
}
|
||||
|
||||
ModFolderPage::~ModFolderPage()
|
||||
{
|
||||
m_destructorStarted = true;
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "ModFolderPage::~ModFolderPage() entered"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "currentProfile:" << m_currentProfile
|
||||
<< "destructorStarted:" << m_destructorStarted;
|
||||
|
||||
{
|
||||
QMutexLocker locker(&g_activeProfilesMutex);
|
||||
g_activeProfiles.remove(m_model);
|
||||
}
|
||||
|
||||
if (m_filterWindow) {
|
||||
m_filterWindow->removeEventFilter(this);
|
||||
|
|
@ -142,7 +85,6 @@ ModFolderPage::~ModFolderPage()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget* parent)
|
||||
: ExternalResourcesPage(inst, model, parent), m_model(model)
|
||||
{
|
||||
|
|
@ -150,7 +92,7 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
|
|||
m_profileTabBar->setExpanding(false);
|
||||
m_profileTabBar->setDrawBase(false); // no underline bar — matches Settings tab style
|
||||
m_profileTabBar->setDocumentMode(false);
|
||||
m_profileTabBar->setUsesScrollButtons(true);
|
||||
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
|
||||
m_profileTabBar->setElideMode(Qt::ElideRight);
|
||||
m_profileTabBar->setContextMenuPolicy(Qt::CustomContextMenu);
|
||||
// Palette-based stylesheet: selected tab uses palette(base) to match the
|
||||
|
|
@ -258,23 +200,14 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
|
|||
m_profileTabBar->blockSignals(true);
|
||||
for (const QString& name : profileList) {
|
||||
m_profileTabBar->addTab(name);
|
||||
|
||||
|
||||
QString key = profileKey(name);
|
||||
m_instance->settings()->getOrRegisterSetting(key, QStringList());
|
||||
QStringList saved = m_instance->settings()->get(key).toStringList();
|
||||
m_profileStates[name] = QSet<QString>(saved.begin(), saved.end());
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = constructor\n"
|
||||
<< "profile = " << name << "\n"
|
||||
<< "count = " << m_profileStates[name].size();
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (constructor)"
|
||||
<< "profile:" << name
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << m_profileStates[name].size();
|
||||
}
|
||||
m_profileTabBar->blockSignals(false);
|
||||
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
|
||||
|
||||
m_instance->settings()->getOrRegisterSetting(lastActiveIndexKey(), 0);
|
||||
int savedIndex = m_instance->settings()->get(lastActiveIndexKey()).toInt();
|
||||
|
|
@ -286,10 +219,6 @@ ModFolderPage::ModFolderPage(BaseInstance* inst, ModFolderModel* model, QWidget*
|
|||
|
||||
connect(m_model, &QAbstractItemModel::dataChanged, this, [this]() {
|
||||
if (!m_applyingProfile) {
|
||||
qDebug().noquote().nospace()
|
||||
<< "[SAVE_TRIGGER]\n"
|
||||
<< "source = dataChanged\n"
|
||||
<< "currentProfile = " << m_currentProfile;
|
||||
saveCurrentProfileState();
|
||||
}
|
||||
});
|
||||
|
|
@ -672,20 +601,7 @@ inline bool ModFolderPage::handleNoModLoader()
|
|||
|
||||
void ModFolderPage::saveCurrentProfileState()
|
||||
{
|
||||
if (m_profileLoading) {
|
||||
return;
|
||||
}
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() START"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profile:" << m_currentProfile
|
||||
<< "destructorStarted:" << m_destructorStarted;
|
||||
|
||||
if (m_currentProfile.isEmpty()) {
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (empty profile)"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model;
|
||||
return;
|
||||
}
|
||||
bool stillExists = false;
|
||||
|
|
@ -696,10 +612,6 @@ void ModFolderPage::saveCurrentProfileState()
|
|||
}
|
||||
}
|
||||
if (!stillExists) {
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (profile no longer exists)"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profile:" << m_currentProfile;
|
||||
return;
|
||||
}
|
||||
QSet<QString> enabledMods;
|
||||
|
|
@ -710,41 +622,13 @@ void ModFolderPage::saveCurrentProfileState()
|
|||
}
|
||||
}
|
||||
m_profileStates[m_currentProfile] = enabledMods;
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = saveCurrentProfileState\n"
|
||||
<< "profile = " << m_currentProfile << "\n"
|
||||
<< "count = " << m_profileStates[m_currentProfile].size();
|
||||
QString key = profileKey(m_currentProfile);
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (saveCurrentProfileState)"
|
||||
<< "profile:" << m_currentProfile
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << enabledMods.size();
|
||||
|
||||
m_instance->settings()->getOrRegisterSetting(key, QStringList());
|
||||
m_instance->settings()->set(key, QStringList(enabledMods.begin(), enabledMods.end()));
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "settings()->set write (saveCurrentProfileState)"
|
||||
<< "profile:" << m_currentProfile
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << enabledMods.size();
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "saveCurrentProfileState() END (saved)"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profile:" << m_currentProfile
|
||||
<< "savedModsCount:" << enabledMods.size();
|
||||
}
|
||||
|
||||
void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() START"
|
||||
<< "index:" << index
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profileBefore:" << m_currentProfile
|
||||
<< "destructorStarted:" << m_destructorStarted;
|
||||
|
||||
if (m_currentProfile.isEmpty()) {
|
||||
QVariant val = m_profileTabBar->property("currentProfileName");
|
||||
m_currentProfile = val.isValid() ? val.toString() : QString();
|
||||
|
|
@ -752,40 +636,21 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
|||
|
||||
saveCurrentProfileState();
|
||||
|
||||
m_profileLoading = true;
|
||||
|
||||
if (index >= 0 && index < m_profileTabBar->count()) {
|
||||
QString tabName = m_profileTabBar->tabText(index);
|
||||
m_currentProfile = tabName;
|
||||
setActiveProfileForModel(m_model, m_currentProfile);
|
||||
m_profileTabBar->setProperty("currentProfileName", tabName);
|
||||
m_instance->settings()->set(lastActiveIndexKey(), index);
|
||||
|
||||
QSet<QString> enabledMods;
|
||||
if (m_profileStates.contains(tabName)) {
|
||||
enabledMods = m_profileStates[tabName];
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "profile load (onProfileTabChanged): cached state read"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profile:" << tabName
|
||||
<< "modsCount:" << enabledMods.size();
|
||||
} else {
|
||||
QString key = profileKey(tabName);
|
||||
m_instance->settings()->getOrRegisterSetting(key, QStringList());
|
||||
QStringList saved = m_instance->settings()->get(key).toStringList();
|
||||
enabledMods = QSet<QString>(saved.begin(), saved.end());
|
||||
m_profileStates[tabName] = enabledMods;
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = onProfileTabChanged\n"
|
||||
<< "profile = " << tabName << "\n"
|
||||
<< "count = " << m_profileStates[tabName].size();
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (onProfileTabChanged - settings read)"
|
||||
<< "profile:" << tabName
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << enabledMods.size();
|
||||
}
|
||||
|
||||
QModelIndexList toEnable;
|
||||
|
|
@ -803,6 +668,7 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
|||
}
|
||||
}
|
||||
}
|
||||
m_applyingProfile = true;
|
||||
if (!toEnable.isEmpty()) {
|
||||
m_model->setResourceEnabled(toEnable, EnableAction::ENABLE);
|
||||
}
|
||||
|
|
@ -810,12 +676,9 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
|||
m_model->setResourceEnabled(toDisable, EnableAction::DISABLE);
|
||||
}
|
||||
|
||||
compareModelToProfileState("BEFORE update()", m_model, enabledMods, ++g_logSequence);
|
||||
|
||||
// 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) {
|
||||
|
|
@ -827,33 +690,11 @@ void ModFolderPage::applyProfileSwitch(int index, int generation) {
|
|||
|
||||
m_model->update();
|
||||
|
||||
|
||||
qDebug().noquote().nospace()
|
||||
<< "[ProfileSwitch]\n"
|
||||
<< "Profile: " << tabName << "\n"
|
||||
<< "Enable: " << toEnable.size() << "\n"
|
||||
<< "Disable: " << toDisable.size() << "\n"
|
||||
<< "updateStarted: " << (started ? "true" : "false");
|
||||
compareModelToProfileState("AFTER update()", m_model, enabledMods, ++g_logSequence);
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "EMIT m_model->dataChanged() (onProfileTabChanged layout update)"
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profile:" << m_currentProfile;
|
||||
emit m_model->dataChanged(m_model->index(0, 0), m_model->index(m_model->rowCount() - 1, m_model->columnCount(QModelIndex()) - 1));
|
||||
} else {
|
||||
m_currentProfile = QString();
|
||||
setActiveProfileForModel(m_model, QStringLiteral("None"));
|
||||
m_profileTabBar->setProperty("currentProfileName", QString());
|
||||
m_profileLoading = false;
|
||||
m_applyingProfile = false;
|
||||
}
|
||||
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence << "onProfileTabChanged() END"
|
||||
<< "index:" << index
|
||||
<< "thread:" << QThread::currentThreadId()
|
||||
<< "model:" << m_model
|
||||
<< "profileAfter:" << m_currentProfile;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -893,25 +734,10 @@ void ModFolderPage::createProfile(const QString& name, const QSet<QString>& init
|
|||
|
||||
// Persist state to memory and settings
|
||||
m_profileStates[name] = initialState;
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = createProfile\n"
|
||||
<< "profile = " << name << "\n"
|
||||
<< "count = " << m_profileStates[name].size();
|
||||
QString key = profileKey(name);
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (createProfile)"
|
||||
<< "profile:" << name
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << initialState.size();
|
||||
|
||||
m_instance->settings()->getOrRegisterSetting(key, QStringList());
|
||||
m_instance->settings()->set(key, QStringList(initialState.begin(), initialState.end()));
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "settings()->set write (createProfile)"
|
||||
<< "profile:" << name
|
||||
<< "key:" << key
|
||||
<< "modsCount:" << initialState.size();
|
||||
|
||||
// Insert tab at the correct position
|
||||
if (insertAfterIndex >= 0 && insertAfterIndex < m_profileTabBar->count()) {
|
||||
|
|
@ -919,6 +745,7 @@ void ModFolderPage::createProfile(const QString& name, const QSet<QString>& init
|
|||
} else {
|
||||
m_profileTabBar->addTab(name);
|
||||
}
|
||||
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
|
||||
|
||||
saveProfileList();
|
||||
}
|
||||
|
|
@ -1007,16 +834,6 @@ void ModFolderPage::onTabDuplicate(int sourceIndex)
|
|||
}
|
||||
}
|
||||
m_profileStates[m_currentProfile] = enabledMods;
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = onTabDuplicate\n"
|
||||
<< "profile = " << m_currentProfile << "\n"
|
||||
<< "count = " << m_profileStates[m_currentProfile].size();
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (onTabDuplicate)"
|
||||
<< "profile:" << m_currentProfile
|
||||
<< "key:" << profileKey(m_currentProfile)
|
||||
<< "modsCount:" << enabledMods.size();
|
||||
}
|
||||
|
||||
QString sourceName = m_profileTabBar->tabText(sourceIndex);
|
||||
|
|
@ -1056,16 +873,6 @@ void ModFolderPage::onTabRename(int tabIndex)
|
|||
// Migrate in-memory state to the new key
|
||||
if (m_profileStates.contains(oldName)) {
|
||||
m_profileStates[newName] = m_profileStates.take(oldName);
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = onTabRename\n"
|
||||
<< "profile = " << newName << "\n"
|
||||
<< "count = " << m_profileStates[newName].size();
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "m_profileStates write (onTabRename)"
|
||||
<< "profile:" << newName
|
||||
<< "key:" << profileKey(newName)
|
||||
<< "modsCount:" << m_profileStates[newName].size();
|
||||
}
|
||||
|
||||
// Migrate settings: read → reset old key → write under new key
|
||||
|
|
@ -1075,11 +882,6 @@ void ModFolderPage::onTabRename(int tabIndex)
|
|||
m_instance->settings()->reset(oldKey);
|
||||
m_instance->settings()->getOrRegisterSetting(newKey, QStringList());
|
||||
m_instance->settings()->set(newKey, stateData);
|
||||
qDebug() << "[INSTRUMENTATION]" << ++g_logSequence
|
||||
<< "settings()->set write (onTabRename)"
|
||||
<< "profile:" << newName
|
||||
<< "key:" << newKey
|
||||
<< "modsCount:" << stateData.size();
|
||||
|
||||
// Update the visible tab label
|
||||
m_profileTabBar->setTabText(tabIndex, newName);
|
||||
|
|
@ -1109,14 +911,11 @@ void ModFolderPage::onTabRemove(int tabIndex)
|
|||
if (response != QMessageBox::Yes) return;
|
||||
|
||||
m_profileStates.remove(name);
|
||||
qDebug().noquote().nospace()
|
||||
<< "[PROFILE_STATE_WRITE]\n"
|
||||
<< "reason = onTabRemove\n"
|
||||
<< "profile = " << name << "\n"
|
||||
<< "count = 0";
|
||||
|
||||
m_instance->settings()->reset(profileKey(name));
|
||||
|
||||
m_profileTabBar->removeTab(tabIndex);
|
||||
m_profileTabBar->setUsesScrollButtons(m_profileTabBar->count() > 1);
|
||||
saveProfileList();
|
||||
}
|
||||
|
||||
|
|
@ -1124,9 +923,9 @@ void ModFolderPage::onTabEnableAll(int tabIndex)
|
|||
{
|
||||
if (m_profileTabBar->currentIndex() != tabIndex) {
|
||||
m_profileTabBar->setCurrentIndex(tabIndex);
|
||||
} else {
|
||||
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||
}
|
||||
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||
|
||||
// Build the full index list and enable every mod in the active profile.
|
||||
QModelIndexList allIndices;
|
||||
allIndices.reserve(m_model->rowCount());
|
||||
|
|
@ -1143,9 +942,9 @@ void ModFolderPage::onTabDisableAll(int tabIndex)
|
|||
{
|
||||
if (m_profileTabBar->currentIndex() != tabIndex) {
|
||||
m_profileTabBar->setCurrentIndex(tabIndex);
|
||||
} else {
|
||||
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||
}
|
||||
applyProfileSwitch(tabIndex, m_profileSwitchGeneration);
|
||||
|
||||
// Build the full index list and disable every mod in the active profile.
|
||||
QModelIndexList allIndices;
|
||||
allIndices.reserve(m_model->rowCount());
|
||||
|
|
|
|||
|
|
@ -120,7 +120,6 @@ class ModFolderPage : public ExternalResourcesPage {
|
|||
QString m_currentProfile;
|
||||
QString m_settingsPrefix;
|
||||
bool m_destructorStarted = false;
|
||||
bool m_profileLoading = false;
|
||||
int m_profileSwitchGeneration = 0;
|
||||
bool m_applyingProfile = false;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue