Add a dedicated library for working with JSON (#2047)
This commit is contained in:
parent
bed58cf8b9
commit
bf1b9a20ec
16 changed files with 154 additions and 92 deletions
4
.gitmodules
vendored
4
.gitmodules
vendored
|
|
@ -42,3 +42,7 @@
|
||||||
path = third-party/build-deps
|
path = third-party/build-deps
|
||||||
url = https://github.com/LizardByte/build-deps.git
|
url = https://github.com/LizardByte/build-deps.git
|
||||||
branch = dist
|
branch = dist
|
||||||
|
[submodule "third-party/nlohmann_json"]
|
||||||
|
path = third-party/nlohmann_json
|
||||||
|
url = https://github.com/nlohmann/json
|
||||||
|
branch = master
|
||||||
|
|
|
||||||
|
|
@ -126,4 +126,5 @@ list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
|
||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OPENSSL_LIBRARIES}
|
${OPENSSL_LIBRARIES}
|
||||||
${CURL_LIBRARIES}
|
${CURL_LIBRARIES}
|
||||||
${PLATFORM_LIBRARIES})
|
${PLATFORM_LIBRARIES}
|
||||||
|
nlohmann_json::nlohmann_json)
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,9 @@ pkg_check_modules(CURL REQUIRED libcurl)
|
||||||
pkg_check_modules(MINIUPNP miniupnpc REQUIRED)
|
pkg_check_modules(MINIUPNP miniupnpc REQUIRED)
|
||||||
include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})
|
include_directories(SYSTEM ${MINIUPNP_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
# nlohmann_json
|
||||||
|
add_subdirectory(third-party/nlohmann_json)
|
||||||
|
|
||||||
# ffmpeg pre-compiled binaries
|
# ffmpeg pre-compiled binaries
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
if(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "AMD64")
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,4 @@
|
||||||
# windows specific dependencies
|
# windows specific dependencies
|
||||||
|
|
||||||
set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103
|
set(Boost_USE_STATIC_LIBS ON) # cmake-lint: disable=C0103
|
||||||
# Boost >= 1.82.0 is required for boost::json::value::set_at_pointer() support
|
find_package(Boost 1.71.0 COMPONENTS locale log filesystem program_options REQUIRED)
|
||||||
# todo - are we actually using json? I think this was attempted to be used in a PR, but we ended up not using json
|
|
||||||
find_package(Boost 1.82.0 COMPONENTS locale log filesystem program_options json REQUIRED)
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#include "nvprefs_common.h"
|
// local includes
|
||||||
|
|
||||||
#include "driver_settings.h"
|
#include "driver_settings.h"
|
||||||
|
#include "nvprefs_common.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
@ -94,9 +94,8 @@ namespace nvprefs {
|
||||||
driver_settings_t::restore_global_profile_to_undo(const undo_data_t &undo_data) {
|
driver_settings_t::restore_global_profile_to_undo(const undo_data_t &undo_data) {
|
||||||
if (!session_handle) return false;
|
if (!session_handle) return false;
|
||||||
|
|
||||||
auto [opengl_swapchain_saved, opengl_swapchain_our_value, opengl_swapchain_undo_value] = undo_data.get_opengl_swapchain();
|
const auto &swapchain_data = undo_data.get_opengl_swapchain();
|
||||||
|
if (swapchain_data) {
|
||||||
if (opengl_swapchain_saved) {
|
|
||||||
NvAPI_Status status;
|
NvAPI_Status status;
|
||||||
|
|
||||||
NvDRSProfileHandle profile_handle = 0;
|
NvDRSProfileHandle profile_handle = 0;
|
||||||
|
|
@ -111,14 +110,14 @@ namespace nvprefs {
|
||||||
setting.version = NVDRS_SETTING_VER;
|
setting.version = NVDRS_SETTING_VER;
|
||||||
status = NvAPI_DRS_GetSetting(session_handle, profile_handle, OGL_CPL_PREFER_DXPRESENT_ID, &setting);
|
status = NvAPI_DRS_GetSetting(session_handle, profile_handle, OGL_CPL_PREFER_DXPRESENT_ID, &setting);
|
||||||
|
|
||||||
if (status == NVAPI_OK && setting.settingLocation == NVDRS_CURRENT_PROFILE_LOCATION && setting.u32CurrentValue == opengl_swapchain_our_value) {
|
if (status == NVAPI_OK && setting.settingLocation == NVDRS_CURRENT_PROFILE_LOCATION && setting.u32CurrentValue == swapchain_data->our_value) {
|
||||||
if (opengl_swapchain_undo_value) {
|
if (swapchain_data->undo_value) {
|
||||||
setting = {};
|
setting = {};
|
||||||
setting.version = NVDRS_SETTING_VER1;
|
setting.version = NVDRS_SETTING_VER1;
|
||||||
setting.settingId = OGL_CPL_PREFER_DXPRESENT_ID;
|
setting.settingId = OGL_CPL_PREFER_DXPRESENT_ID;
|
||||||
setting.settingType = NVDRS_DWORD_TYPE;
|
setting.settingType = NVDRS_DWORD_TYPE;
|
||||||
setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION;
|
setting.settingLocation = NVDRS_CURRENT_PROFILE_LOCATION;
|
||||||
setting.u32CurrentValue = *opengl_swapchain_undo_value;
|
setting.u32CurrentValue = *swapchain_data->undo_value;
|
||||||
|
|
||||||
status = NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting);
|
status = NvAPI_DRS_SetSetting(session_handle, profile_handle, &setting);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// nvapi headers
|
||||||
|
// disable clang-format header reordering
|
||||||
|
// as <NvApiDriverSettings.h> needs types from <nvapi.h>
|
||||||
|
// clang-format off
|
||||||
|
#include <nvapi.h>
|
||||||
|
#include <NvApiDriverSettings.h>
|
||||||
|
// clang-format on
|
||||||
|
|
||||||
|
// local includes
|
||||||
#include "undo_data.h"
|
#include "undo_data.h"
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,11 @@
|
||||||
|
// standard library headers
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "driver_settings.h"
|
||||||
#include "nvprefs_common.h"
|
#include "nvprefs_common.h"
|
||||||
|
|
||||||
|
// special nvapi header that should be the last include
|
||||||
#include <nvapi_interface.h>
|
#include <nvapi_interface.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
|
// local includes
|
||||||
#include "nvprefs_common.h"
|
#include "nvprefs_common.h"
|
||||||
|
#include "src/main.h" // sunshine boost::log severity levels
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,6 @@
|
||||||
// sunshine utility header for generic smart pointers
|
// sunshine utility header for generic smart pointers
|
||||||
#include "src/utility.h"
|
#include "src/utility.h"
|
||||||
|
|
||||||
// sunshine boost::log severity levels
|
|
||||||
#include "src/main.h"
|
|
||||||
|
|
||||||
// standard library headers
|
|
||||||
#include <filesystem>
|
|
||||||
#include <iostream>
|
|
||||||
#include <map>
|
|
||||||
#include <memory>
|
|
||||||
#include <optional>
|
|
||||||
#include <string>
|
|
||||||
#include <type_traits>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// winapi headers
|
// winapi headers
|
||||||
// disable clang-format header reordering
|
// disable clang-format header reordering
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
@ -23,21 +10,12 @@
|
||||||
#include <aclapi.h>
|
#include <aclapi.h>
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// nvapi headers
|
|
||||||
// disable clang-format header reordering
|
|
||||||
// clang-format off
|
|
||||||
#include <nvapi.h>
|
|
||||||
#include <NvApiDriverSettings.h>
|
|
||||||
// clang-format on
|
|
||||||
|
|
||||||
// boost headers
|
|
||||||
#include <boost/json.hpp>
|
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
||||||
struct safe_handle: public util::safe_ptr_v2<void, BOOL, CloseHandle> {
|
struct safe_handle: public util::safe_ptr_v2<void, BOOL, CloseHandle> {
|
||||||
using util::safe_ptr_v2<void, BOOL, CloseHandle>::safe_ptr_v2;
|
using util::safe_ptr_v2<void, BOOL, CloseHandle>::safe_ptr_v2;
|
||||||
explicit operator bool() const {
|
explicit
|
||||||
|
operator bool() const {
|
||||||
auto handle = get();
|
auto handle = get();
|
||||||
return handle != NULL && handle != INVALID_HANDLE_VALUE;
|
return handle != NULL && handle != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,7 @@
|
||||||
#include "nvprefs_common.h"
|
// local includes
|
||||||
|
|
||||||
#include "nvprefs_interface.h"
|
#include "nvprefs_interface.h"
|
||||||
|
|
||||||
#include "driver_settings.h"
|
#include "driver_settings.h"
|
||||||
#include "undo_data.h"
|
#include "src/main.h" // main include for assert
|
||||||
#include "undo_file.h"
|
#include "undo_file.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// standard library headers
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
||||||
class nvprefs_interface {
|
class nvprefs_interface {
|
||||||
|
|
|
||||||
|
|
@ -1,70 +1,117 @@
|
||||||
#include "nvprefs_common.h"
|
// external includes
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "nvprefs_common.h"
|
||||||
#include "undo_data.h"
|
#include "undo_data.h"
|
||||||
|
|
||||||
namespace {
|
using json = nlohmann::json;
|
||||||
|
|
||||||
const auto opengl_swapchain_our_value_key = "/opengl_swapchain/our_value";
|
// Separate namespace for ADL, otherwise we need to define json
|
||||||
const auto opengl_swapchain_undo_value_key = "/opengl_swapchain/undo_value";
|
// functions in the same namespace as our types
|
||||||
|
namespace nlohmann {
|
||||||
|
using data_t = nvprefs::undo_data_t::data_t;
|
||||||
|
using opengl_swapchain_t = data_t::opengl_swapchain_t;
|
||||||
|
|
||||||
} // namespace
|
template <typename T>
|
||||||
|
struct adl_serializer<std::optional<T>> {
|
||||||
|
static void
|
||||||
|
to_json(json &j, const std::optional<T> &opt) {
|
||||||
|
if (opt == std::nullopt) {
|
||||||
|
j = nullptr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
j = *opt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
from_json(const json &j, std::optional<T> &opt) {
|
||||||
|
if (j.is_null()) {
|
||||||
|
opt = std::nullopt;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opt = j.template get<T>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct adl_serializer<data_t> {
|
||||||
|
static void
|
||||||
|
to_json(json &j, const data_t &data) {
|
||||||
|
j = json { { "opengl_swapchain", data.opengl_swapchain } };
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
from_json(const json &j, data_t &data) {
|
||||||
|
j.at("opengl_swapchain").get_to(data.opengl_swapchain);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct adl_serializer<opengl_swapchain_t> {
|
||||||
|
static void
|
||||||
|
to_json(json &j, const opengl_swapchain_t &opengl_swapchain) {
|
||||||
|
j = json {
|
||||||
|
{ "our_value", opengl_swapchain.our_value },
|
||||||
|
{ "undo_value", opengl_swapchain.undo_value }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
from_json(const json &j, opengl_swapchain_t &opengl_swapchain) {
|
||||||
|
j.at("our_value").get_to(opengl_swapchain.our_value);
|
||||||
|
j.at("undo_value").get_to(opengl_swapchain.undo_value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace nlohmann
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
||||||
void
|
void
|
||||||
undo_data_t::set_opengl_swapchain(uint32_t our_value, std::optional<uint32_t> undo_value) {
|
undo_data_t::set_opengl_swapchain(uint32_t our_value, std::optional<uint32_t> undo_value) {
|
||||||
data.set_at_pointer(opengl_swapchain_our_value_key, our_value);
|
data.opengl_swapchain = data_t::opengl_swapchain_t {
|
||||||
if (undo_value) {
|
our_value,
|
||||||
data.set_at_pointer(opengl_swapchain_undo_value_key, *undo_value);
|
undo_value
|
||||||
}
|
};
|
||||||
else {
|
|
||||||
data.set_at_pointer(opengl_swapchain_undo_value_key, nullptr);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<bool, uint32_t, std::optional<uint32_t>>
|
std::optional<undo_data_t::data_t::opengl_swapchain_t>
|
||||||
undo_data_t::get_opengl_swapchain() const {
|
undo_data_t::get_opengl_swapchain() const {
|
||||||
auto get_value = [this](const auto &key) -> std::tuple<bool, std::optional<uint32_t>> {
|
return data.opengl_swapchain;
|
||||||
try {
|
|
||||||
auto value = data.at_pointer(key);
|
|
||||||
if (value.is_null()) {
|
|
||||||
return { true, std::nullopt };
|
|
||||||
}
|
|
||||||
else if (value.is_number()) {
|
|
||||||
return { true, value.template to_number<uint32_t>() };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (...) {
|
|
||||||
}
|
|
||||||
error_message(std::string("Couldn't find ") + key + " element");
|
|
||||||
return { false, std::nullopt };
|
|
||||||
};
|
|
||||||
|
|
||||||
auto [our_value_present, our_value] = get_value(opengl_swapchain_our_value_key);
|
|
||||||
auto [undo_value_present, undo_value] = get_value(opengl_swapchain_undo_value_key);
|
|
||||||
|
|
||||||
if (!our_value_present || !undo_value_present || !our_value) {
|
|
||||||
return { false, 0, std::nullopt };
|
|
||||||
}
|
|
||||||
|
|
||||||
return { true, *our_value, undo_value };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
undo_data_t::write() const {
|
undo_data_t::write() const {
|
||||||
return boost::json::serialize(data);
|
try {
|
||||||
|
// Keep this assignment otherwise data will be treated as an array due to
|
||||||
|
// initializer list shenanigangs.
|
||||||
|
const json json_data = data;
|
||||||
|
return json_data.dump();
|
||||||
|
}
|
||||||
|
catch (const std::exception &err) {
|
||||||
|
error_message(std::string { "failed to serialize json data" });
|
||||||
|
return {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
undo_data_t::read(const std::vector<char> &buffer) {
|
undo_data_t::read(const std::vector<char> &buffer) {
|
||||||
data = boost::json::parse(std::string_view(buffer.data(), buffer.size()));
|
try {
|
||||||
|
data = json::parse(std::begin(buffer), std::end(buffer));
|
||||||
|
}
|
||||||
|
catch (const std::exception &err) {
|
||||||
|
error_message(std::string { "failed to parse json data: " } + err.what());
|
||||||
|
data = {};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
undo_data_t::merge(const undo_data_t &newer_data) {
|
undo_data_t::merge(const undo_data_t &newer_data) {
|
||||||
auto [opengl_swapchain_saved, opengl_swapchain_our_value, opengl_swapchain_undo_value] = newer_data.get_opengl_swapchain();
|
const auto &swapchain_data = newer_data.get_opengl_swapchain();
|
||||||
if (opengl_swapchain_saved) {
|
if (swapchain_data) {
|
||||||
set_opengl_swapchain(opengl_swapchain_our_value, opengl_swapchain_undo_value);
|
set_opengl_swapchain(swapchain_data->our_value, swapchain_data->undo_value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,24 +1,33 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// standard library headers
|
||||||
|
#include <cstdint>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
||||||
class undo_data_t {
|
class undo_data_t {
|
||||||
public:
|
public:
|
||||||
|
struct data_t {
|
||||||
|
struct opengl_swapchain_t {
|
||||||
|
uint32_t our_value;
|
||||||
|
std::optional<uint32_t> undo_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::optional<opengl_swapchain_t> opengl_swapchain;
|
||||||
|
};
|
||||||
|
|
||||||
void
|
void
|
||||||
set_opengl_swapchain(uint32_t our_value, std::optional<uint32_t> undo_value);
|
set_opengl_swapchain(uint32_t our_value, std::optional<uint32_t> undo_value);
|
||||||
|
|
||||||
std::tuple<bool, uint32_t, std::optional<uint32_t>>
|
std::optional<data_t::opengl_swapchain_t>
|
||||||
get_opengl_swapchain() const;
|
get_opengl_swapchain() const;
|
||||||
|
|
||||||
void
|
|
||||||
write(std::ostream &stream) const;
|
|
||||||
|
|
||||||
std::string
|
std::string
|
||||||
write() const;
|
write() const;
|
||||||
|
|
||||||
void
|
|
||||||
read(std::istream &stream);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
read(const std::vector<char> &buffer);
|
read(const std::vector<char> &buffer);
|
||||||
|
|
||||||
|
|
@ -26,7 +35,7 @@ namespace nvprefs {
|
||||||
merge(const undo_data_t &newer_data);
|
merge(const undo_data_t &newer_data);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
boost::json::value data;
|
data_t data;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace nvprefs
|
} // namespace nvprefs
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
#include "nvprefs_common.h"
|
// local includes
|
||||||
|
|
||||||
#include "undo_file.h"
|
#include "undo_file.h"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,10 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
// standard library headers
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "nvprefs_common.h"
|
||||||
#include "undo_data.h"
|
#include "undo_data.h"
|
||||||
|
|
||||||
namespace nvprefs {
|
namespace nvprefs {
|
||||||
|
|
|
||||||
1
third-party/nlohmann_json
vendored
Submodule
1
third-party/nlohmann_json
vendored
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 9cca280a4d0ccf0c08f47a99aa71d1b0e52f8d03
|
||||||
Loading…
Add table
Add a link
Reference in a new issue