| 1 | //! @file configure.hpp |
| 2 | //! @author ryftchen |
| 3 | //! @brief The declarations (configure) in the application module. |
| 4 | //! @version 0.1.0 |
| 5 | //! @copyright Copyright (c) 2022-2025 ryftchen. All rights reserved. |
| 6 | |
| 7 | #pragma once |
| 8 | |
| 9 | #include "utility/include/json.hpp" |
| 10 | #include "utility/include/macro.hpp" |
| 11 | #include "utility/include/memory.hpp" |
| 12 | #include "utility/include/thread.hpp" |
| 13 | |
| 14 | //! @brief The application module. |
| 15 | namespace application // NOLINT(modernize-concat-nested-namespaces) |
| 16 | { |
| 17 | //! @brief Configuration-related functions in the application module. |
| 18 | namespace configure |
| 19 | { |
| 20 | //! @brief The literal string of the field. |
| 21 | namespace field |
| 22 | { |
| 23 | //! @brief The literal string of the "activateHelper" field. |
| 24 | constexpr const char* const activateHelper = MACRO_STRINGIFY(activateHelper); |
| 25 | //! @brief The literal string of the "helperList" field. |
| 26 | constexpr const char* const helperList = MACRO_STRINGIFY(helperList); |
| 27 | //! @brief The literal string of the "properties" field in the object of "helpList". |
| 28 | constexpr const char* const properties = MACRO_STRINGIFY(properties); |
| 29 | //! @brief The literal string of the "required" field in the object of "helpList". |
| 30 | constexpr const char* const required = MACRO_STRINGIFY(required); |
| 31 | //! @brief The literal string of the "logger" field of "helpList". |
| 32 | constexpr const char* const logger = MACRO_STRINGIFY(logger); |
| 33 | //! @brief The literal string of the "filePath" field in the properties of "logger" object of "helpList". |
| 34 | constexpr const char* const filePath = MACRO_STRINGIFY(filePath); |
| 35 | //! @brief The literal string of the "priorityLevel" field in the properties of "logger" object of "helpList". |
| 36 | constexpr const char* const priorityLevel = MACRO_STRINGIFY(priorityLevel); |
| 37 | //! @brief The literal string of the "targetType" field in the properties of "logger" object of "helpList". |
| 38 | constexpr const char* const targetType = MACRO_STRINGIFY(targetType); |
| 39 | //! @brief The literal string of the "writeMode" field in the properties of "logger" object of "helpList". |
| 40 | constexpr const char* const writeMode = MACRO_STRINGIFY(writeMode); |
| 41 | //! @brief The literal string of the "viewer" field of "helpList". |
| 42 | constexpr const char* const viewer = MACRO_STRINGIFY(viewer); |
| 43 | //! @brief The literal string of the "tcpHost" field in the properties of "viewer" object of "helpList". |
| 44 | constexpr const char* const tcpHost = MACRO_STRINGIFY(tcpHost); |
| 45 | //! @brief The literal string of the "tcpPort" field in the properties of "viewer" object of "helpList". |
| 46 | constexpr const char* const tcpPort = MACRO_STRINGIFY(tcpPort); |
| 47 | //! @brief The literal string of the "udpHost" field in the properties of "viewer" object of "helpList". |
| 48 | constexpr const char* const udpHost = MACRO_STRINGIFY(udpHost); |
| 49 | //! @brief The literal string of the "udpPort" field in the properties of "viewer" object of "helpList". |
| 50 | constexpr const char* const udpPort = MACRO_STRINGIFY(udpPort); |
| 51 | //! @brief The literal string of the "helperTimeout" field. |
| 52 | constexpr const char* const helperTimeout = MACRO_STRINGIFY(helperTimeout); |
| 53 | } // namespace field |
| 54 | |
| 55 | //! @brief Maximum access limit. |
| 56 | constexpr std::uint8_t maxAccessLimit = 10; |
| 57 | //! @brief Default configuration filename. |
| 58 | constexpr std::string_view defaultConfigFile = "configure/foo.json" ; |
| 59 | //! @brief Get the full path to the configuration file. |
| 60 | //! @param filename - configuration file path |
| 61 | //! @return full path to the configuration file |
| 62 | std::string getFullConfigPath(const std::string_view filename = defaultConfigFile); |
| 63 | |
| 64 | //! @brief Configuration. |
| 65 | class Configure final |
| 66 | { |
| 67 | public: |
| 68 | //! @brief Destroy the Configure object. |
| 69 | ~Configure() = default; |
| 70 | //! @brief Construct a new Configure object. |
| 71 | Configure(const Configure&) = delete; |
| 72 | //! @brief Construct a new Configure object. |
| 73 | Configure(Configure&&) = delete; |
| 74 | //! @brief The operator (=) overloading of Configure class. |
| 75 | //! @return reference of the Configure object |
| 76 | Configure& operator=(const Configure&) = delete; |
| 77 | //! @brief The operator (=) overloading of Configure class. |
| 78 | //! @return reference of the Configure object |
| 79 | Configure& operator=(Configure&&) = delete; |
| 80 | |
| 81 | friend const Configure& getInstance(const std::string_view filename); |
| 82 | |
| 83 | private: |
| 84 | //! @brief Construct a new Configure object. |
| 85 | //! @param filename - configure file path |
| 86 | explicit Configure(const std::string_view filename) : |
| 87 | filePath{getFullConfigPath(filename)}, dataRepo(parseConfigFile(configFile: filePath)) |
| 88 | { |
| 89 | } |
| 90 | |
| 91 | //! @brief Full path to the configuration file. |
| 92 | const std::string filePath; |
| 93 | //! @brief Configuration data repository. |
| 94 | const utility::json::JSON dataRepo; |
| 95 | |
| 96 | friend class Retrieve; |
| 97 | //! @brief Parse the configuration file. |
| 98 | //! @param configFile - configuration file |
| 99 | //! @return configuration data |
| 100 | static utility::json::JSON parseConfigFile(const std::string_view configFile); |
| 101 | //! @brief Verify the configuration data. |
| 102 | //! @param configData - configuration data |
| 103 | static void verifyConfigData(const utility::json::JSON& configData); |
| 104 | //! @brief Check the object in the helper list. |
| 105 | //! @tparam Helper - type of helper |
| 106 | //! @param helper - object of helper |
| 107 | template <typename Helper> |
| 108 | static void checkObjectInHelperList(const utility::json::JSON& helper); |
| 109 | }; |
| 110 | |
| 111 | //! @brief Guard for retrieve configuration. |
| 112 | class Retrieve final |
| 113 | { |
| 114 | public: |
| 115 | //! @brief Construct a new Retrieve object. |
| 116 | //! @param sem - semaphore for configuration access control |
| 117 | explicit Retrieve(std::counting_semaphore<maxAccessLimit>& sem); |
| 118 | //! @brief Destroy the Retrieve object. |
| 119 | ~Retrieve(); |
| 120 | //! @brief Construct a new Retrieve object. |
| 121 | Retrieve(const Retrieve&) = delete; |
| 122 | //! @brief Construct a new Retrieve object. |
| 123 | Retrieve(Retrieve&&) = delete; |
| 124 | //! @brief The operator (=) overloading of Retrieve class. |
| 125 | //! @return reference of the Retrieve object |
| 126 | Retrieve& operator=(const Retrieve&) = delete; |
| 127 | //! @brief The operator (=) overloading of Retrieve class. |
| 128 | //! @return reference of the Retrieve object |
| 129 | Retrieve& operator=(Retrieve&&) = delete; |
| 130 | |
| 131 | //! @brief The operator (/) overloading of Retrieve class. |
| 132 | //! @param field - field name |
| 133 | //! @return const reference of the JSON object |
| 134 | const utility::json::JSON& operator/(const std::string& field) const; |
| 135 | //! @brief The operator (()) overloading of Retrieve class. |
| 136 | //! @return const reference of the JSON object |
| 137 | explicit operator const utility::json::JSON&() const; |
| 138 | |
| 139 | private: |
| 140 | //! @brief Semaphore that controls the maximum access limit. |
| 141 | std::counting_semaphore<maxAccessLimit>& sem; |
| 142 | }; |
| 143 | |
| 144 | extern Retrieve retrieveDataRepo(); |
| 145 | extern utility::json::JSON dumpDefaultConfig(); |
| 146 | extern bool loadSettings(const std::string_view filename = defaultConfigFile); |
| 147 | |
| 148 | //! @brief Configuration details. |
| 149 | namespace detail |
| 150 | { |
| 151 | //! @brief The operator (/) overloading of JSON class. |
| 152 | //! @param json - specific JSON object |
| 153 | //! @param field - field name |
| 154 | //! @return const reference of the JSON object |
| 155 | inline const utility::json::JSON& operator/(const utility::json::JSON& json, const std::string& field) |
| 156 | { |
| 157 | return json.at(key: field); |
| 158 | } |
| 159 | |
| 160 | //! @brief Query the "activateHelper" configuration. |
| 161 | //! @return "activateHelper" configuration |
| 162 | inline bool activateHelper() noexcept |
| 163 | { |
| 164 | return (retrieveDataRepo() / field::activateHelper).asBoolean(); |
| 165 | } |
| 166 | //! @brief Query the "filePath" configuration in the properties of "logger" object of "helpList". |
| 167 | //! @return "filePath" configuration in the properties of "logger" object of "helpList" |
| 168 | inline std::string filePath4Logger() noexcept |
| 169 | { |
| 170 | return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::filePath).asString(); |
| 171 | } |
| 172 | //! @brief Query the "priorityLevel" configuration in the properties of "logger" object of "helpList". |
| 173 | //! @return "priorityLevel" configuration in the properties of "logger" object of "helpList" |
| 174 | inline int priorityLevel4Logger() noexcept |
| 175 | { |
| 176 | return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::priorityLevel) |
| 177 | .asIntegral(); |
| 178 | } |
| 179 | //! @brief Query the "targetType" configuration in the properties of "logger" object of "helpList". |
| 180 | //! @return "targetType" configuration in the properties of "logger" object of "helpList" |
| 181 | inline int targetType4Logger() noexcept |
| 182 | { |
| 183 | return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::targetType) |
| 184 | .asIntegral(); |
| 185 | } |
| 186 | //! @brief Query the "writeMode" configuration in the properties of "logger" object of "helpList". |
| 187 | //! @return "writeMode" configuration in the properties of "logger" object of "helpList" |
| 188 | inline int writeMode4Logger() noexcept |
| 189 | { |
| 190 | return (retrieveDataRepo() / field::helperList / field::logger / field::properties / field::writeMode).asIntegral(); |
| 191 | } |
| 192 | //! @brief Query the "tcpHost" configuration in the properties of "viewer" object of "helpList". |
| 193 | //! @return "tcpHost" configuration in the properties of "viewer" object of "helpList" |
| 194 | inline std::string tcpHost4Viewer() noexcept |
| 195 | { |
| 196 | return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::tcpHost).asString(); |
| 197 | } |
| 198 | //! @brief Query the "tcpPort" configuration in the properties of "viewer" object of "helpList". |
| 199 | //! @return "tcpPort" configuration in the properties of "viewer" object of "helpList" |
| 200 | inline int tcpPort4Viewer() noexcept |
| 201 | { |
| 202 | return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::tcpPort).asIntegral(); |
| 203 | } |
| 204 | //! @brief Query the "udpHost" configuration in the properties of "viewer" object of "helpList". |
| 205 | //! @return "udpHost" configuration in the properties of "viewer" object of "helpList" |
| 206 | inline std::string udpHost4Viewer() noexcept |
| 207 | { |
| 208 | return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::udpHost).asString(); |
| 209 | } |
| 210 | //! @brief Query the "udpPort" configuration in the properties of "viewer" object of "helpList". |
| 211 | //! @return "udpPort" configuration in the properties of "viewer" object of "helpList" |
| 212 | inline int udpPort4Viewer() noexcept |
| 213 | { |
| 214 | return (retrieveDataRepo() / field::helperList / field::viewer / field::properties / field::udpPort).asIntegral(); |
| 215 | } |
| 216 | //! @brief Query the "helperTimeout" configuration. |
| 217 | //! @return "helperTimeout" configuration |
| 218 | inline int helperTimeout() noexcept |
| 219 | { |
| 220 | return (retrieveDataRepo() / field::helperTimeout).asIntegral(); |
| 221 | } |
| 222 | } // namespace detail |
| 223 | |
| 224 | //! @brief Activity configuration applied to tasks. |
| 225 | namespace task |
| 226 | { |
| 227 | //! @brief Alias for the memory pool for task when making multi-threading. |
| 228 | using ResourcePool = utility::memory::Memory<utility::thread::Thread>; |
| 229 | extern ResourcePool& resourcePool(); |
| 230 | //! @brief Preset full name for the task. |
| 231 | //! @param cli - sub-cli name |
| 232 | //! @param cat - category name |
| 233 | //! @param cho - choice name |
| 234 | //! @return full name |
| 235 | inline std::string presetName(const std::string_view cli, const std::string_view cat, const std::string_view cho) |
| 236 | { |
| 237 | return '@' + std::string{cli} + '_' + std::string{cat} + '_' + std::string{cho}; |
| 238 | } |
| 239 | } // namespace task |
| 240 | } // namespace configure |
| 241 | } // namespace application |
| 242 | |