ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
ConfigReader.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#pragma once
4
66#include "ApplicationModule.h"
67#include "ArrayAccessor.h"
68#include "ScalarAccessor.h"
69
70#include <ChimeraTK/SupportedUserTypes.h>
71
72#include <map>
73#include <unordered_map>
74#include <utility>
75
76namespace ChimeraTK {
77
78 struct FunctorFill;
79 struct ArrayFunctorFill;
80 struct FunctorSetValues;
81 struct FunctorSetValuesArray;
82 class ModuleTree;
83
112 public:
113 ConfigReader(ModuleGroup* owner, const std::string& name, const std::string& fileName,
114 const std::unordered_set<std::string>& tags = {});
115 ~ConfigReader() override;
116
117 void mainLoop() override {}
118 void prepare() override;
119
125 template<typename T>
126 const T& get(std::string variableName) const;
127
132 template<typename T>
133 const T& get(std::string variableName, const T& defaultValue) const;
134
139 std::list<std::string> getModules(const std::string& path = {}) const;
140
141 protected:
143 void construct(const std::string& fileName);
144
146 std::string _fileName;
147
149 std::unique_ptr<ModuleTree> _moduleTree;
150
152 void parsingError(const std::string& message) noexcept;
153
155 template<typename T>
156 struct Var {
157 Var(Module* owner, const std::string& name, T theValue)
158 : accessor(owner, name, "unknown", "Configuration variable"), value(std::move(theValue)) {}
159
160 Var() = default;
161
163 T value{};
164 };
165
167 template<typename T>
168 struct Array {
169 Array(Module* owner, const std::string& name, const std::vector<T>& theValue)
170 : accessor(owner, name, "unknown", theValue.size(), "Configuration array"), value(theValue) {}
171
172 Array() = default;
173
175 std::vector<T> value;
176 };
177
179 template<typename T>
180 void createVar(const std::string& name, const std::string& value);
181
183 template<typename T>
184 void createArray(const std::string& name, const std::map<size_t, std::string>& values);
185
188 [[nodiscard]] bool checkVariable(std::string const& name, std::string const& type) const;
189
192 [[nodiscard]] bool checkArray(std::string const& name, std::string const& type) const;
193
196 template<typename T>
197 using MapOfVar = std::unordered_map<std::string, Var<T>>;
198
200 ChimeraTK::TemplateUserTypeMapNoVoid<MapOfVar> _variableMap;
201
204 template<typename T>
205 using MapOfArray = std::unordered_map<std::string, Array<T>>;
206
208 ChimeraTK::TemplateUserTypeMapNoVoid<MapOfArray> _arrayMap;
209
211 ChimeraTK::SingleTypeUserTypeMapNoVoid<const char*> _typeMap{"int8", "uint8", "int16", "uint16", "int32", "uint32",
212 "int64", "uint64", "float", "double", "string", "boolean"};
213
219 template<typename T>
220 std::optional<const T*> getImpl(const std::string& variableName, T*) const;
221
222 template<typename T>
223 std::optional<const std::vector<T>*> getImpl(const std::string& variableName, std::vector<T>*) const;
224
225 friend struct FunctorFill;
226 friend struct ArrayFunctorFill;
227 friend struct FunctorSetValues;
230 };
231
232 /********************************************************************************************************************/
233 /********************************************************************************************************************/
234
235 template<typename T>
236 const T& ConfigReader::get(std::string variableName, const T& defaultValue) const {
237 if(variableName.starts_with("/")) {
238 variableName = variableName.substr(1);
239 }
240 auto result = getImpl(variableName, static_cast<T*>(nullptr));
241 return *(result.value_or(&defaultValue));
242 }
243
244 /********************************************************************************************************************/
245 /********************************************************************************************************************/
246
247 template<typename T>
248 const T& ConfigReader::get(std::string variableName) const {
249 if(variableName.starts_with("/")) {
250 variableName = variableName.substr(1);
251 }
252 auto result = getImpl(variableName, static_cast<T*>(nullptr));
253 if(!result.has_value()) {
254 auto msg = "ConfigReader: Cannot find configuration variable of the name '" + variableName +
255 "' in the config file '" + _fileName + "'.";
256 std::cerr << msg << std::endl;
257 throw(ChimeraTK::logic_error(msg));
258 }
259 return *(result.value());
260 }
261
262 /********************************************************************************************************************/
263 /********************************************************************************************************************/
264
265 template<typename T>
266 std::optional<const T*> ConfigReader::getImpl(const std::string& variableName, T*) const {
267 bool exists = checkVariable(variableName, boost::fusion::at_key<T>(_typeMap));
268 if(!exists) {
269 return {};
270 }
271 return &(boost::fusion::at_key<T>(_variableMap.table).at(variableName).value);
272 }
273
274 /********************************************************************************************************************/
275 /********************************************************************************************************************/
276
277 template<typename T>
278 std::optional<const std::vector<T>*> ConfigReader::getImpl(const std::string& variableName, std::vector<T>*) const {
279 bool exists = checkArray(variableName, boost::fusion::at_key<T>(_typeMap));
280 if(!exists) {
281 return {};
282 }
283 return &(boost::fusion::at_key<T>(_arrayMap.table).at(variableName).value);
284 }
285
286} // namespace ChimeraTK
Generic module to read an XML config file and provide the defined values as constant variables.
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
void createVar(const std::string &name, const std::string &value)
Create an instance of Var<T> and place it on the variableMap.
std::list< std::string > getModules(const std::string &path={}) const
Returns a list of names of modules which are direct children of path.
std::optional< const T * > getImpl(const std::string &variableName, T *) const
Implementation of get() which can be overloaded for scalars and vectors.
bool checkVariable(std::string const &name, std::string const &type) const
Check if variable exists in the config and if type of var name in the config file matches the given t...
std::string _fileName
File name.
std::unique_ptr< ModuleTree > _moduleTree
List to hold VariableNodes corresponding to xml modules.
bool checkArray(std::string const &name, std::string const &type) const
Check if array exists in the config and if type of array name in the config file matches the given ty...
void prepare() override
Prepare the execution of the module.
std::unordered_map< std::string, Array< T > > MapOfArray
Define type for map of std::string to Array, so we can put it into the TemplateUserTypeMap.
ChimeraTK::TemplateUserTypeMapNoVoid< MapOfArray > _arrayMap
Type-depending map of vectors of arrays.
void construct(const std::string &fileName)
Helper function to avoid code duplication in constructors.
ChimeraTK::SingleTypeUserTypeMapNoVoid< const char * > _typeMap
Map assigning string type identifyers to C++ types.
ChimeraTK::TemplateUserTypeMapNoVoid< MapOfVar > _variableMap
Type-depending map of vectors of variables.
std::unordered_map< std::string, Var< T > > MapOfVar
Define type for map of std::string to Var, so we can put it into the TemplateUserTypeMap.
const T & get(std::string variableName) const
Get value for given configuration variable.
void createArray(const std::string &name, const std::map< size_t, std::string > &values)
Create an instance of Array<T> and place it on the arrayMap.
void parsingError(const std::string &message) noexcept
throw a parsing error with more information
Base class for ApplicationModule and DeviceModule, to have a common interface for these module types.
Definition Module.h:21
InvalidityTracer application module.
Functor to fill variableMap for arrays.
Convenience class for output array accessors (always UpdateMode::push)
Class holding the values and the accessor for one configuration array.
Array(Module *owner, const std::string &name, const std::vector< T > &theValue)
Class holding the value and the accessor for one configuration variable.
Var(Module *owner, const std::string &name, T theValue)
Functor to fill variableMap.
Functor to set values to the array accessors.
Functor to set values to the scalar accessors.
Convenience class for output scalar accessors (always UpdateMode::push)