libfly  6.2.2
C++20 utility library for Linux, macOS, and Windows
config_manager.hpp
1 #pragma once
2 
3 #include "fly/concepts/concepts.hpp"
4 #include "fly/config/config.hpp"
5 #include "fly/logger/logger.hpp"
6 #include "fly/types/json/json.hpp"
7 #include "fly/types/string/formatters.hpp"
8 
9 #include <cstdint>
10 #include <filesystem>
11 #include <map>
12 #include <memory>
13 #include <mutex>
14 #include <string>
15 #include <type_traits>
16 
17 namespace fly::parser {
18 class Parser;
19 } // namespace fly::parser
20 
21 namespace fly::path {
22 class PathMonitor;
23 } // namespace fly::path
24 
25 namespace fly::task {
26 class SequencedTaskRunner;
27 } // namespace fly::task
28 
29 namespace fly::config {
30 
34 enum class ConfigFileType : std::uint8_t
35 {
36  Ini,
37  Json,
38 };
39 
46 class ConfigManager : public std::enable_shared_from_this<ConfigManager>
47 {
48 public:
52  using ConfigMap = std::map<std::string, std::weak_ptr<Config>>;
53 
63  static std::shared_ptr<ConfigManager> create(
64  std::shared_ptr<fly::task::SequencedTaskRunner> task_runner,
65  ConfigFileType file_type,
66  std::filesystem::path path);
67 
72 
80  template <fly::DerivedFrom<Config> T>
81  std::shared_ptr<T> create_config();
82 
88  ConfigMap::size_type prune();
89 
90 private:
99  std::shared_ptr<fly::task::SequencedTaskRunner> task_runner,
100  ConfigFileType file_type,
101  std::filesystem::path path) noexcept;
102 
108  bool start();
109 
113  void update_config();
114 
115  std::shared_ptr<fly::task::SequencedTaskRunner> m_task_runner;
116 
117  std::shared_ptr<fly::path::PathMonitor> m_monitor;
118  std::unique_ptr<fly::parser::Parser> m_parser;
119  fly::Json m_values;
120 
121  const std::filesystem::path m_path;
122 
123  mutable std::mutex m_configs_mutex;
124  ConfigMap m_configs;
125 };
126 
127 //==================================================================================================
128 template <fly::DerivedFrom<Config> T>
129 std::shared_ptr<T> ConfigManager::create_config()
130 {
131  std::shared_ptr<T> config;
132 
133  std::lock_guard<std::mutex> lock(m_configs_mutex);
134  ConfigMap::const_iterator it = m_configs.find(T::identifier);
135 
136  if (it == m_configs.end())
137  {
138  config = std::make_shared<T>();
139  m_configs[T::identifier] = config;
140  }
141  else
142  {
143  std::shared_ptr<Config> base_config = it->second.lock();
144 
145  if (base_config)
146  {
147  config = std::dynamic_pointer_cast<T>(base_config);
148  }
149  else
150  {
151  config = std::make_shared<T>();
152  m_configs[T::identifier] = config;
153  }
154  }
155 
156  if (config)
157  {
158  config->update(m_values[T::identifier]);
159  }
160  else
161  {
162  LOGW("Could not create configuration for type {}", T::identifier);
163  }
164 
165  return config;
166 }
167 
168 } // namespace fly::config
169 
170 //==================================================================================================
171 template <>
172 struct fly::Formatter<fly::config::ConfigFileType> : public fly::Formatter<std::uint8_t>
173 {
182  template <typename FormatContext>
183  void format(fly::config::ConfigFileType file_type, FormatContext &context)
184  {
185  fly::Formatter<std::uint8_t>::format(static_cast<std::uint8_t>(file_type), context);
186  }
187 };
Definition: json.hpp:162
Definition: config_manager.hpp:47
std::shared_ptr< T > create_config()
Definition: config_manager.hpp:129
~ConfigManager()
Definition: config_manager.cpp:66
ConfigMap::size_type prune()
Definition: config_manager.cpp:99
static std::shared_ptr< ConfigManager > create(std::shared_ptr< fly::task::SequencedTaskRunner > task_runner, ConfigFileType file_type, std::filesystem::path path)
Definition: config_manager.cpp:15
std::map< std::string, std::weak_ptr< Config > > ConfigMap
Definition: config_manager.hpp:52
void format(fly::config::ConfigFileType file_type, FormatContext &context)
Definition: config_manager.hpp:183
Definition: formatters.hpp:42