Skip to content

Commit

Permalink
fix: bug for loading features due to missing keys
Browse files Browse the repository at this point in the history
  • Loading branch information
alandtse committed Oct 15, 2024
1 parent 39343d8 commit 6ee1730
Show file tree
Hide file tree
Showing 2 changed files with 124 additions and 90 deletions.
212 changes: 123 additions & 89 deletions src/State.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@
#include "Streamline.h"
#include "Upscaling.h"

#define JSON_LOAD(setting_name, condition, json_data, action) \
try { \
if (condition) { \
action; \
} \
} catch (const json::exception& e) { \
logger::warn("JSON Error processing '{}': {}. JSON section: {}", \
setting_name, e.what(), json_data.dump()); \
throw(e); \
} catch (const std::exception& e) { \
logger::warn("General error processing '{}': {}", setting_name, e.what()); \
}

void State::Draw()
{
const auto& shaderCache = SIE::ShaderCache::Instance();
Expand Down Expand Up @@ -130,7 +143,7 @@ static const std::string& GetConfigPath(State::ConfigMode a_configMode)
}
}

void State::Load(ConfigMode a_configMode)
void State::Load(ConfigMode a_configMode, bool a_allowReload)
{
ConfigMode configMode = a_configMode;
auto& shaderCache = SIE::ShaderCache::Instance();
Expand All @@ -139,6 +152,7 @@ void State::Load(ConfigMode a_configMode)
// Attempt to load the config file
auto tryLoadConfig = [&](const std::string& path) {
std::ifstream i(path);
logger::info("Attempting to open config file: {}", path);
if (!i.is_open()) {
logger::warn("Unable to open config file: {}", path);
return false;
Expand Down Expand Up @@ -174,109 +188,129 @@ void State::Load(ConfigMode a_configMode)
}

// Proceed with loading settings from the loaded configuration
if (settings["Menu"].is_object()) {
Menu::GetSingleton()->Load(settings["Menu"]);
}

if (settings["Advanced"].is_object()) {
json& advanced = settings["Advanced"];
if (advanced["Dump Shaders"].is_boolean())
shaderCache.SetDump(advanced["Dump Shaders"]);
if (advanced["Log Level"].is_number_integer())
logLevel = static_cast<spdlog::level::level_enum>((int)advanced["Log Level"]);
if (advanced["Shader Defines"].is_string())
SetDefines(advanced["Shader Defines"]);
if (advanced["Compiler Threads"].is_number_integer())
shaderCache.compilationThreadCount = std::clamp(advanced["Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency()));
if (advanced["Background Compiler Threads"].is_number_integer())
shaderCache.backgroundCompilationThreadCount = std::clamp(advanced["Background Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency()));
if (advanced["Use FileWatcher"].is_boolean())
shaderCache.SetFileWatcher(advanced["Use FileWatcher"]);
if (advanced["Extended Frame Annotations"].is_boolean())
extendedFrameAnnotations = advanced["Extended Frame Annotations"];
}
try {
// Load Menu settings

JSON_LOAD("Menu", settings["Menu"].is_object(), settings["Menu"], logger::info("Loading Menu settings"); Menu::GetSingleton()->Load(settings["Menu"]));

// Load Advanced settings
if (settings["Advanced"].is_object()) {
json& advanced = settings["Advanced"];
logger::info("Loading Advanced settings");
JSON_LOAD("Dump Shaders", advanced["Dump Shaders"].is_boolean(), advanced["Dump Shaders"], shaderCache.SetDump(advanced["Dump Shaders"]));
JSON_LOAD("Log Level", advanced["Log Level"].is_number_integer(), advanced["Log Level"], logLevel = static_cast<spdlog::level::level_enum>((int)advanced["Log Level"]));
JSON_LOAD("Shader Defines", advanced["Shader Defines"].is_string(), advanced["Shader Defines"], SetDefines(advanced["Shader Defines"]));
JSON_LOAD("Compiler Threads", advanced["Compiler Threads"].is_number_integer(), advanced["Compiler Threads"],
shaderCache.compilationThreadCount = std::clamp(advanced["Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency())));
JSON_LOAD("Background Compiler Threads", advanced["Background Compiler Threads"].is_number_integer(), advanced["Background Compiler Threads"],
shaderCache.backgroundCompilationThreadCount = std::clamp(advanced["Background Compiler Threads"].get<int32_t>(), 1, static_cast<int32_t>(std::thread::hardware_concurrency())));
JSON_LOAD("Use FileWatcher", advanced["Use FileWatcher"].is_boolean(), advanced["Use FileWatcher"], shaderCache.SetFileWatcher(advanced["Use FileWatcher"]));
JSON_LOAD("Extended Frame Annotations", advanced["Extended Frame Annotations"].is_boolean(), advanced["Extended Frame Annotations"], extendedFrameAnnotations = advanced["Extended Frame Annotations"]);
}

if (settings["General"].is_object()) {
json& general = settings["General"];
// Load General settings
if (settings["General"].is_object()) {
json& general = settings["General"];
logger::info("Loading General settings");
JSON_LOAD("Enable Shaders", general["Enable Shaders"].is_boolean(), general["Enable Shaders"], shaderCache.SetEnabled(general["Enable Shaders"]));
JSON_LOAD("Enable Disk Cache", general["Enable Disk Cache"].is_boolean(), general["Enable Disk Cache"], shaderCache.SetDiskCache(general["Enable Disk Cache"]));
JSON_LOAD("Enable Async", general["Enable Async"].is_boolean(), general["Enable Async"], shaderCache.SetAsync(general["Enable Async"]));
}

if (general["Enable Shaders"].is_boolean())
shaderCache.SetEnabled(general["Enable Shaders"]);
// Load Replace Original Shaders settings
if (settings["Replace Original Shaders"].is_object()) {
json& originalShaders = settings["Replace Original Shaders"];
logger::info("Loading Replace Original Shaders settings");
for (int classIndex = 0; classIndex < RE::BSShader::Type::Total - 1; ++classIndex) {
auto name = magic_enum::enum_name((RE::BSShader::Type)(classIndex + 1));
JSON_LOAD(name, originalShaders[name].is_boolean(), originalShaders[name], enabledClasses[classIndex] = originalShaders[name]);
}
}

if (general["Enable Disk Cache"].is_boolean())
shaderCache.SetDiskCache(general["Enable Disk Cache"]);
// Ensure 'Disable at Boot' section exists in the JSON
if (!settings.contains("Disable at Boot") || !settings["Disable at Boot"].is_object()) {
settings["Disable at Boot"] = json::object(); // Initialize to an empty object if it doesn't exist
}

if (general["Enable Async"].is_boolean())
shaderCache.SetAsync(general["Enable Async"]);
}
json& disabledFeaturesJson = settings["Disable at Boot"];
logger::info("Loading 'Disable at Boot' settings");

if (settings["Replace Original Shaders"].is_object()) {
json& originalShaders = settings["Replace Original Shaders"];
for (int classIndex = 0; classIndex < RE::BSShader::Type::Total - 1; ++classIndex) {
auto name = magic_enum::enum_name((RE::BSShader::Type)(classIndex + 1));
if (originalShaders[name].is_boolean()) {
enabledClasses[classIndex] = originalShaders[name];
} else {
logger::warn("Invalid entry for shader class '{}', using default", name);
}
for (auto& [featureName, featureStatus] : disabledFeaturesJson.items()) {
JSON_LOAD(featureName, featureStatus.is_boolean(), featureStatus, disabledFeatures[featureName] = featureStatus.get<bool>());
}
}
// Ensure 'Disable at Boot' section exists in the JSON
if (!settings.contains("Disable at Boot") || !settings["Disable at Boot"].is_object()) {
// Initialize to an empty object if it doesn't exist
settings["Disable at Boot"] = json::object();
}

json& disabledFeaturesJson = settings["Disable at Boot"];
for (const auto& [featureName, _] : specialFeatures) {
if (IsFeatureDisabled(featureName)) {
logger::info("Special Feature '{}' disabled at boot", featureName);
}
}

for (auto& [featureName, featureStatus] : disabledFeaturesJson.items()) {
if (featureStatus.is_boolean()) {
disabledFeatures[featureName] = featureStatus.get<bool>();
// Load TruePBR settings
auto truePBR = TruePBR::GetSingleton();
auto& pbrJson = settings[truePBR->GetShortName()];
if (pbrJson.is_object()) {
try {
logger::info("Loading TruePBR settings");
truePBR->LoadSettings(pbrJson);
} catch (const json::exception& e) {
logger::warn("JSON error loading TruePBR settings: {}. JSON section: {}", e.what(), pbrJson.dump());
} catch (const std::exception& e) {
logger::warn("General error loading TruePBR settings: {}", e.what());
}
} else {
logger::warn("Invalid entry for feature '{}' in 'Disable at Boot', expected boolean.", featureName);
}
}
for (const auto& [featureName, _] : specialFeatures) {
if (IsFeatureDisabled(featureName)) {
logger::info("Special Feature '{}' disabled at boot", featureName);
logger::warn("Missing settings for TruePBR, using default.");
}
}

auto truePBR = TruePBR::GetSingleton();
auto& pbrJson = settings[truePBR->GetShortName()];
if (pbrJson.is_object()) {
truePBR->LoadSettings(pbrJson);
} else {
logger::warn("Missing settings for TruePBR, using default.");
}

auto upscaling = Upscaling::GetSingleton();
auto& upscalingJson = settings[upscaling->GetShortName()];
if (upscalingJson.is_object()) {
upscaling->LoadSettings(upscalingJson);
} else {
logger::warn("Missing settings for Upscaling, using default.");
}
// Load Upscaling settings
auto upscaling = Upscaling::GetSingleton();
auto& upscalingJson = settings[upscaling->GetShortName()];
if (upscalingJson.is_object()) {
try {
logger::info("Loading Upscaling settings");
upscaling->LoadSettings(upscalingJson);
} catch (const json::exception& e) {
logger::warn("JSON error loading Upscaling settings: {}. JSON section: {}", e.what(), upscalingJson.dump());
} catch (const std::exception& e) {
logger::warn("General error loading Upscaling settings: {}", e.what());
}
} else {
logger::warn("Missing settings for Upscaling, using default.");
}

for (auto* feature : Feature::GetFeatureList()) {
try {
const std::string featureName = feature->GetShortName();
bool isDisabled = disabledFeatures.contains(featureName) && disabledFeatures[featureName];
if (!isDisabled) {
feature->Load(settings);
} else {
logger::info("Feature '{}' is disabled at boot.", featureName);
for (auto* feature : Feature::GetFeatureList()) {
try {
const std::string featureName = feature->GetShortName();
bool isDisabled = disabledFeatures.contains(featureName) && disabledFeatures[featureName];
if (!isDisabled) {
logger::info("Loading Feature: '{}'", featureName);
feature->Load(settings);
} else {
logger::info("Feature '{}' is disabled at boot.", featureName);
}
} catch (const std::exception& e) {
feature->failedLoadedMessage = std::format(
"{}{} failed to load. Check CommunityShaders.log",
feature->failedLoadedMessage.empty() ? "" : feature->failedLoadedMessage + "\n",
feature->GetName());
logger::warn("Error loading setting for feature '{}': {}", feature->GetShortName(), e.what());
}
} catch (const std::exception& e) {
feature->failedLoadedMessage = std::format(
"{}{} failed to load. Check CommunityShaders.log",
feature->failedLoadedMessage.empty() ? "" : feature->failedLoadedMessage + "\n",
feature->GetName());
logger::warn("Error loading setting for feature '{}': {}", feature->GetShortName(), e.what());
}
}
if (settings["Version"].is_string() && settings["Version"].get<std::string>() != Plugin::VERSION.string()) {
logger::info("Found older config for version {}; upgrading to {}", (std::string)settings["Version"], Plugin::VERSION.string());
Save(configMode);
if (settings["Version"].is_string() && settings["Version"].get<std::string>() != Plugin::VERSION.string()) {
logger::info("Found older config for version {}; upgrading to {}", (std::string)settings["Version"], Plugin::VERSION.string());
Save(configMode);
}
logger::info("Loading Settings Complete");
} catch (const json::exception& e) {
logger::info("General JSON error accessing settings: {}; recreating config", e.what());
Save(a_configMode);
if (a_allowReload)
Load(a_configMode, false);
} catch (const std::exception& e) {
logger::info("General error accessing settings: {}; recreating config", e.what());
Save(a_configMode);
if (a_allowReload)
Load(a_configMode, false);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/State.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class State
void Reset();
void Setup();

void Load(ConfigMode a_configMode = ConfigMode::USER);
void Load(ConfigMode a_configMode = ConfigMode::USER, bool a_allowReload = true);
void Save(ConfigMode a_configMode = ConfigMode::USER);
void PostPostLoad();

Expand Down

0 comments on commit 6ee1730

Please sign in to comment.