Skip to content
Snippets Groups Projects
Commit 76cddf9d authored by vargheseg's avatar vargheseg
Browse files

Introduced class ModuleList

ModuleList serves as a container for VariableGroups. The VariableGroups
mirror xml modules in the config file.
parent 80e8fe2e
No related branches found
No related tags found
No related merge requests found
...@@ -13,6 +13,7 @@ namespace ChimeraTK { ...@@ -13,6 +13,7 @@ namespace ChimeraTK {
struct ArrayFunctorFill; struct ArrayFunctorFill;
struct FunctorSetValues; struct FunctorSetValues;
struct FunctorSetValuesArray; struct FunctorSetValuesArray;
class ModuleList;
/** Generic module to read an XML config file and provide the defined values as /** Generic module to read an XML config file and provide the defined values as
* constant variables. The config file should look like this: * constant variables. The config file should look like this:
...@@ -45,6 +46,7 @@ namespace ChimeraTK { ...@@ -45,6 +46,7 @@ namespace ChimeraTK {
ConfigReader(EntityOwner* owner, const std::string& name, const std::string& fileName, ConfigReader(EntityOwner* owner, const std::string& name, const std::string& fileName,
const std::unordered_set<std::string>& tags = {}); const std::unordered_set<std::string>& tags = {});
~ConfigReader() override;
void mainLoop() override {} void mainLoop() override {}
void prepare() override; void prepare() override;
...@@ -56,9 +58,12 @@ namespace ChimeraTK { ...@@ -56,9 +58,12 @@ namespace ChimeraTK {
const T& get(const std::string& variableName) const; const T& get(const std::string& variableName) const;
protected: protected:
/** File name */ /** File name */
std::string _fileName; std::string _fileName;
std::unique_ptr<ModuleList> _moduleList;
/** throw a parsing error with more information */ /** throw a parsing error with more information */
void parsingError(const std::string& message); void parsingError(const std::string& message);
...@@ -118,6 +123,7 @@ namespace ChimeraTK { ...@@ -118,6 +123,7 @@ namespace ChimeraTK {
template<typename T> template<typename T>
const std::vector<T>& get_impl(const std::string& variableName, std::vector<T>*) const; const std::vector<T>& get_impl(const std::string& variableName, std::vector<T>*) const;
friend struct FunctorFill; friend struct FunctorFill;
friend struct ArrayFunctorFill; friend struct ArrayFunctorFill;
friend struct FunctorSetValues; friend struct FunctorSetValues;
......
#include <libxml++/libxml++.h> #include <libxml++/libxml++.h>
#include "ConfigReader.h" #include "ConfigReader.h"
#include<iostream>
namespace ChimeraTK { namespace ChimeraTK {
...@@ -14,6 +15,9 @@ void prefix(std::string s, List& varList){ ...@@ -14,6 +15,9 @@ void prefix(std::string s, List& varList){
} }
} }
std::string parent(std::string flattened_name);
std::string leaf(std::string flattened_name);
struct Variable { struct Variable {
std::string name; std::string name;
std::string type; std::string type;
...@@ -58,62 +62,78 @@ private: ...@@ -58,62 +62,78 @@ private:
std::map<size_t, std::string> gettArrayValues(const xmlpp::Element * element); std::map<size_t, std::string> gettArrayValues(const xmlpp::Element * element);
}; };
class ModuleList {
std::unordered_map<std::string, ChimeraTK::VariableGroup> map_;
ChimeraTK::Module* owner_;
/*********************************************************************************************************************/ public:
ModuleList(ChimeraTK::Module* o):owner_(o){}
ChimeraTK::Module *lookup(std::string flattened_module_name);
ChimeraTK::Module *get(std::string flattened_name);
};
/** Functor to fill variableMap */ /*********************************************************************************************************************/
struct FunctorFill {
FunctorFill(ConfigReader* owner, const std::string& type, const std::string& name, const std::string& value,
bool& processed)
: _owner(owner), _type(type), _name(name), _value(value), _processed(processed) {}
template<typename PAIR> /** Functor to fill variableMap */
void operator()(PAIR&) const { struct FunctorFill {
// extract the user type from the pair FunctorFill(ConfigReader *owner, const std::string &type,
typedef typename PAIR::first_type T; const std::string &name, const std::string &value,
bool &processed)
: _owner(owner), _type(type), _name(name), _value(value),
_processed(processed) {}
// skip this type, if not matching the type string in the config file template <typename PAIR> void operator()(PAIR &) const {
if(_type != boost::fusion::at_key<T>(_owner->typeMap)) return; // extract the user type from the pair
typedef typename PAIR::first_type T;
_owner->createVar<T>(_name, _value); // skip this type, if not matching the type string in the config file
_processed = true; if (_type != boost::fusion::at_key<T>(_owner->typeMap))
} return;
ConfigReader* _owner; _owner->createVar<T>(_name, _value);
const std::string &_type, &_name, &_value; _processed = true;
bool& _processed; // must be a non-const reference, since we want to return }
// this to the caller
ConfigReader *_owner;
const std::string &_type, &_name, &_value;
bool &_processed; // must be a non-const reference, since we want to return
// this to the caller
typedef boost::fusion::pair<std::string, ConfigReader::Var<std::string>> StringPair; typedef boost::fusion::pair<std::string, ConfigReader::Var<std::string>>
StringPair;
}; };
/*********************************************************************************************************************/ /*********************************************************************************************************************/
/** Functor to fill variableMap for arrays */ /** Functor to fill variableMap for arrays */
struct ArrayFunctorFill { struct ArrayFunctorFill {
ArrayFunctorFill(ConfigReader* owner, const std::string& type, const std::string& name, ArrayFunctorFill(ConfigReader *owner, const std::string &type,
const std::map<size_t, std::string>& values, bool& processed) const std::string &name,
: _owner(owner), _type(type), _name(name), _values(values), _processed(processed) {} const std::map<size_t, std::string> &values,
bool &processed)
template<typename PAIR> : _owner(owner), _type(type), _name(name), _values(values),
void operator()(PAIR&) const { _processed(processed) {}
template <typename PAIR> void operator()(PAIR &) const {
// extract the user type from the pair // extract the user type from the pair
typedef typename PAIR::first_type T; typedef typename PAIR::first_type T;
// skip this type, if not matching the type string in the config file // skip this type, if not matching the type string in the config file
if(_type != boost::fusion::at_key<T>(_owner->typeMap)) return; if (_type != boost::fusion::at_key<T>(_owner->typeMap))
return;
_owner->createArray<T>(_name, _values); _owner->createArray<T>(_name, _values);
_processed = true; _processed = true;
} }
ConfigReader* _owner; ConfigReader *_owner;
const std::string &_type, &_name; const std::string &_type, &_name;
const std::map<size_t, std::string>& _values; const std::map<size_t, std::string> &_values;
bool& _processed; // must be a non-const reference, since we want to return bool &_processed; // must be a non-const reference, since we want to return
// this to the caller // this to the caller
typedef boost::fusion::pair<std::string, ConfigReader::Var<std::string>> StringPair; typedef boost::fusion::pair<std::string, ConfigReader::Var<std::string>>
StringPair;
}; };
/*********************************************************************************************************************/ /*********************************************************************************************************************/
...@@ -134,8 +154,11 @@ private: ...@@ -134,8 +154,11 @@ private:
} }
// place the variable onto the vector // place the variable onto the vector
auto moduleName = parent(name);
auto varName = leaf(name);
auto varOwner = _moduleList->lookup(moduleName);
std::map<std::string, ConfigReader::Var<T>>& theMap = boost::fusion::at_key<T>(variableMap.table); std::map<std::string, ConfigReader::Var<T>>& theMap = boost::fusion::at_key<T>(variableMap.table);
theMap.emplace(std::make_pair(name, ConfigReader::Var<T>(this, name, convertedValue))); theMap.emplace(std::make_pair(name, ConfigReader::Var<T>(varOwner, varName, convertedValue)));
} }
/*********************************************************************************************************************/ /*********************************************************************************************************************/
...@@ -143,9 +166,11 @@ private: ...@@ -143,9 +166,11 @@ private:
template<> template<>
void ConfigReader::createVar<std::string>(const std::string& name, const std::string& value) { void ConfigReader::createVar<std::string>(const std::string& name, const std::string& value) {
// place the variable onto the vector // place the variable onto the vector
std::map<std::string, ConfigReader::Var<std::string>>& theMap = auto moduleName = parent(name);
boost::fusion::at_key<std::string>(variableMap.table); auto varName = leaf(name);
theMap.emplace(std::make_pair(name, ConfigReader::Var<std::string>(this, name, value))); auto varOwner = _moduleList->lookup(moduleName);
std::map<std::string, ConfigReader::Var<std::string>>& theMap = boost::fusion::at_key<std::string>(variableMap.table);
theMap.emplace(std::make_pair(name, ConfigReader::Var<std::string>(varOwner, varName, value)));
} }
/*********************************************************************************************************************/ /*********************************************************************************************************************/
...@@ -183,8 +208,12 @@ private: ...@@ -183,8 +208,12 @@ private:
} }
// place the variable onto the vector // place the variable onto the vector
auto module_name = parent(name);
auto array_name = leaf(name);
auto arrayOwner = _moduleList->lookup(module_name);
std::map<std::string, ConfigReader::Array<T>>& theMap = boost::fusion::at_key<T>(arrayMap.table); std::map<std::string, ConfigReader::Array<T>>& theMap = boost::fusion::at_key<T>(arrayMap.table);
theMap.emplace(std::make_pair(name, ConfigReader::Array<T>(this, name, Tvalues))); theMap.emplace(std::make_pair( name, ConfigReader::Array<T>(arrayOwner, array_name, Tvalues)));
} }
/*********************************************************************************************************************/ /*********************************************************************************************************************/
...@@ -208,16 +237,19 @@ private: ...@@ -208,16 +237,19 @@ private:
} }
// place the variable onto the vector // place the variable onto the vector
std::map<std::string, ConfigReader::Array<std::string>>& theMap = auto module_name = parent(name);
boost::fusion::at_key<std::string>(arrayMap.table); auto array_name = leaf(name);
theMap.emplace(std::make_pair(name, ConfigReader::Array<std::string>(this, name, Tvalues))); auto arrayOwner = _moduleList->lookup(module_name);
std::map<std::string, ConfigReader::Array<std::string>>& theMap = boost::fusion::at_key<std::string>(arrayMap.table);
theMap.emplace(std::make_pair( name, ConfigReader::Array<std::string>(arrayOwner, array_name, Tvalues)));
} }
/*********************************************************************************************************************/ /*********************************************************************************************************************/
ConfigReader::ConfigReader(EntityOwner* owner, const std::string& name, const std::string& fileName, const std::unordered_set<std::string>& tags) ConfigReader::ConfigReader(EntityOwner* owner, const std::string& name, const std::string& fileName, const std::unordered_set<std::string>& tags)
: ApplicationModule(owner, name, "Configuration read from file '" + fileName + "'", false, tags), : ApplicationModule(owner, name, "Configuration read from file '" + fileName + "'", false, tags),
_fileName(fileName) { _fileName(fileName), _moduleList(std::make_unique<ModuleList>(this)) {
auto fillVariableMap = [this](const Variable &var) { auto fillVariableMap = [this](const Variable &var) {
bool processed{false}; bool processed{false};
...@@ -254,6 +286,7 @@ private: ...@@ -254,6 +286,7 @@ private:
} }
} }
ConfigReader::~ConfigReader() = default;
/********************************************************************************************************************/ /********************************************************************************************************************/
void ConfigReader::parsingError(const std::string& message) { void ConfigReader::parsingError(const std::string& message) {
...@@ -315,6 +348,37 @@ private: ...@@ -315,6 +348,37 @@ private:
/*********************************************************************************************************************/ /*********************************************************************************************************************/
ChimeraTK::Module *ModuleList::lookup(std::string flattened_module_name) {
return get(flattened_module_name);
}
ChimeraTK::Module *ModuleList::get(std::string flattened_name) {
if (flattened_name == "") {
return owner_;
}
auto e = map_.find(flattened_name);
if (e == map_.end()) {
auto module_name = leaf(flattened_name);
auto owner = get(parent(flattened_name));
map_[flattened_name] = ChimeraTK::VariableGroup(owner, module_name, "");
return &map_[flattened_name];
}
return &e->second;
}
std::string parent(std::string flattened_name) {
auto pos = flattened_name.find_last_of('/');
pos = (pos == std::string::npos) ? 0 : pos;
return flattened_name.substr(0, pos);
}
std::string leaf(std::string flattened_name) {
auto pos = flattened_name.find_last_of('/');
return flattened_name.substr(pos + 1, flattened_name.size());
}
std::unique_ptr<VariableList> ConfigParser::getVariableList() { std::unique_ptr<VariableList> ConfigParser::getVariableList() {
if (variableList_ == nullptr) { if (variableList_ == nullptr) {
std::tie(variableList_, arrayList_) = parse(); std::tie(variableList_, arrayList_) = parse();
...@@ -340,9 +404,10 @@ std::tuple<std::unique_ptr<VariableList>, std::unique_ptr<ArrayList>> ConfigPars ...@@ -340,9 +404,10 @@ std::tuple<std::unique_ptr<VariableList>, std::unique_ptr<ArrayList>> ConfigPars
std::tuple<std::unique_ptr<VariableList>, std::unique_ptr<ArrayList>> std::tuple<std::unique_ptr<VariableList>, std::unique_ptr<ArrayList>>
ConfigParser::parseModule(const xmlpp::Element * element) { ConfigParser::parseModule(const xmlpp::Element * element) {
auto module_name = (element->get_name() == "configuration")? auto module_name = (element->get_name() == "configuration")
"": ? ""
element->get_name() + "/"; : element->get_attribute("name")->get_value() + "/";
auto v = std::make_unique<VariableList>(); auto v = std::make_unique<VariableList>();
auto a = std::make_unique<ArrayList>(); auto a = std::make_unique<ArrayList>();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment