From e374575852eae27f8fe38d17d528f068b80eb6a8 Mon Sep 17 00:00:00 2001 From: yyc12345 Date: Wed, 3 Jul 2024 10:14:17 +0800 Subject: [PATCH] fix: fix issue in config manager. - fix fwrite fread issue in config manager. - add testbench for config manager. - change testbench order to get better experience. --- src/ConfigManager.cpp | 20 ++++---- src/ConfigManager.hpp | 9 ++-- testbench/main.cpp | 103 ++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 116 insertions(+), 16 deletions(-) diff --git a/src/ConfigManager.cpp b/src/ConfigManager.cpp index cc6cfc8..f0e0c5d 100644 --- a/src/ConfigManager.cpp +++ b/src/ConfigManager.cpp @@ -35,7 +35,7 @@ namespace YYCC::ConfigManager { // fetch version info uint64_t version_info; - if (std::fread(&version_info, sizeof(version_info), 1u, fs.get()) != sizeof(version_info)) + if (std::fread(&version_info, 1u, sizeof(version_info), fs.get()) != sizeof(version_info)) return false; // check version // if read version is greater than we expected, @@ -51,19 +51,19 @@ namespace YYCC::ConfigManager { // try fetch setting name // fetch name length size_t name_length; - if (std::fread(&name_length, sizeof(name_length), 1u, fs.get()) != sizeof(name_length)) { + if (std::fread(&name_length, 1u, sizeof(name_length), fs.get()) != sizeof(name_length)) { // we also check whether reach EOF at there. if (std::feof(fs.get())) break; else return false; } // fetch name body name_cache.resize(name_length); - if (std::fread(name_cache.data(), name_length, 1u, fs.get()) != name_length) + if (std::fread(name_cache.data(), 1u, name_length, fs.get()) != name_length) return false; // get setting data length size_t data_length; - if (std::fread(&data_length, sizeof(data_length), 1u, fs.get()) != sizeof(data_length)) + if (std::fread(&data_length, 1u, sizeof(data_length), fs.get()) != sizeof(data_length)) return false; // get matched setting first @@ -71,7 +71,7 @@ namespace YYCC::ConfigManager { if (found != m_Settings.end()) { // found. read data for it found->second->ResizeData(data_length); - if (std::fread(found->second->GetDataPtr(), data_length, 1u, fs.get()) != data_length) + if (std::fread(found->second->GetDataPtr(), 1u, data_length, fs.get()) != data_length) return false; // call user defined load function // if fail to parse, reset to default value @@ -95,7 +95,7 @@ namespace YYCC::ConfigManager { // write config data uint64_t version_info = m_VersionIdentifier; - if (std::fwrite(&version_info, sizeof(version_info), 1u, fs.get()) != sizeof(version_info)) + if (std::fwrite(&version_info, 1u, sizeof(version_info), fs.get()) != sizeof(version_info)) return false; // iterate all data for writing @@ -108,19 +108,19 @@ namespace YYCC::ConfigManager { // write setting name // write name length size_t name_length = pair.first.size(); - if (std::fwrite(&name_length, sizeof(name_length), 1u, fs.get()) != sizeof(name_length)) + if (std::fwrite(&name_length, 1u, sizeof(name_length), fs.get()) != sizeof(name_length)) return false; // write name body - if (std::fwrite(pair.first.c_str(), name_length, 1u, fs.get()) != name_length) + if (std::fwrite(pair.first.c_str(), 1u, name_length, fs.get()) != name_length) return false; // write setting daat // write data length size_t data_length = pair.second->GetDataSize(); - if (std::fwrite(&data_length, sizeof(data_length), 1u, fs.get()) != sizeof(data_length)) + if (std::fwrite(&data_length, 1u, sizeof(data_length), fs.get()) != sizeof(data_length)) return false; // write data body - if (std::fwrite(pair.second->GetDataPtr(), data_length, 1u, fs.get()) != data_length) + if (std::fwrite(pair.second->GetDataPtr(), 1u, data_length, fs.get()) != data_length) return false; } diff --git a/src/ConfigManager.hpp b/src/ConfigManager.hpp index c57fd17..76925c2 100644 --- a/src/ConfigManager.hpp +++ b/src/ConfigManager.hpp @@ -26,7 +26,7 @@ namespace YYCC::ConfigManager { namespace ConstrainPresets { - template, int> = 0> + template && !std::is_enum_v<_Ty> && !std::is_same_v<_Ty, bool>, int> = 0> Constrain<_Ty> GetNumberRangeConstrain(_Ty min_value, _Ty max_value) { if (min_value > max_value) throw std::invalid_argument("invalid min max value for NumberRangeConstrain"); @@ -93,7 +93,7 @@ namespace YYCC::ConfigManager { #pragma region Setting Presets - template, int> = 0> + template || std::is_enum_v<_Ty>, int> = 0> class NumberSetting : public AbstractSetting { public: NumberSetting(const yycc_char8_t* name, _Ty default_value, Constrain<_Ty> constrain = Constrain<_Ty> {}) : @@ -103,7 +103,7 @@ namespace YYCC::ConfigManager { _Ty Get() const { return m_Data; } bool Set(_Ty new_data) { // validate data - if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(m_Data)) + if (m_Constrain.IsValid() && !m_Constrain.m_CheckFct(new_data)) return false; // assign data m_Data = new_data; @@ -189,6 +189,9 @@ namespace YYCC::ConfigManager { std::memcpy(ptr + sizeof(string_length), m_Data.data(), string_length); return true; } + virtual void UserReset() override { + m_Data = m_DefaultData; + } yycc_u8string m_Data, m_DefaultData; Constrain m_Constrain; diff --git a/testbench/main.cpp b/testbench/main.cpp index 62f2111..9f9daa5 100644 --- a/testbench/main.cpp +++ b/testbench/main.cpp @@ -390,15 +390,112 @@ namespace YYCCTestbench { } + class TestConfigManager { + public: + enum class TestEnum : int8_t { + Test1, Test2, Test3 + }; + + TestConfigManager() : + m_IntSetting(YYCC_U8("int-setting"), INT32_C(0)), + m_FloatSetting(YYCC_U8("float-setting"), 0.0f), + m_StringSetting(YYCC_U8("string-setting"), YYCC_U8("")), + m_BoolSetting(YYCC_U8("bool-setting"), false), + m_ClampedFloatSetting(YYCC_U8("clamped-float-setting"), 0.0f, YYCC::ConfigManager::ConstrainPresets::GetNumberRangeConstrain(-1.0f, 1.0f)), + m_EnumSetting(YYCC_U8("enum-setting"), TestEnum::Test1), + m_CoreManager(YYCC_U8("test.cfg"), UINT64_C(0), { + &m_IntSetting, &m_FloatSetting, &m_StringSetting, &m_BoolSetting, &m_ClampedFloatSetting, &m_EnumSetting + }) + {} + ~TestConfigManager() {} + + void PrintSettings() { + Console::WriteLine(YYCC_U8("Config Manager Settings:")); + + Console::FormatLine(YYCC_U8("\tint-setting: %" PRIi32), m_IntSetting.Get()); + Console::FormatLine(YYCC_U8("\tfloat-setting: %f"), m_FloatSetting.Get()); + Console::FormatLine(YYCC_U8("\tstring-setting: %s"), m_StringSetting.Get().c_str()); + + Console::FormatLine(YYCC_U8("\tbool-setting: %s"), m_BoolSetting.Get() ? YYCC_U8("true") : YYCC_U8("false")); + Console::FormatLine(YYCC_U8("\tfloat-setting: %f"), m_ClampedFloatSetting.Get()); + Console::FormatLine(YYCC_U8("\tenum-setting: %" PRIi8), static_cast>(m_EnumSetting.Get())); + } + + YYCC::ConfigManager::NumberSetting m_IntSetting; + YYCC::ConfigManager::NumberSetting m_FloatSetting; + YYCC::ConfigManager::StringSetting m_StringSetting; + + YYCC::ConfigManager::NumberSetting m_BoolSetting; + YYCC::ConfigManager::NumberSetting m_ClampedFloatSetting; + YYCC::ConfigManager::NumberSetting m_EnumSetting; + + YYCC::ConfigManager::CoreManager m_CoreManager; + }; + + static void ConfigManagerTestbench() { + // init cfg manager + TestConfigManager test; + + // test constrain works + Assert(!test.m_ClampedFloatSetting.Set(2.0f), YYCC_U8("YYCC::ConfigManager::Constraint")); + Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::Constraint")); + + // test modify settings +#define TEST_MACRO(member_name, set_val) { \ + Assert(test.member_name.Set(set_val), YYCC_U8("YYCC::ConfigManager::AbstractSetting::Set")); \ + Assert(test.member_name.Get() == set_val, YYCC_U8("YYCC::ConfigManager::AbstractSetting::Set")); \ +} + + TEST_MACRO(m_IntSetting, INT32_C(114)); + TEST_MACRO(m_FloatSetting, 2.0f); + TEST_MACRO(m_StringSetting, YYCC_U8("fuck")); + TEST_MACRO(m_BoolSetting, true); + TEST_MACRO(m_ClampedFloatSetting, 0.5f); + TEST_MACRO(m_EnumSetting, TestConfigManager::TestEnum::Test2); + +#undef TEST_MACRO + + // test save + test.PrintSettings(); + Assert(test.m_CoreManager.Save(), YYCC_U8("YYCC::ConfigManager::CoreManager::Save")); + + // test reset + test.m_CoreManager.Reset(); + test.PrintSettings(); + Assert(test.m_IntSetting.Get() == INT32_C(0), YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + Assert(test.m_FloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + Assert(test.m_StringSetting.Get() == YYCC_U8(""), YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + Assert(test.m_BoolSetting.Get() == false, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + Assert(test.m_EnumSetting.Get() == TestConfigManager::TestEnum::Test1, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset")); + + // test load + Assert(test.m_CoreManager.Load(), YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + test.PrintSettings(); + Assert(test.m_IntSetting.Get() == INT32_C(114), YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + Assert(test.m_FloatSetting.Get() == 2.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + Assert(test.m_StringSetting.Get() == YYCC_U8("fuck"), YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + Assert(test.m_BoolSetting.Get() == true, YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + Assert(test.m_ClampedFloatSetting.Get() == 0.5f, YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + Assert(test.m_EnumSetting.Get() == TestConfigManager::TestEnum::Test2, YYCC_U8("YYCC::ConfigManager::CoreManager::Load")); + + } + } int main(int argc, char** args) { - //YYCCTestbench::ConsoleTestbench(); + // common testbench + // normal YYCCTestbench::EncodingTestbench(); YYCCTestbench::StringTestbench(); YYCCTestbench::ParserTestbench(); - YYCCTestbench::DialogTestbench(); - YYCCTestbench::ExceptionTestbench(); YYCCTestbench::WinFctTestbench(); YYCCTestbench::FsPathPatch(); + // advanced + YYCCTestbench::ConfigManagerTestbench(); + + // testbench which may terminal app or ordering input + YYCCTestbench::ConsoleTestbench(); + YYCCTestbench::DialogTestbench(); + YYCCTestbench::ExceptionTestbench(); }