Merge 3d546ac7ed
into a6642d5f79
This commit is contained in:
commit
faefc2c9da
|
@ -139,10 +139,6 @@ Java_org_dolphinemu_dolphinemu_features_settings_model_NativeConfig_unloadGameIn
|
|||
JNIEXPORT void JNICALL Java_org_dolphinemu_dolphinemu_features_settings_model_NativeConfig_save(
|
||||
JNIEnv*, jclass, jint layer)
|
||||
{
|
||||
// HostThreadLock is used to ensure we don't try to save to SYSCONF at the same time as
|
||||
// emulation shutdown does
|
||||
HostThreadLock guard;
|
||||
|
||||
return GetLayer(layer, {})->Save();
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "Core/AchievementManager.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Config/MainSettings.h"
|
||||
#include "Core/Config/SYSCONFSettings.h"
|
||||
#include "Core/ConfigLoaders/BaseConfigLoader.h"
|
||||
#include "Core/ConfigLoaders/NetPlayConfigLoader.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
|
@ -148,6 +147,8 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
|||
|
||||
Core::UpdateWantDeterminism(system, /*initial*/ true);
|
||||
|
||||
ConfigLoaders::TransferSYSCONFControlToGuest();
|
||||
|
||||
if (system.IsWii())
|
||||
{
|
||||
Core::InitializeWiiRoot(Core::WantsDeterminism());
|
||||
|
@ -156,13 +157,16 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
|||
if (!Core::WantsDeterminism())
|
||||
{
|
||||
Core::BackupWiiSettings();
|
||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta);
|
||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta,
|
||||
ConfigLoaders::SkipIfControlledByGuest::No);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Meta, [](const Config::Location& location) {
|
||||
return Config::GetActiveLayerForConfig(location) >= Config::LayerType::Movie;
|
||||
});
|
||||
ConfigLoaders::SaveToSYSCONF(
|
||||
Config::LayerType::Meta, ConfigLoaders::SkipIfControlledByGuest::No,
|
||||
[](const Config::Location& location) {
|
||||
return Config::GetActiveLayerForConfig(location) >= Config::LayerType::Movie;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,35 +187,6 @@ bool BootCore(Core::System& system, std::unique_ptr<BootParameters> boot,
|
|||
return Core::Init(system, std::move(boot), wsi);
|
||||
}
|
||||
|
||||
// SYSCONF can be modified during emulation by the user and internally, which makes it
|
||||
// a bad idea to just always overwrite it with the settings from the base layer.
|
||||
//
|
||||
// Conversely, we also shouldn't just accept any changes to SYSCONF, as it may cause
|
||||
// temporary settings (from Movie, Netplay, game INIs, etc.) to stick around.
|
||||
//
|
||||
// To avoid inconveniences in most cases, we accept changes that aren't being overridden by a
|
||||
// non-base layer, and restore only the overridden settings.
|
||||
static void RestoreSYSCONF()
|
||||
{
|
||||
// This layer contains the new SYSCONF settings (including any temporary settings).
|
||||
Config::Layer temp_layer(Config::LayerType::Base);
|
||||
// Use a separate loader so the temp layer doesn't automatically save
|
||||
ConfigLoaders::GenerateBaseConfigLoader()->Load(&temp_layer);
|
||||
|
||||
for (const auto& setting : Config::SYSCONF_SETTINGS)
|
||||
{
|
||||
std::visit(
|
||||
[&](auto* info) {
|
||||
// If this setting was overridden, then we copy the base layer value back to the SYSCONF.
|
||||
// Otherwise we leave the new value in the SYSCONF.
|
||||
if (Config::GetActiveLayerForConfig(*info) == Config::LayerType::Base)
|
||||
Config::SetBase(*info, temp_layer.Get(*info));
|
||||
},
|
||||
setting.config_info);
|
||||
}
|
||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Base);
|
||||
}
|
||||
|
||||
void RestoreConfig()
|
||||
{
|
||||
Core::ShutdownWiiRoot();
|
||||
|
@ -219,7 +194,11 @@ void RestoreConfig()
|
|||
if (!Core::WiiRootIsTemporary())
|
||||
{
|
||||
Core::RestoreWiiSettings(Core::RestoreReason::EmulationEnd);
|
||||
RestoreSYSCONF();
|
||||
ConfigLoaders::TransferSYSCONFControlFromGuest(ConfigLoaders::WriteBackChangedValues::Yes);
|
||||
}
|
||||
else
|
||||
{
|
||||
ConfigLoaders::TransferSYSCONFControlFromGuest(ConfigLoaders::WriteBackChangedValues::No);
|
||||
}
|
||||
|
||||
Config::ClearCurrentRunLayer();
|
||||
|
|
|
@ -9,12 +9,14 @@
|
|||
#include <list>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <variant>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Config/Config.h"
|
||||
#include "Common/Config/Layer.h"
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
@ -23,17 +25,67 @@
|
|||
#include "Core/Config/SYSCONFSettings.h"
|
||||
#include "Core/ConfigLoaders/IsSettingSaveable.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/IOS/IOS.h"
|
||||
#include "Core/IOS/USB/Bluetooth/BTBase.h"
|
||||
#include "Core/SysConf.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
static bool s_sysconf_controlled_by_guest = false;
|
||||
static std::recursive_mutex s_sysconf_lock;
|
||||
|
||||
namespace ConfigLoaders
|
||||
{
|
||||
void SaveToSYSCONF(Config::LayerType layer, std::function<bool(const Config::Location&)> predicate)
|
||||
void TransferSYSCONFControlToGuest()
|
||||
{
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
std::lock_guard lock(s_sysconf_lock);
|
||||
|
||||
ASSERT(!s_sysconf_controlled_by_guest);
|
||||
s_sysconf_controlled_by_guest = true;
|
||||
}
|
||||
|
||||
void TransferSYSCONFControlFromGuest(WriteBackChangedValues write_back_changed_values)
|
||||
{
|
||||
std::lock_guard lock(s_sysconf_lock);
|
||||
|
||||
ASSERT(s_sysconf_controlled_by_guest);
|
||||
s_sysconf_controlled_by_guest = false;
|
||||
|
||||
if (write_back_changed_values == WriteBackChangedValues::Yes)
|
||||
{
|
||||
// SYSCONF can be modified during emulation by the user and internally, which makes it
|
||||
// a bad idea to just always overwrite it with the settings from the base layer.
|
||||
//
|
||||
// Conversely, we also shouldn't just accept any changes to SYSCONF, as it may cause
|
||||
// temporary settings (from Movie, Netplay, game INIs, etc.) to stick around.
|
||||
//
|
||||
// To avoid inconveniences in most cases, we accept changes that aren't being overridden by a
|
||||
// non-base layer, and restore only the overridden settings.
|
||||
|
||||
// This layer contains the new SYSCONF settings (including any temporary settings).
|
||||
Config::Layer temp_layer(Config::LayerType::Base);
|
||||
// Use a separate loader so the temp layer doesn't automatically save
|
||||
GenerateBaseConfigLoader()->Load(&temp_layer);
|
||||
|
||||
for (const auto& setting : Config::SYSCONF_SETTINGS)
|
||||
{
|
||||
std::visit(
|
||||
[&](auto* info) {
|
||||
// If this setting was overridden, then we copy the base layer value back to the
|
||||
// SYSCONF. Otherwise we leave the new value in the SYSCONF.
|
||||
if (Config::GetActiveLayerForConfig(*info) == Config::LayerType::Base)
|
||||
Config::SetBase(*info, temp_layer.Get(*info));
|
||||
},
|
||||
setting.config_info);
|
||||
}
|
||||
ConfigLoaders::SaveToSYSCONF(Config::LayerType::Base);
|
||||
}
|
||||
}
|
||||
|
||||
void SaveToSYSCONF(Config::LayerType layer, SkipIfControlledByGuest skip,
|
||||
std::function<bool(const Config::Location&)> predicate)
|
||||
{
|
||||
std::lock_guard lock(s_sysconf_lock);
|
||||
if (skip != SkipIfControlledByGuest::No && s_sysconf_controlled_by_guest)
|
||||
return;
|
||||
|
||||
IOS::HLE::Kernel ios;
|
||||
|
@ -182,7 +234,8 @@ public:
|
|||
private:
|
||||
void LoadFromSYSCONF(Config::Layer* layer)
|
||||
{
|
||||
if (Core::IsRunning(Core::System::GetInstance()))
|
||||
std::lock_guard lock(s_sysconf_lock);
|
||||
if (s_sysconf_controlled_by_guest)
|
||||
return;
|
||||
|
||||
IOS::HLE::Kernel ios;
|
||||
|
|
|
@ -15,7 +15,22 @@ struct Location;
|
|||
|
||||
namespace ConfigLoaders
|
||||
{
|
||||
enum class WriteBackChangedValues
|
||||
{
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
enum class SkipIfControlledByGuest
|
||||
{
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
void TransferSYSCONFControlToGuest();
|
||||
void TransferSYSCONFControlFromGuest(WriteBackChangedValues write_back_changed_values);
|
||||
void SaveToSYSCONF(Config::LayerType layer,
|
||||
SkipIfControlledByGuest skip = SkipIfControlledByGuest::Yes,
|
||||
std::function<bool(const Config::Location&)> predicate = {});
|
||||
std::unique_ptr<Config::ConfigLayerLoader> GenerateBaseConfigLoader();
|
||||
} // namespace ConfigLoaders
|
||||
|
|
Loading…
Reference in New Issue