Common: Add additional ryml helpers
Some checks failed
Automated Builds / 💻 Windows (push) Waiting to run
Automated Builds / 🐧 Linux AppImage (push) Waiting to run
Automated Builds / 🐧 Linux Cross-Compiled AppImage (push) Waiting to run
Automated Builds / 🍎 MacOS (push) Waiting to run
Automated Builds / 📤 Create Release (push) Blocked by required conditions
Translation Lint / translation-lint (push) Has been cancelled

This commit is contained in:
Stenzek 2025-12-21 16:14:20 +10:00
parent d7c015aefb
commit 2935a3d71b
No known key found for this signature in database
4 changed files with 67 additions and 13 deletions

View File

@ -2,10 +2,11 @@
// SPDX-License-Identifier: CC-BY-NC-ND-4.0 // SPDX-License-Identifier: CC-BY-NC-ND-4.0
#include "log.h" #include "log.h"
#include "small_string.h"
#include "string_util.h" #include "string_util.h"
#include "types.h" #include "types.h"
#include "common/small_string.h"
#include "ryml.hpp" #include "ryml.hpp"
#include <string> #include <string>
@ -56,8 +57,34 @@ inline bool GetStringFromObject(const ryml::ConstNodeRef& object, std::string_vi
return true; return true;
} }
inline bool GetBoolFromObject(const ryml::ConstNodeRef& object, std::string_view key, bool* dest)
{
*dest = 0;
const ryml::ConstNodeRef member = object.find_child(to_csubstr(key));
if (!member.valid())
return false;
const c4::csubstr val = member.val();
if (val.empty())
{
GENERIC_LOG(Log::Channel::Log, Log::Level::Error, Log::Color::StrongOrange, "Unexpected empty value in {}", key);
return false;
}
const std::optional<bool> opt_value = StringUtil::FromChars<bool>(to_stringview(val));
if (!opt_value.has_value())
{
GENERIC_LOG(Log::Channel::Log, Log::Level::Error, Log::Color::StrongOrange, "Unexpected non-bool value in {}", key);
return false;
}
*dest = opt_value.value();
return true;
}
template<typename T> template<typename T>
inline bool GetUIntFromObject(const ryml::ConstNodeRef& object, std::string_view key, T* dest) inline bool GetIntFromObject(const ryml::ConstNodeRef& object, std::string_view key, T* dest)
{ {
*dest = 0; *dest = 0;
@ -83,6 +110,33 @@ inline bool GetUIntFromObject(const ryml::ConstNodeRef& object, std::string_view
return true; return true;
} }
static inline bool GetFloatFromObject(const ryml::ConstNodeRef& object, std::string_view key, float* dest)
{
*dest = 0;
const ryml::ConstNodeRef member = object.find_child(to_csubstr(key));
if (!member.valid())
return false;
const c4::csubstr val = member.val();
if (val.empty())
{
GENERIC_LOG(Log::Channel::Log, Log::Level::Error, Log::Color::StrongOrange, "Unexpected empty value in {}", key);
return false;
}
const std::optional<float> opt_value = StringUtil::FromChars<float>(to_stringview(val));
if (!opt_value.has_value())
{
GENERIC_LOG(Log::Channel::Log, Log::Level::Error, Log::Color::StrongOrange, "Unexpected non-float value in {}",
key);
return false;
}
*dest = opt_value.value();
return true;
}
template<typename T> template<typename T>
inline std::optional<T> GetOptionalTFromObject(const ryml::ConstNodeRef& object, std::string_view key) inline std::optional<T> GetOptionalTFromObject(const ryml::ConstNodeRef& object, std::string_view key)
{ {

View File

@ -1467,10 +1467,10 @@ bool GameDatabase::ParseYamlEntry(Entry* entry, const ryml::ConstNodeRef& value)
GetStringFromObject(metadata, "developer", &entry->developer); GetStringFromObject(metadata, "developer", &entry->developer);
GetStringFromObject(metadata, "publisher", &entry->publisher); GetStringFromObject(metadata, "publisher", &entry->publisher);
GetUIntFromObject(metadata, "minPlayers", &entry->min_players); GetIntFromObject(metadata, "minPlayers", &entry->min_players);
GetUIntFromObject(metadata, "maxPlayers", &entry->max_players); GetIntFromObject(metadata, "maxPlayers", &entry->max_players);
GetUIntFromObject(metadata, "minBlocks", &entry->min_blocks); GetIntFromObject(metadata, "minBlocks", &entry->min_blocks);
GetUIntFromObject(metadata, "maxBlocks", &entry->max_blocks); GetIntFromObject(metadata, "maxBlocks", &entry->max_blocks);
if (const ryml::ConstNodeRef languages = metadata.find_child(to_csubstr("languages")); languages.valid()) if (const ryml::ConstNodeRef languages = metadata.find_child(to_csubstr("languages")); languages.valid())
{ {

View File

@ -1670,12 +1670,12 @@ bool GPUPresenter::LoadOverlayPreset(Error* error, Image* image)
bool alpha_blend = false; bool alpha_blend = false;
bool destination_alpha_blend = false; bool destination_alpha_blend = false;
if (!GetStringFromObject(root, "image", &image_filename) || if (!GetStringFromObject(root, "image", &image_filename) ||
!GetUIntFromObject(root, "displayStartX", &display_area.x) || !GetIntFromObject(root, "displayStartX", &display_area.x) ||
!GetUIntFromObject(root, "displayStartY", &display_area.y) || !GetIntFromObject(root, "displayStartY", &display_area.y) ||
!GetUIntFromObject(root, "displayEndX", &display_area.z) || !GetIntFromObject(root, "displayEndX", &display_area.z) ||
!GetUIntFromObject(root, "displayEndY", &display_area.w) || !GetIntFromObject(root, "displayEndY", &display_area.w) ||
!GetUIntFromObject(root, "alphaBlend", &alpha_blend) || !GetIntFromObject(root, "alphaBlend", &alpha_blend) ||
!GetUIntFromObject(root, "destinationAlphaBlend", &destination_alpha_blend)) !GetIntFromObject(root, "destinationAlphaBlend", &destination_alpha_blend))
{ {
Error::SetStringView(error, "One or more parameters is missing."); Error::SetStringView(error, "One or more parameters is missing.");
return false; return false;

View File

@ -522,7 +522,7 @@ bool MemoryWatchList::LoadFromFile(const char* path, Error* error)
std::optional<u32> parsed_address; std::optional<u32> parsed_address;
if (!GetStringFromObject(child, "description", &entry.description) || if (!GetStringFromObject(child, "description", &entry.description) ||
!GetStringFromObject(child, "address", &address) || !GetStringFromObject(child, "size", &size) || !GetStringFromObject(child, "address", &address) || !GetStringFromObject(child, "size", &size) ||
!GetUIntFromObject(child, "isSigned", &entry.is_signed) || !GetUIntFromObject(child, "freeze", &entry.freeze) || !GetIntFromObject(child, "isSigned", &entry.is_signed) || !GetIntFromObject(child, "freeze", &entry.freeze) ||
!(parsed_address = StringUtil::FromCharsWithOptionalBase<u32>(address)).has_value() || !(parsed_address = StringUtil::FromCharsWithOptionalBase<u32>(address)).has_value() ||
(size != "byte" && size != "halfword" && size != "word")) (size != "byte" && size != "halfword" && size != "word"))
{ {