Fawkes API  Fawkes Development Version
feature_config.cpp
1 
2 /***************************************************************************
3  * feature_config.cpp - CLIPS config feature
4  *
5  * Created: Sun Oct 06 13:08:00 2013
6  * Copyright 2006-2013 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU Library General Public License for more details.
19  *
20  * Read the full text in the LICENSE.GPL file in the doc directory.
21  */
22 
23 #include "feature_config.h"
24 
25 #include <config/config.h>
26 #include <core/threading/mutex_locker.h>
27 #include <logging/logger.h>
28 #include <utils/misc/string_split.h>
29 
30 #include <clipsmm.h>
31 #include <iomanip>
32 #include <sstream>
33 
34 using namespace fawkes;
35 
36 /** @class ConfigCLIPSFeature "feature_blackboard.h"
37  * CLIPS blackboard feature.
38  * @author Tim Niemueller
39  */
40 
41 /** Constructor.
42  * @param logger message logger
43  * @param config configuration to use for CLIPS commands
44  */
46 : CLIPSFeature("config"), logger_(logger), config_(config)
47 {
48 }
49 
50 /** Destructor. */
52 {
53  envs_.clear();
54 }
55 
56 void
57 ConfigCLIPSFeature::clips_context_init(const std::string & env_name,
59 {
60  envs_[env_name] = clips;
61  clips->evaluate("(path-load \"ff-config.clp\")");
62  clips->add_function("config-load",
63  sigc::slot<void, std::string>(
64  sigc::bind<0>(sigc::mem_fun(*this, &ConfigCLIPSFeature::clips_config_load),
65  env_name)));
66 }
67 
68 void
69 ConfigCLIPSFeature::clips_context_destroyed(const std::string &env_name)
70 {
71  envs_.erase(env_name);
72 }
73 
74 void
75 ConfigCLIPSFeature::clips_config_load(std::string env_name, std::string cfg_prefix)
76 {
77  std::string name = "ClipsConfig|" + env_name;
78 
79  if (envs_.find(env_name) == envs_.end()) {
80  logger_->log_warn(name.c_str(),
81  "Environment %s has not been registered "
82  "for config feature",
83  env_name.c_str());
84  return;
85  }
86 
87  fawkes::MutexLocker lock(envs_[env_name].objmutex_ptr());
88 #if __cplusplus >= 201103L
89  std::unique_ptr<Configuration::ValueIterator> v(config_->search(cfg_prefix.c_str()));
90 #else
91  std::auto_ptr<Configuration::ValueIterator> v(config_->search(cfg_prefix.c_str()));
92 #endif
93 
94  while (v->next()) {
95  std::string type = "";
96  std::string value = v->get_as_string();
97 
98  if (v->is_uint())
99  type = "UINT";
100  else if (v->is_int())
101  type = "INT";
102  else if (v->is_float())
103  type = "FLOAT";
104  else if (v->is_bool()) {
105  type = "BOOL";
106  value = v->get_bool() ? "TRUE" : "FALSE";
107  } else if (v->is_string()) {
108  type = "STRING";
109  if (!v->is_list()) {
110  std::stringstream escaped_quotes_value;
111  escaped_quotes_value << std::quoted(value);
112  value = escaped_quotes_value.str();
113  } else {
114  std::vector<std::string> strings = v->get_strings();
115  if (!strings.empty()) {
116  for (std::string &s : strings) {
117  std::stringstream escaped_quotes_value;
118  escaped_quotes_value << std::quoted(s);
119  s = escaped_quotes_value.str();
120  }
121  value = str_join(strings, ' ');
122  }
123  }
124  } else {
125  logger_->log_warn(name.c_str(),
126  "Config value at '%s' of unknown type '%s'",
127  v->path(),
128  v->type());
129  }
130 
131  if (v->is_list()) {
132  envs_[env_name]->assert_fact_f("(confval (path \"%s\") (type %s) "
133  "(is-list TRUE) (list-value %s))",
134  v->path(),
135  type.c_str(),
136  value.c_str());
137  } else {
138  envs_[env_name]->assert_fact_f("(confval (path \"%s\") (type %s) (value %s))",
139  v->path(),
140  type.c_str(),
141  value.c_str());
142  }
143  }
144 }
fawkes::str_join
std::string str_join(const InputIterator &first, const InputIterator &last, char delim='/')
Join list of strings string using given delimiter.
Definition: string_split.h:139
fawkes::LockPtr< CLIPS::Environment >
ConfigCLIPSFeature::clips_context_destroyed
virtual void clips_context_destroyed(const std::string &env_name)
Notification that a CLIPS environment has been destroyed.
Definition: feature_config.cpp:69
fawkes::MutexLocker
Mutex locking helper.
Definition: mutex_locker.h:34
ConfigCLIPSFeature::clips_context_init
virtual void clips_context_init(const std::string &env_name, fawkes::LockPtr< CLIPS::Environment > &clips)
Initialize a CLIPS context to use the provided feature.
Definition: feature_config.cpp:57
ConfigCLIPSFeature::ConfigCLIPSFeature
ConfigCLIPSFeature(fawkes::Logger *logger, fawkes::Configuration *config)
Constructor.
Definition: feature_config.cpp:45
fawkes::Configuration
Interface for configuration handling.
Definition: config.h:65
fawkes::Configuration::search
virtual ValueIterator * search(const char *path)=0
Iterator with search results.
ConfigCLIPSFeature::~ConfigCLIPSFeature
virtual ~ConfigCLIPSFeature()
Destructor.
Definition: feature_config.cpp:51
fawkes::Logger
Interface for logging.
Definition: logger.h:42
fawkes
Fawkes library namespace.
fawkes::Logger::log_warn
virtual void log_warn(const char *component, const char *format,...)=0
Log warning message.
fawkes::CLIPSFeature
CLIPS feature maintainer.
Definition: clips_feature.h:42