Qt: Fix settings not applying immediately when editing profile

This commit is contained in:
Stenzek 2024-11-14 00:16:28 +10:00
parent 2da32d8e57
commit 8ec9c90c82
No known key found for this signature in database
6 changed files with 107 additions and 33 deletions

View File

@ -186,6 +186,7 @@ static void AccumulatePreFrameSleepTime(Common::Timer::Value current_time);
static void UpdateDisplayVSync();
static bool UpdateGameSettingsLayer();
static void UpdateInputSettingsLayer(std::string input_profile_name, std::unique_lock<std::mutex>& lock);
static void UpdateRunningGame(const std::string_view path, CDImage* image, bool booting);
static bool CheckForRequiredSubQ(Error* error);
@ -1461,13 +1462,35 @@ void System::ApplySettings(bool display_osd_messages)
Host::CheckForSettingsChanges(old_config);
}
bool System::ReloadGameSettings(bool display_osd_messages)
void System::ReloadGameSettings(bool display_osd_messages)
{
if (!IsValid() || !UpdateGameSettingsLayer())
return false;
return;
ApplySettings(display_osd_messages);
}
void System::ReloadInputProfile(bool display_osd_messages)
{
if (!IsValid() || !s_state.game_settings_interface)
return;
// per-game configuration?
if (s_state.game_settings_interface->GetBoolValue("ControllerPorts", "UseGameSettingsForController", false))
{
// update the whole game settings layer.
UpdateGameSettingsLayer();
}
else if (std::string profile_name =
s_state.game_settings_interface->GetStringValue("ControllerPorts", "InputProfileName");
!profile_name.empty())
{
// only have to reload the input layer
auto lock = Host::GetSettingsLock();
UpdateInputSettingsLayer(std::move(profile_name), lock);
}
ApplySettings(display_osd_messages);
return true;
}
bool System::UpdateGameSettingsLayer()
@ -1506,6 +1529,16 @@ bool System::UpdateGameSettingsLayer()
Host::Internal::SetGameSettingsLayer(new_interface.get(), lock);
s_state.game_settings_interface = std::move(new_interface);
UpdateInputSettingsLayer(std::move(input_profile_name), lock);
if (!IsReplayingGPUDump())
Cheats::ReloadCheats(false, true, false, true);
return true;
}
void System::UpdateInputSettingsLayer(std::string input_profile_name, std::unique_lock<std::mutex>& lock)
{
std::unique_ptr<INISettingsInterface> input_interface;
if (!input_profile_name.empty())
{
@ -1531,11 +1564,6 @@ bool System::UpdateGameSettingsLayer()
Host::Internal::SetInputSettingsLayer(input_interface.get(), lock);
s_state.input_settings_interface = std::move(input_interface);
s_state.input_profile_name = std::move(input_profile_name);
if (!IsReplayingGPUDump())
Cheats::ReloadCheats(false, true, false, true);
return true;
}
void System::ResetSystem()

View File

@ -236,7 +236,10 @@ void SetDefaultSettings(SettingsInterface& si);
void ApplySettings(bool display_osd_messages);
/// Reloads game specific settings, and applys any changes present.
bool ReloadGameSettings(bool display_osd_messages);
void ReloadGameSettings(bool display_osd_messages);
/// Reloads input profile, depending on whether it is a specific profile or game configuration.
void ReloadInputProfile(bool display_osd_messages);
/// Reloads input sources.
void ReloadInputSources();

View File

@ -801,7 +801,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
sb->setMinimum(si.IntegerMinValue());
sb->setMaximum(si.IntegerMaxValue());
sb->setSingleStep(si.IntegerStepValue());
SettingWidgetBinder::BindWidgetToIntSetting(sif, sb, section, std::move(key_name), si.IntegerDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileInt(sif, sb, section, std::move(key_name),
si.IntegerDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
layout->addWidget(sb, current_row, 1, 1, 3);
current_row++;
@ -814,8 +815,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
cb->setObjectName(QString::fromUtf8(si.name));
for (u32 j = 0; si.options[j] != nullptr; j++)
cb->addItem(qApp->translate(cinfo->name, si.options[j]));
SettingWidgetBinder::BindWidgetToIntSetting(sif, cb, section, std::move(key_name), si.IntegerDefaultValue(),
si.IntegerMinValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileInt(sif, cb, section, std::move(key_name),
si.IntegerDefaultValue(), si.IntegerMinValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
layout->addWidget(cb, current_row, 1, 1, 3);
current_row++;
@ -838,8 +839,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
sb->setSuffix(QStringLiteral("%"));
}
SettingWidgetBinder::BindWidgetToNormalizedSetting(sif, sb, section, std::move(key_name), si.multiplier,
si.FloatDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileNormalized(sif, sb, section, std::move(key_name),
si.multiplier, si.FloatDefaultValue());
}
else
{
@ -847,7 +848,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
sb->setMaximum(si.FloatMaxValue());
sb->setSingleStep(si.FloatStepValue());
SettingWidgetBinder::BindWidgetToFloatSetting(sif, sb, section, std::move(key_name), si.FloatDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileFloat(sif, sb, section, std::move(key_name),
si.FloatDefaultValue());
}
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
layout->addWidget(sb, current_row, 1, 1, 3);
@ -859,7 +861,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
{
QLineEdit* le = new QLineEdit(this);
le->setObjectName(QString::fromUtf8(si.name));
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(sif, le, section, std::move(key_name),
si.StringDefaultValue());
layout->addWidget(new QLabel(qApp->translate(cinfo->name, si.display_name), this), current_row, 0);
layout->addWidget(le, current_row, 1, 1, 3);
current_row++;
@ -871,7 +874,8 @@ void ControllerCustomSettingsWidget::createSettingWidgets(ControllerBindingWidge
QLineEdit* le = new QLineEdit(this);
le->setObjectName(QString::fromUtf8(si.name));
QPushButton* browse_button = new QPushButton(tr("Browse..."), this);
SettingWidgetBinder::BindWidgetToStringSetting(sif, le, section, std::move(key_name), si.StringDefaultValue());
ControllerSettingWidgetBinder::BindWidgetToInputProfileString(sif, le, section, std::move(key_name),
si.StringDefaultValue());
connect(browse_button, &QPushButton::clicked, [this, le]() {
QString path = QDir::toNativeSeparators(QFileDialog::getOpenFileName(this, tr("Select File")));
if (!path.isEmpty())

View File

@ -38,7 +38,7 @@ static void BindWidgetToInputProfileBool(SettingsInterface* sif, WidgetType* wid
const bool new_value = Accessor::getBoolValue(widget);
sif->SetBoolValue(section.c_str(), key.c_str(), new_value);
QtHost::SaveGameSettings(sif, false);
g_emu_thread->reloadGameSettings();
g_emu_thread->reloadInputProfile();
});
}
else
@ -55,6 +55,41 @@ static void BindWidgetToInputProfileBool(SettingsInterface* sif, WidgetType* wid
}
}
/// Interface specific method of BindWidgetToIntSetting().
template<typename WidgetType>
static void BindWidgetToInputProfileInt(SettingsInterface* sif, WidgetType* widget, std::string section,
std::string key, int default_value, int option_offset = 0)
{
using Accessor = SettingWidgetBinder::SettingAccessor<WidgetType>;
if (sif)
{
const int value = sif->GetIntValue(section.c_str(), key.c_str(), default_value) - option_offset;
Accessor::setIntValue(widget, value);
Accessor::connectValueChanged(widget,
[sif, widget, section = std::move(section), key = std::move(key), option_offset]() {
const int new_value = Accessor::getIntValue(widget);
sif->SetIntValue(section.c_str(), key.c_str(), new_value + option_offset);
QtHost::SaveGameSettings(sif, false);
g_emu_thread->reloadInputProfile();
});
}
else
{
const int value = Host::GetBaseIntSettingValue(section.c_str(), key.c_str(), default_value) - option_offset;
Accessor::setIntValue(widget, value);
Accessor::connectValueChanged(
widget, [widget, section = std::move(section), key = std::move(key), option_offset]() {
const int new_value = Accessor::getIntValue(widget);
Host::SetBaseIntSettingValue(section.c_str(), key.c_str(), new_value + option_offset);
Host::CommitBaseSettingChanges();
g_emu_thread->applySettings();
});
}
}
/// Interface specific method of BindWidgetToFloatSetting().
template<typename WidgetType>
static void BindWidgetToInputProfileFloat(SettingsInterface* sif, WidgetType* widget, std::string section,
@ -71,7 +106,7 @@ static void BindWidgetToInputProfileFloat(SettingsInterface* sif, WidgetType* wi
const float new_value = Accessor::getFloatValue(widget);
sif->SetFloatValue(section.c_str(), key.c_str(), new_value);
QtHost::SaveGameSettings(sif, false);
g_emu_thread->reloadGameSettings();
g_emu_thread->reloadInputProfile();
});
}
else
@ -104,7 +139,7 @@ static void BindWidgetToInputProfileNormalized(SettingsInterface* sif, WidgetTyp
const int new_value = Accessor::getIntValue(widget);
sif->SetFloatValue(section.c_str(), key.c_str(), static_cast<float>(new_value) / range);
QtHost::SaveGameSettings(sif, false);
g_emu_thread->reloadGameSettings();
g_emu_thread->reloadInputProfile();
});
}
else
@ -138,7 +173,7 @@ static void BindWidgetToInputProfileString(SettingsInterface* sif, WidgetType* w
Accessor::connectValueChanged(widget, [widget, sif, section = std::move(section), key = std::move(key)]() {
sif->SetStringValue(section.c_str(), key.c_str(), Accessor::getStringValue(widget).toUtf8().constData());
QtHost::SaveGameSettings(sif, false);
g_emu_thread->reloadGameSettings();
g_emu_thread->reloadInputProfile();
});
}
else
@ -185,19 +220,11 @@ static void BindWidgetToInputProfileEnumSetting(SettingsInterface* sif, WidgetTy
{
Accessor::connectValueChanged(
widget, [sif, widget, section = std::move(section), key = std::move(key), to_string_function]() {
if (std::optional<int> new_value = Accessor::getIntValue(widget); new_value.has_value())
{
const char* string_value =
to_string_function(static_cast<DataType>(static_cast<UnderlyingType>(new_value.value())));
sif->SetStringValue(section.c_str(), key.c_str(), string_value);
}
else
{
sif->DeleteValue(section.c_str(), key.c_str());
}
const DataType value = static_cast<DataType>(static_cast<UnderlyingType>(Accessor::getIntValue(widget)));
const char* string_value = to_string_function(value);
sif->SetStringValue(section.c_str(), key.c_str(), string_value);
QtHost::SaveGameSettings(sif, true);
g_emu_thread->reloadGameSettings();
g_emu_thread->reloadInputProfile();
});
}
else

View File

@ -675,6 +675,17 @@ void EmuThread::reloadGameSettings(bool display_osd_messages /* = false */)
System::ReloadGameSettings(display_osd_messages);
}
void EmuThread::reloadInputProfile(bool display_osd_messages /*= false*/)
{
if (!isCurrentThread())
{
QMetaObject::invokeMethod(this, "reloadInputProfile", Qt::QueuedConnection, Q_ARG(bool, display_osd_messages));
return;
}
System::ReloadInputProfile(display_osd_messages);
}
void EmuThread::updateEmuFolders()
{
if (!isCurrentThread())

View File

@ -168,6 +168,7 @@ public Q_SLOTS:
void setDefaultSettings(bool system = true, bool controller = true);
void applySettings(bool display_osd_messages = false);
void reloadGameSettings(bool display_osd_messages = false);
void reloadInputProfile(bool display_osd_messages = false);
void reloadCheats(bool reload_files, bool reload_enabled_list, bool verbose, bool verbose_if_changed);
void updateEmuFolders();
void updateControllerSettings();