21#include "execution_time_estimator.h"
23#include <core/exception.h>
24#include <utils/misc/string_split.h>
110 const ::std::string &cfg_prefix)
112 cfg_prefix_(cfg_prefix),
113 speed_(config->get_float_or_default((cfg_prefix_ +
"speed").c_str(), 1)),
114 whitelist_(get_skills_from_config(cfg_prefix_ +
"whitelist")),
115 blacklist_(get_skills_from_config(cfg_prefix_ +
"blacklist"))
123 bool allowed_to_execute =
false;
125 allowed_to_execute =
true;
130 return skill.matches(s.second);
140 return skill.matches(s.second);
152 std::string skill_no_newlines(skill_string);
153 skill_no_newlines.erase(std::remove(skill_no_newlines.begin(), skill_no_newlines.end(),
'\n'),
154 skill_no_newlines.end());
155 if (skill_no_newlines.empty()) {
158 const std::regex regex(
"(\\w+)(?:\\(\\)|\\{(.+)?\\})");
160 if (std::regex_match(skill_no_newlines, match, regex)) {
161 assert(match.size() > 1);
163 if (match.size() > 2) {
164 const std::string args = match[2];
168 throw Exception(
"Unexpected skill string: '%s'", skill_no_newlines.c_str());
175 bool args_match =
true;
179 || !std::regex_match(search_arg->second, std::regex(arg.second))) {
188Skill::parse_args(
const std::string &args)
190 const std::regex skill_args_regex(
"(?:([^,]+),\\s*)*?([^,]+)");
191 std::smatch args_match;
192 if (std::regex_match(args, args_match, skill_args_regex)) {
193 const std::regex skill_arg_regex(
"(\\w+)=(['\"]?)([^'\"]*)\\2\\s*");
194 for (
auto kv_match = std::next(args_match.begin()); kv_match != args_match.end(); kv_match++) {
195 const std::string key_arg = *kv_match;
197 if (std::regex_match(key_arg, m, skill_arg_regex)) {
204std::map<std::string, Skill>
207 const size_t id_index = 0;
208 const size_t property_index = 1;
209 std::unique_ptr<Configuration::ValueIterator> it(
config_->
search(path.c_str()));
210 std::map<std::string, std::string> skill_strings;
212 std::vector<std::string> skill_property =
213 str_split(std::string(it->path()).substr(path.size()));
214 if (skill_property.size() != 2) {
217 if (skill_property[property_index] ==
"args") {
218 skill_strings[skill_property[id_index]] +=
str_join(it->get_strings(),
',');
219 }
else if (skill_property[property_index] ==
"name") {
220 skill_strings[skill_property[id_index]] =
221 it->get_string() +
"{" + skill_strings[skill_property[id_index]];
224 std::map<std::string, Skill> res;
225 for (
const auto &skill_string : skill_strings) {
226 res.insert(std::make_pair(skill_string.first,
Skill(skill_string.second +
"}")));
236 return property.get_default_value();
245 const std::string & path,
246 const std::string & property,
247 const std::optional<T> &default_val)
250 if constexpr (std::is_same<T, std::string>()) {
251 default_value = config->
get_string((path + property).c_str());
252 }
else if constexpr (std::is_same<T, float>()) {
253 default_value = config->
get_float((path + property).c_str());
254 }
else if constexpr (std::is_same<T, bool>()) {
255 default_value = config->
get_bool((path + property).c_str());
258 "Property with this template type is not implemented");
261 default_value = default_val;
263 const size_t id_index = 0;
264 const size_t property_index = 1;
265 std::string whitelist_path = path +
"whitelist";
266 std::unique_ptr<Configuration::ValueIterator> it(config->
search(whitelist_path.c_str()));
268 std::vector<std::string> skill_property =
269 str_split(std::string(it->path()).substr(whitelist_path.size()));
270 if (skill_property.size() != 2) {
273 if (skill_property[property_index] == property) {
274 if constexpr (std::is_same<T, std::string>()) {
275 property_entries[skill_property[id_index]] += it->get_string();
276 }
else if constexpr (std::is_same<T, float>()) {
277 property_entries[skill_property[id_index]] += it->get_float();
278 }
else if constexpr (std::is_same<T, bool>()) {
279 property_entries[skill_property[id_index]] += it->get_bool();
282 "Property with this template type is not implemented");
293 return default_value.value();
295 throw Exception(
"failed to get property");
303 auto property_specified = property_entries.find(key);
304 if (property_specified == property_entries.end()) {
305 return get_default_value();
307 return property_specified->second;
Interface for configuration handling.
virtual bool get_bool(const char *path)=0
Get value from configuration which is of type bool.
virtual float get_float(const char *path)=0
Get value from configuration which is of type float.
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
virtual std::string get_string(const char *path)=0
Get value from configuration which is of type string.
Base class for exceptions in Fawkes.
A configurable property that is skill-specific and may have a default value.
Property(fawkes::Configuration *config, const std::string &path, const std::string &property, const std::optional< T > &default_value=std::nullopt)
Constructor.
T get_property(const std::string &key) const
Get the property falue for a given skill.
T get_default_value() const
Get the default value if it is set, otherwise throw an exception.
A structured representation of a skill.
bool matches(const Skill &skill) const
Check, whether the skill matches another skill description.
std::string skill_name
The name of the skill.
Skill(const std::string &skill_string)
Constructor.
std::unordered_map< std::string, std::string > skill_args
A map of the skill's argument keys to argument values.
virtual bool can_provide_exec_time(const Skill &skill) const =0
Check if this estimator can give an estimate for a given skill.
Configuration *const config_
Config to obtain common configurables.
std::map< std::string, Skill >::const_iterator active_whitelist_entry_
Points to the whitelist entry that matches the skill to execute.
const std::map< std::string, Skill > blacklist_
Blacklist of skills that the estimator must not process.
virtual bool can_execute(const Skill &skill)
Check if this estimator is both allowed and able to give an estimate for a given skill.
const std::map< std::string, Skill > whitelist_
Whitelist of skills that the estimator is allowed to process.
T get_property(const Property< T > &property) const
Get the current property value for active_whitelist_entry_.
std::map< std::string, Skill > get_skills_from_config(const std::string &path) const
Load skill descriptions from a yaml config.
ExecutionTimeEstimator(Configuration *config, const ::std::string &cfg_prefix)
Constructor.
const float speed_
Config estimator-specific speedup factor.
Fawkes library namespace.
static std::string str_join(const std::vector< std::string > &v, char delim='/')
Join vector of strings string using given delimiter.
static std::vector< std::string > str_split(const std::string &s, char delim='/')
Split string by delimiter.