#ifndef __APPLICATIONSETTINGS_H__ #define __APPLICATIONSETTINGS_H__ #include "BoostLog.h" #include #include #include #include #include #include template 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(#Category "." #Name, DefaultValue); \ } #define BUILD_STATUS(Type, Name, DefaultValue) BUILD_SETTING_FIELD(Status, Type, Name, DefaultValue) #define BUILD_SETTING(Type, Name, DefaultValue) BUILD_SETTING_FIELD(Settings, Type, Name, DefaultValue) #define INITIALIZE_FIELD(Name) set##Name(get##Name()); #define MACRO(r, data, elem) INITIALIZE_FIELD(elem) #define INITIALIZE_FIELDS(...) \ inline void initializeFileds() final { \ BOOST_PP_SEQ_FOR_EACH(MACRO, _, BOOST_PP_TUPLE_TO_SEQ((__VA_ARGS__))) \ } public: ApplicationSettings(const std::string &path) : m_path(path) { if (std::filesystem::exists(path)) { try { boost::property_tree::read_ini(path, m_ptree); } catch (const boost::property_tree::ini_parser_error &e) { LOG(error) << e.what(); } } else { static_cast(this)->initializeFileds(); save(); } } void startCheckInterval(boost::asio::io_context &ioContext, uint32_t seconds) { m_timer = std::make_unique(ioContext); m_interval = seconds; run(); } protected: void save() { if (!m_needSave) return; try { std::lock_guard locker(m_mutex); boost::property_tree::write_ini(m_path, m_ptree); m_needSave = false; } catch (const boost::property_tree::ini_parser_error &e) { LOG(error) << e.what(); } } void run() { m_timer->expires_after(std::chrono::seconds(m_interval)); m_timer->async_wait([this](const boost::system::error_code &error) { if (error) { LOG(error) << error.message(); return; } save(); run(); }); } virtual void initializeFileds() { } boost::property_tree::ptree m_ptree; bool m_needSave = false; mutable std::mutex m_mutex; private: std::string m_path; std::unique_ptr m_timer; uint32_t m_interval; }; #endif // __APPLICATIONSETTINGS_H__