add settings class.
This commit is contained in:
parent
b8c3ed6b7d
commit
20750d1a80
@ -31,6 +31,9 @@ add_executable(UnitTest main.cpp
|
||||
HttpProxy/BoostUrlTest.cpp
|
||||
|
||||
Universal/BoostLogTest.cpp
|
||||
Universal/DateTimeTest.cpp
|
||||
Universal/MessageManagerTest.cpp
|
||||
Universal/SingletonTest.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(UnitTest
|
||||
|
83
UnitTest/Universal/DateTimeTest.cpp
Normal file
83
UnitTest/Universal/DateTimeTest.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include <BoostLog.h>
|
||||
#include <DateTime.h>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(DateTimeTest, *boost::unit_test::enabled())
|
||||
|
||||
BOOST_AUTO_TEST_CASE(BasicUse) {
|
||||
std::time_t c_current = std::time(nullptr);
|
||||
auto c_local = localtime(&c_current);
|
||||
|
||||
auto now = DateTime::currentDateTime();
|
||||
BOOST_CHECK_EQUAL(now.year(), c_local->tm_year + 1900);
|
||||
BOOST_CHECK_EQUAL(now.month(), c_local->tm_mon + 1);
|
||||
BOOST_CHECK_EQUAL(now.day(), c_local->tm_mday);
|
||||
BOOST_CHECK_EQUAL(now.hour(), c_local->tm_hour);
|
||||
BOOST_CHECK_EQUAL(now.minute(), c_local->tm_min);
|
||||
BOOST_CHECK_EQUAL(now.second(), c_local->tm_sec);
|
||||
|
||||
// std::cout << "now: " << DateTime::toString(std::chrono::system_clock::now()) << std::endl;
|
||||
// std::cout << "now: " << DateTime::currentDateTime().toString() << std::endl;
|
||||
|
||||
auto day = DateTime::makeDateTime(2018, 8, 15, 13, 14, 59);
|
||||
DateTime r(day);
|
||||
BOOST_CHECK_EQUAL(r.week(), DateTime::Wednesday);
|
||||
BOOST_CHECK_EQUAL(DateTime::toString(day), "2018-08-15 13:14:59");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(IsLeapYearTest) {
|
||||
BOOST_TEST(DateTime::isLeapYear(2008));
|
||||
BOOST_TEST(!DateTime::isLeapYear(2100));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(TomorrowTest) {
|
||||
DateTime day(2018, 8, 15, 13, 14, 59);
|
||||
auto t = day.tomorrow();
|
||||
BOOST_CHECK_EQUAL(t.toString(), "2018-08-16 13:14:59");
|
||||
|
||||
day = DateTime(2018, 12, 31, 13, 14, 59);
|
||||
t = day.tomorrow();
|
||||
BOOST_CHECK_EQUAL(t.toString(), "2019-01-01 13:14:59");
|
||||
|
||||
day = DateTime(2020, 2, 28, 13, 14, 59);
|
||||
t = day.tomorrow();
|
||||
BOOST_CHECK_EQUAL(t.toString(), "2020-02-29 13:14:59");
|
||||
|
||||
day = DateTime(2021, 2, 28, 13, 14, 59);
|
||||
t = day.tomorrow();
|
||||
BOOST_CHECK_EQUAL(t.toString(), "2021-03-01 13:14:59");
|
||||
|
||||
day = DateTime(2021, 10, 25, 22, 31, 59);
|
||||
t = day.tomorrow();
|
||||
BOOST_CHECK_EQUAL(t.toString(), "2021-10-26 22:31:59");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(CurrentMSecsSinceEpoch) {
|
||||
BOOST_CHECK_EQUAL(DateTime::currentMSecsSinceEpoch(),
|
||||
std::chrono::time_point_cast<std::chrono::milliseconds>(std::chrono::system_clock::now())
|
||||
.time_since_epoch()
|
||||
.count());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ParseTimeString) {
|
||||
auto [hour, minute, second] = DateTime::parseTime("12:14:15");
|
||||
BOOST_CHECK_EQUAL(hour, 12);
|
||||
BOOST_CHECK_EQUAL(minute, 14);
|
||||
BOOST_CHECK_EQUAL(second, 15);
|
||||
|
||||
std::tie(hour, minute, second) = DateTime::parseTime("15:12");
|
||||
BOOST_CHECK_EQUAL(hour, 15);
|
||||
BOOST_CHECK_EQUAL(minute, 12);
|
||||
BOOST_CHECK_EQUAL(second, 0);
|
||||
|
||||
std::tie(hour, minute, second) = DateTime::parseTime("00:09:07");
|
||||
BOOST_CHECK_EQUAL(hour, 0);
|
||||
BOOST_CHECK_EQUAL(minute, 9);
|
||||
BOOST_CHECK_EQUAL(second, 7);
|
||||
|
||||
std::tie(hour, minute, second) = DateTime::parseTime("15:12");
|
||||
BOOST_CHECK_EQUAL(hour, 15);
|
||||
BOOST_CHECK_EQUAL(minute, 12);
|
||||
BOOST_CHECK_EQUAL(second, 0);
|
||||
}
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
187
UnitTest/Universal/MessageManagerTest.cpp
Normal file
187
UnitTest/Universal/MessageManagerTest.cpp
Normal file
@ -0,0 +1,187 @@
|
||||
#include <BoostLog.h>
|
||||
#include <FunctionTraits.h>
|
||||
#include <MessageManager.h>
|
||||
#include <boost/function_types/function_type.hpp>
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
static int test(int a, int b) {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
class Test {
|
||||
public:
|
||||
int test(int a, int b) {
|
||||
result = a + b + 3;
|
||||
return result;
|
||||
}
|
||||
int result{0};
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(MessageManagerTest, *boost::unit_test::enabled())
|
||||
// returned-function-return-type (* function-name (parameter-list) ) (function-to-return-parameter-list)
|
||||
BOOST_AUTO_TEST_CASE(FunctionTraitsNormalFunctionTest) {
|
||||
using namespace std::placeholders;
|
||||
MessageManager m;
|
||||
|
||||
m.registerTopic("123", [](int a) -> void { a = a + 102; });
|
||||
BOOST_CHECK_EQUAL(m.topicCount<int(int)>("123"), 1);
|
||||
|
||||
Test t;
|
||||
m.registerTopic("123", [&t](int a, int b) { return t.test(a, b); });
|
||||
BOOST_CHECK_EQUAL(m.topicCount<int(int, int)>("123"), 1);
|
||||
|
||||
m.registerTopic("123", std::bind(&Test::test, &t, _1, _2));
|
||||
BOOST_CHECK_EQUAL(m.topicCount<int(int, int)>("123"), 2);
|
||||
|
||||
m.registerTopic("123", &test);
|
||||
BOOST_CHECK_EQUAL(m.topicCount<int(int, int)>("123"), 3);
|
||||
|
||||
m.removeTopic<int(int, int)>("123");
|
||||
BOOST_CHECK_EQUAL(m.topicCount<int(int, int)>("123"), 0);
|
||||
|
||||
m.registerTopic("123", [](const std::string &title) {});
|
||||
|
||||
m.registerTopic(
|
||||
"123", [](int type, const std::string &title, const std::string &message, const std::function<void()> &yes) {});
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SyncMessage) {
|
||||
using namespace std::placeholders;
|
||||
MessageManager manager;
|
||||
|
||||
int result1 = 0;
|
||||
std::thread::id id;
|
||||
manager.registerTopic("123", [&result1](int a) {
|
||||
result1 += a;
|
||||
return a + 102;
|
||||
});
|
||||
int result2 = 0;
|
||||
manager.registerTopic("123", [&result2](const int &a) {
|
||||
result2 = a + 102;
|
||||
return result2;
|
||||
});
|
||||
manager.sendMessage("123", 5);
|
||||
BOOST_CHECK_EQUAL(result1, 5);
|
||||
BOOST_CHECK_EQUAL(result2, 107);
|
||||
|
||||
int result3 = 0;
|
||||
manager.registerTopic("123", [&result3](int a, int b) {
|
||||
result3 = a + b;
|
||||
return 0;
|
||||
});
|
||||
Test t;
|
||||
manager.registerTopic("123", std::bind(&Test::test, &t, _1, _2));
|
||||
manager.sendMessage("123", 12, 13);
|
||||
BOOST_CHECK_EQUAL(result3, 25);
|
||||
BOOST_CHECK_EQUAL(t.result, 28);
|
||||
|
||||
int result4 = 0;
|
||||
manager.registerTopic("123", [&result4]() {
|
||||
result4 = 102;
|
||||
return result4;
|
||||
});
|
||||
manager.sendMessage("123");
|
||||
BOOST_CHECK_EQUAL(result4, 102);
|
||||
|
||||
constexpr auto magic = "MagicString";
|
||||
std::string result5;
|
||||
manager.registerTopic("test", [&result5](const std::string &text) { result5 = text; });
|
||||
// manager.sendMessage<std::string>("test", magic); // 编译不通过
|
||||
|
||||
// manager.sendMessage("test", magic); // const char*无法匹配到std::string
|
||||
// BOOST_CHECK_EQUAL(result5, magic);
|
||||
// result5.clear();
|
||||
|
||||
manager.sendMessage<void(const std::string &), std::string>("test", magic);
|
||||
BOOST_CHECK_EQUAL(result5, magic);
|
||||
result5.clear();
|
||||
|
||||
manager.sendMessage<void(const std::string &)>("test", std::string(magic));
|
||||
BOOST_CHECK_EQUAL(result5, magic);
|
||||
result5.clear();
|
||||
|
||||
manager.sendMessage<void(std::string)>("test", magic);
|
||||
BOOST_CHECK_EQUAL(result5, magic);
|
||||
result5.clear();
|
||||
|
||||
manager.sendMessage("test", std::string(magic));
|
||||
BOOST_CHECK_EQUAL(result5, magic);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(SyncMessageWithVoidArg) {
|
||||
MessageManager manager;
|
||||
constexpr auto Topic = MessageManager::Message<>("test1");
|
||||
int result = 0;
|
||||
manager.registerTopic("test1", [&result]() -> void { result = 250; });
|
||||
manager.sendMessage("test1");
|
||||
BOOST_CHECK_EQUAL(result, 250);
|
||||
|
||||
result = 0;
|
||||
manager.sendMessage(Topic);
|
||||
BOOST_CHECK_EQUAL(result, 250);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AsyncMessage) {
|
||||
int result = 0;
|
||||
std::thread::id id;
|
||||
auto test1 = [&result, &id](int a, int b) -> void {
|
||||
result = a + b;
|
||||
id = std::this_thread::get_id();
|
||||
};
|
||||
|
||||
MessageManager manager;
|
||||
manager.registerTopic("test1", test1);
|
||||
manager.sendAsyncMessage("test1", 2, 6);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
BOOST_CHECK_EQUAL(result, 8);
|
||||
BOOST_CHECK_NE(std::this_thread::get_id(), id);
|
||||
|
||||
constexpr auto magic = "MagicString";
|
||||
manager.registerTopic("StringCompare", [magic](const std::string &text) { BOOST_CHECK_EQUAL(text, magic); });
|
||||
{
|
||||
std::string string(magic);
|
||||
manager.sendAsyncMessage("StringCompare", string);
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(AsyncMessageImplictConversion) {
|
||||
float result1 = 0;
|
||||
auto test1 = [&result1](int a, int b) -> void { result1 = a + b; };
|
||||
|
||||
float result2 = 0;
|
||||
auto test2 = [&result2](int a, int b) -> void { result2 = a + b; };
|
||||
|
||||
MessageManager manager;
|
||||
|
||||
manager.registerTopic("test1", test1);
|
||||
manager.registerTopic("test2", test2);
|
||||
manager.sendAsyncMessage<decltype(test1)>("test1", 2.6, 6);
|
||||
manager.sendAsyncMessage("test2", (int)3.6, 6);
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
BOOST_CHECK_EQUAL(result1, 8);
|
||||
BOOST_CHECK_EQUAL(result2, 9);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(DefineTopicUseMessage) {
|
||||
constexpr auto TestTopic1 = MessageManager::Message<int, int>("TestTopic1");
|
||||
int result1 = 0;
|
||||
auto test1 = [&result1](int a, int b) -> void { result1 = a + b; };
|
||||
MessageManager manager;
|
||||
manager.registerTopic(TestTopic1, test1);
|
||||
manager.sendMessage(TestTopic1, 2, 3);
|
||||
BOOST_CHECK_EQUAL(result1, 5);
|
||||
|
||||
std::string result2;
|
||||
constexpr auto TestTopic2 = MessageManager::Message<const std::string &>("TestTopic2");
|
||||
auto test2 = [&result2](const std::string &text) -> void { result2 = text; };
|
||||
manager.registerTopic(TestTopic2, test2);
|
||||
manager.sendMessage(TestTopic2, std::string("hello"));
|
||||
std::string message("hello");
|
||||
// manager.sendMessage(TestTopic2, message);
|
||||
// manager.sendMessage(TestTopic2, "hello");
|
||||
BOOST_CHECK_EQUAL(result2, "hello");
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
39
UnitTest/Universal/SingletonTest.cpp
Normal file
39
UnitTest/Universal/SingletonTest.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
#include "Singleton.h"
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
class Test {
|
||||
public:
|
||||
size_t index;
|
||||
};
|
||||
|
||||
BOOST_AUTO_TEST_CASE(LocalInstance) {
|
||||
auto test = Amass::Singleton<Test>::instance();
|
||||
BOOST_TEST(!test);
|
||||
|
||||
{
|
||||
auto local = Amass::Singleton<Test>::instance<Amass::Construct>();
|
||||
BOOST_TEST(local);
|
||||
|
||||
auto refer = Amass::Singleton<Test>::instance();
|
||||
BOOST_TEST(refer);
|
||||
}
|
||||
|
||||
test = Amass::Singleton<Test>::instance();
|
||||
BOOST_TEST(!test);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(GlobalInstance) {
|
||||
auto test = Amass::Singleton<Test, Amass::GlobalInstance>::instance();
|
||||
BOOST_TEST(test);
|
||||
|
||||
{
|
||||
auto local = Amass::Singleton<Test, Amass::GlobalInstance>::instance();
|
||||
BOOST_TEST(local);
|
||||
|
||||
auto refer = Amass::Singleton<Test, Amass::GlobalInstance>::instance();
|
||||
BOOST_TEST(refer);
|
||||
}
|
||||
|
||||
test = Amass::Singleton<Test, Amass::GlobalInstance>::instance();
|
||||
BOOST_TEST(test);
|
||||
}
|
36
Universal/ApplicationSettings.cpp
Normal file
36
Universal/ApplicationSettings.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include "ApplicationSettings.h"
|
||||
#include "BoostLog.h"
|
||||
#include <boost/property_tree/ini_parser.hpp>
|
||||
#include <filesystem>
|
||||
|
||||
ApplicationSettings::ApplicationSettings(boost::asio::io_context &ioContext, const std::string &path)
|
||||
: m_ioContext(ioContext), m_timer(ioContext), m_path(path) {
|
||||
if (std::filesystem::exists(std::filesystem::path(path))) {
|
||||
try {
|
||||
boost::property_tree::read_ini(path, m_ptree);
|
||||
} catch (const boost::property_tree::ini_parser_error &e) {
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
}
|
||||
run();
|
||||
}
|
||||
|
||||
void ApplicationSettings::run() {
|
||||
m_timer.expires_after(std::chrono::seconds(1));
|
||||
m_timer.async_wait([this](const boost::system::error_code &error) {
|
||||
if (error) {
|
||||
LOG(error) << error.message();
|
||||
return;
|
||||
}
|
||||
if (m_needSave) {
|
||||
try {
|
||||
std::lock_guard locker(m_mutex);
|
||||
boost::property_tree::write_ini(m_path, m_ptree);
|
||||
} catch (const boost::property_tree::ini_parser_error &e) {
|
||||
LOG(error) << e.what();
|
||||
}
|
||||
m_needSave = false;
|
||||
}
|
||||
run();
|
||||
});
|
||||
}
|
38
Universal/ApplicationSettings.h
Normal file
38
Universal/ApplicationSettings.h
Normal file
@ -0,0 +1,38 @@
|
||||
#ifndef __APPLICATIONSETTINGS_H__
|
||||
#define __APPLICATIONSETTINGS_H__
|
||||
|
||||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/property_tree/ptree.hpp>
|
||||
|
||||
class ApplicationSettings {
|
||||
#define BUILD_SETTING_FIELD(Category, Type, Name, DefaultValue) \
|
||||
inline void set##Name(const Type &value) { \
|
||||
std::lock_guard locker(m_mutex); \
|
||||
m_ptree.put(#Category "." #Name, value); \
|
||||
m_needSave = true; \
|
||||
} \
|
||||
inline Type get##Name() const { \
|
||||
std::lock_guard locker(m_mutex); \
|
||||
return m_ptree.get<Type>(#Category "." #Name, DefaultValue); \
|
||||
}
|
||||
|
||||
#define BUILD_STATUS(Type, Name, DefaultValue) BUILD_SETTING_FIELD(Status, Type, Name, DefaultValue)
|
||||
|
||||
public:
|
||||
ApplicationSettings(boost::asio::io_context &ioContext, const std::string &path);
|
||||
|
||||
protected:
|
||||
void run();
|
||||
|
||||
boost::property_tree::ptree m_ptree;
|
||||
bool m_needSave = false;
|
||||
mutable std::mutex m_mutex;
|
||||
|
||||
private:
|
||||
boost::asio::io_context &m_ioContext;
|
||||
boost::asio::steady_timer m_timer;
|
||||
std::string m_path;
|
||||
};
|
||||
|
||||
#endif // __APPLICATIONSETTINGS_H__
|
@ -1,6 +1,7 @@
|
||||
find_package(Boost REQUIRED COMPONENTS log log_setup program_options)
|
||||
|
||||
add_library(Universal
|
||||
ApplicationSettings.h ApplicationSettings.cpp
|
||||
BoostLog.h BoostLog.inl BoostLog.cpp
|
||||
BufferUtility.h BufferUtility.cpp
|
||||
DateTime.h DateTime.cpp
|
||||
|
@ -36,6 +36,11 @@ public:
|
||||
std::chrono::time_point<std::chrono::system_clock> operator()();
|
||||
std::string toString(const std::string_view &format = "%F %T") const;
|
||||
|
||||
/**
|
||||
* @brief 2023-10-12 12:10:23 then return 2023-10-13 12:10:23
|
||||
*
|
||||
* @return DateTime
|
||||
*/
|
||||
DateTime tomorrow();
|
||||
|
||||
// Returns the number of milliseconds since 1970-01-01T00:00:00 Universal Coordinated Time. This number is like the
|
||||
|
Loading…
Reference in New Issue
Block a user