You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Currently, each caller to cfg_get sets it's own defaults. This makes it difficult to gather information about running configurations, since there is no single source that sets the default configuration and it could get messy if two callers are setting their own defaults.
The idea is that each executable that uses the common library configuration portion sets all configuration options on startup and including the defaults as well. This way, the caller won't have to worry about defaults at all (unless it specifically wants to).
#pragma once
#include"common/platform.h"
#include<cstdint>
#include<memory>
#include<sstream>
#include<string>
#include"common/cfg.h"/// Abstract base class for configuration options./// Used to trick the compiler into allowing a map of different types of/// templated options.classOptionBase {
public:/// Default constructor.explicitOptionBase(std::string name) : name_(std::move(name)) {}
/// Copy and move constructors and assignment operators.OptionBase(const OptionBase &) = delete;
OptionBase(OptionBase &&) = delete;
OptionBase &operator=(const OptionBase &) = delete;
OptionBase &operator=(OptionBase &&) = delete;
/// Default virtual destructor, needed for polymorphism.virtual~OptionBase() = default;
/// Get the name of the option.
std::string getName() const { return name_; }
/// Should return an string representation of the option.virtual std::string toString() const = 0;
private:/// The name of the option.
std::string name_;
};
template<typename T>
classGenericOption : publicOptionBase {
public:/// Constructor with parameters.GenericOption(std::string name, T defaultValue)
: OptionBase(std::move(name)),
defaultValue_(defaultValue),
value_(defaultValue_) {}
/// Default constructor.GenericOption() = delete;
/// Not needed constructors/assignment operators.GenericOption(const GenericOption &) = delete;
GenericOption(GenericOption &&) = delete;
GenericOption &operator=(const GenericOption &) = delete;
GenericOption &operator=(GenericOption &&) = delete;
/// Default virtual destructor, needed for polymorphism.virtual~GenericOption() = default;
/// Should update the value of the option from the configuration file using/// the concrete type.virtualvoidupdateValueFromFile() = 0;
/// Get the value of the option.
T getValue() const { return value_; }
/// Set the value of the option.voidsetValue(T newValue) {
value_ = newValue;
}
/// Get the default value of the option.
T getDefaultValue() const { return defaultValue_; }
/// Returns an string representation of the option.
std::string toString() constoverride {
std::stringstream result;
result << getName() << " = " << value_
<< "; // Default: " << defaultValue_;
return result.str();
}
private:/// The default value of the option.
T defaultValue_;
/// The value of the option.
T value_;
};
/// Specialization of GenericOption to handle uint32_tclassOptionUint32 : publicGenericOption<uint32_t> {
public:OptionUint32(std::string name, uint32_t defaultValue)
: GenericOption<uint32_t>(std::move(name), defaultValue) {}
voidupdateValueFromFile() override {
auto val = cfg_getuint32(getName().c_str(), getDefaultValue());
setValue(val);
}
};
/// Specialization of GenericOption to handle std::stringclassOptionString : publicGenericOption<std::string> {
public:OptionString(std::string name, std::string defaultValue)
: GenericOption<std::string>(std::move(name), std::move(defaultValue)) {
}
voidupdateValueFromFile() override {
auto *val = cfg_getstr(getName().c_str(), getDefaultValue().c_str());
setValue(val);
}
};
// The rest of the concrete options should be added here until we move them to// their own file. Some of them will be: OptionDouble, OptionRanged, etc../// Singleton class to store configuration parameters./// All the calls to the cfg_get* functions should be replaced by calls to the/// getOption method of this class. This way, the map will contain the actual/// effective value of the options in a single place per module.classConfiguration {
public:/// Get the instance of the Configuration class.static Configuration& instance() {
static Configuration instance;
return instance;
}
// Not needed methodsConfiguration(const Configuration &) = delete;
Configuration &operator=(const Configuration &) = delete;
Configuration(Configuration &&) = delete;
Configuration &operator=(Configuration &&) = delete;
/// Default destructor~Configuration() = default;
/// Retrieves an option from the configuration file as uint32_t./// \param optionName The name of the option to retrieve./// In the future, the option will be cached and only read from the file/// once, unless reaload is requested.template<typename T>
autogetOption(const std::string &name) {
// Make sure the option existsassert(options_.find(name) != options_.end());
// Cast to the concrete typeauto option = static_cast<GenericOption<T> *>(options_.at(name).get());
// Update the value (always until we have add support for reload option)
option->updateValueFromFile();
return option->getValue();
}
/// Adds an option to the map. All options should be added at start time./// \param option The option to add.voidaddOption(std::shared_ptr<OptionBase> &option) {
if (options_.find(option->getName()) != options_.end()) {
safs_pretty_syslog(LOG_WARNING,
"Option %s already exists in the configuration",
option->getName().c_str());
return;
}
options_.insert({option->getName(), option});
}
/// Prints all the configurations options using safs_pretty_syslog./// Used only for debugging purposes (GUILLEX remove later).voidprintAllOptions() const {
safs_pretty_syslog(LOG_NOTICE, "Configuration options:");
for (constauto &option : options_) {
safs_pretty_syslog(LOG_NOTICE, "%s", option.second->toString().c_str());
}
}
private:/// Private constructor for the singleton patternConfiguration() = default;
/// Map with all the configuration options.
std::map<std::string, std::shared_ptr<OptionBase>> options_;
};
The text was updated successfully, but these errors were encountered:
Currently, each caller to cfg_get sets it's own defaults. This makes it difficult to gather information about running configurations, since there is no single source that sets the default configuration and it could get messy if two callers are setting their own defaults.
The idea is that each executable that uses the common library configuration portion sets all configuration options on startup and including the defaults as well. This way, the caller won't have to worry about defaults at all (unless it specifically wants to).
Related to #13.
An example draft from @lgsilva3087:
The text was updated successfully, but these errors were encountered: