VideoCommon: add ability to serialize graphics mod to json object

This commit is contained in:
iwubcode 2023-11-11 16:48:18 -06:00
parent 003872d7dd
commit 3658d3bffe
11 changed files with 129 additions and 7 deletions

View File

@ -112,6 +112,42 @@ std::string GraphicsModConfig::GetAbsolutePath() const
} }
} }
void GraphicsModConfig::SerializeToConfig(picojson::object& json_obj) const
{
picojson::object serialized_metadata;
serialized_metadata["title"] = picojson::value{m_title};
serialized_metadata["author"] = picojson::value{m_author};
serialized_metadata["description"] = picojson::value{m_description};
json_obj["meta"] = picojson::value{serialized_metadata};
picojson::array serialized_groups;
for (const auto& group : m_groups)
{
picojson::object serialized_group;
group.SerializeToConfig(serialized_group);
serialized_groups.push_back(picojson::value{serialized_group});
}
json_obj["groups"] = picojson::value{serialized_groups};
picojson::array serialized_features;
for (const auto& feature : m_features)
{
picojson::object serialized_feature;
feature.SerializeToConfig(serialized_feature);
serialized_features.push_back(picojson::value{serialized_feature});
}
json_obj["features"] = picojson::value{serialized_features};
picojson::array serialized_assets;
for (const auto& asset : m_assets)
{
picojson::object serialized_asset;
asset.SerializeToConfig(serialized_asset);
serialized_assets.push_back(picojson::value{serialized_asset});
}
json_obj["assets"] = picojson::value{serialized_assets};
}
bool GraphicsModConfig::DeserializeFromConfig(const picojson::value& value) bool GraphicsModConfig::DeserializeFromConfig(const picojson::value& value)
{ {
const auto& meta = value.get("meta"); const auto& meta = value.get("meta");

View File

@ -38,6 +38,7 @@ struct GraphicsModConfig
std::string GetAbsolutePath() const; std::string GetAbsolutePath() const;
void SerializeToConfig(picojson::object& json_obj) const;
bool DeserializeFromConfig(const picojson::value& value); bool DeserializeFromConfig(const picojson::value& value);
void SerializeToProfile(picojson::object* value) const; void SerializeToProfile(picojson::object* value) const;

View File

@ -4,6 +4,19 @@
#include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h" #include "VideoCommon/GraphicsModSystem/Config/GraphicsModAsset.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
void GraphicsModAssetConfig::SerializeToConfig(picojson::object& json_obj) const
{
json_obj["name"] = picojson::value{m_asset_id};
picojson::object serialized_data;
for (const auto& [name, path] : m_map)
{
serialized_data[name] = picojson::value{PathToString(path)};
}
json_obj["data"] = picojson::value{serialized_data};
}
bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj) bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj)
{ {
@ -19,13 +32,13 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj)
"that is not a string"); "that is not a string");
return false; return false;
} }
m_name = name_iter->second.to_str(); m_asset_id = name_iter->second.to_str();
auto data_iter = obj.find("data"); auto data_iter = obj.find("data");
if (data_iter == obj.end()) if (data_iter == obj.end())
{ {
ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has no data", ERROR_LOG_FMT(VIDEO, "Failed to load mod configuration file, specified asset '{}' has no data",
m_name); m_asset_id);
return false; return false;
} }
if (!data_iter->second.is<picojson::object>()) if (!data_iter->second.is<picojson::object>())
@ -33,7 +46,7 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj)
ERROR_LOG_FMT(VIDEO, ERROR_LOG_FMT(VIDEO,
"Failed to load mod configuration file, specified asset '{}' has data " "Failed to load mod configuration file, specified asset '{}' has data "
"that is not an object", "that is not an object",
m_name); m_asset_id);
return false; return false;
} }
for (const auto& [key, value] : data_iter->second.get<picojson::object>()) for (const auto& [key, value] : data_iter->second.get<picojson::object>())
@ -43,7 +56,7 @@ bool GraphicsModAssetConfig::DeserializeFromConfig(const picojson::object& obj)
ERROR_LOG_FMT(VIDEO, ERROR_LOG_FMT(VIDEO,
"Failed to load mod configuration file, specified asset '{}' has data " "Failed to load mod configuration file, specified asset '{}' has data "
"with a value for key '{}' that is not a string", "with a value for key '{}' that is not a string",
m_name, key); m_asset_id, key);
return false; return false;
} }
m_map[key] = value.to_str(); m_map[key] = value.to_str();

View File

@ -11,8 +11,9 @@
struct GraphicsModAssetConfig struct GraphicsModAssetConfig
{ {
std::string m_name; VideoCommon::CustomAssetLibrary::AssetID m_asset_id;
VideoCommon::DirectFilesystemAssetLibrary::AssetMap m_map; VideoCommon::DirectFilesystemAssetLibrary::AssetMap m_map;
void SerializeToConfig(picojson::object& json_obj) const;
bool DeserializeFromConfig(const picojson::object& obj); bool DeserializeFromConfig(const picojson::object& obj);
}; };

View File

@ -5,6 +5,13 @@
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
void GraphicsModFeatureConfig::SerializeToConfig(picojson::object& json_obj) const
{
json_obj["group"] = picojson::value{m_group};
json_obj["action"] = picojson::value{m_action};
json_obj["action_data"] = m_action_data;
}
bool GraphicsModFeatureConfig::DeserializeFromConfig(const picojson::object& obj) bool GraphicsModFeatureConfig::DeserializeFromConfig(const picojson::object& obj)
{ {
if (auto group_iter = obj.find("group"); group_iter != obj.end()) if (auto group_iter = obj.find("group"); group_iter != obj.end())

View File

@ -13,6 +13,7 @@ struct GraphicsModFeatureConfig
std::string m_action; std::string m_action;
picojson::value m_action_data; picojson::value m_action_data;
void SerializeToConfig(picojson::object& json_obj) const;
bool DeserializeFromConfig(const picojson::object& value); bool DeserializeFromConfig(const picojson::object& value);
void SerializeToProfile(picojson::object* value) const; void SerializeToProfile(picojson::object* value) const;

View File

@ -5,6 +5,7 @@
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Common/VariantUtil.h"
#include "VideoCommon/TextureCacheBase.h" #include "VideoCommon/TextureCacheBase.h"
namespace namespace
@ -152,6 +153,53 @@ std::optional<std::string> ExtractTextureFilenameForConfig(const picojson::objec
} }
} // namespace } // namespace
void SerializeTargetToConfig(picojson::object& json_obj, const GraphicsTargetConfig& target)
{
std::visit(
overloaded{
[&](const DrawStartedTextureTarget& the_target) {
json_obj["type"] = picojson::value{"draw_started"};
json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string};
},
[&](const LoadTextureTarget& the_target) {
json_obj["type"] = picojson::value{"load_texture"};
json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string};
},
[&](const CreateTextureTarget& the_target) {
json_obj["type"] = picojson::value{"create_texture"};
json_obj["texture_filename"] = picojson::value{the_target.m_texture_info_string};
},
[&](const EFBTarget& the_target) {
json_obj["type"] = picojson::value{"efb"};
json_obj["texture_filename"] = picojson::value{
fmt::format("{}_{}x{}_{}", EFB_DUMP_PREFIX, the_target.m_width, the_target.m_height,
static_cast<int>(the_target.m_texture_format))};
},
[&](const XFBTarget& the_target) {
json_obj["type"] = picojson::value{"xfb"};
json_obj["texture_filename"] = picojson::value{
fmt::format("{}_{}x{}_{}", XFB_DUMP_PREFIX, the_target.m_width, the_target.m_height,
static_cast<int>(the_target.m_texture_format))};
},
[&](const ProjectionTarget& the_target) {
json_obj["type"] = picojson::value{"projection"};
if (the_target.m_projection_type == ProjectionType::Orthographic)
{
json_obj["type"] = picojson::value{"2d"};
}
else
{
json_obj["type"] = picojson::value{"3d"};
}
if (the_target.m_texture_info_string)
{
json_obj["texture_filename"] = picojson::value{*the_target.m_texture_info_string};
}
},
},
target);
}
std::optional<GraphicsTargetConfig> DeserializeTargetFromConfig(const picojson::object& obj) std::optional<GraphicsTargetConfig> DeserializeTargetFromConfig(const picojson::object& obj)
{ {
const auto type_iter = obj.find("type"); const auto type_iter = obj.find("type");

View File

@ -55,6 +55,7 @@ using GraphicsTargetConfig =
std::variant<DrawStartedTextureTarget, LoadTextureTarget, CreateTextureTarget, EFBTarget, std::variant<DrawStartedTextureTarget, LoadTextureTarget, CreateTextureTarget, EFBTarget,
XFBTarget, ProjectionTarget>; XFBTarget, ProjectionTarget>;
void SerializeTargetToConfig(picojson::object& json_obj, const GraphicsTargetConfig& target);
std::optional<GraphicsTargetConfig> DeserializeTargetFromConfig(const picojson::object& obj); std::optional<GraphicsTargetConfig> DeserializeTargetFromConfig(const picojson::object& obj);
void SerializeTargetToProfile(picojson::object* obj, const GraphicsTargetConfig& target); void SerializeTargetToProfile(picojson::object* obj, const GraphicsTargetConfig& target);

View File

@ -5,6 +5,19 @@
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
void GraphicsTargetGroupConfig::SerializeToConfig(picojson::object& json_obj) const
{
picojson::array serialized_targets;
for (const auto& target : m_targets)
{
picojson::object serialized_target;
SerializeTargetToConfig(serialized_target, target);
serialized_targets.push_back(picojson::value{serialized_target});
}
json_obj["targets"] = picojson::value{serialized_targets};
json_obj["name"] = picojson::value{m_name};
}
bool GraphicsTargetGroupConfig::DeserializeFromConfig(const picojson::object& obj) bool GraphicsTargetGroupConfig::DeserializeFromConfig(const picojson::object& obj)
{ {
if (auto name_iter = obj.find("name"); name_iter != obj.end()) if (auto name_iter = obj.find("name"); name_iter != obj.end())

View File

@ -15,6 +15,7 @@ struct GraphicsTargetGroupConfig
std::string m_name; std::string m_name;
std::vector<GraphicsTargetConfig> m_targets; std::vector<GraphicsTargetConfig> m_targets;
void SerializeToConfig(picojson::object& json_obj) const;
bool DeserializeFromConfig(const picojson::object& obj); bool DeserializeFromConfig(const picojson::object& obj);
void SerializeToProfile(picojson::object* obj) const; void SerializeToProfile(picojson::object* obj) const;

View File

@ -225,7 +225,7 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
WARN_LOG_FMT(VIDEO, WARN_LOG_FMT(VIDEO,
"Specified graphics mod asset '{}' for mod '{}' has an absolute path, you " "Specified graphics mod asset '{}' for mod '{}' has an absolute path, you "
"shouldn't release this to users.", "shouldn't release this to users.",
asset.m_name, mod.m_title); asset.m_asset_id, mod.m_title);
} }
else else
{ {
@ -233,7 +233,7 @@ void GraphicsModManager::Load(const GraphicsModGroupConfig& config)
} }
} }
filesystem_library->SetAssetIDMapData(asset.m_name, std::move(asset_map)); filesystem_library->SetAssetIDMapData(asset.m_asset_id, std::move(asset_map));
} }
} }