Fawkes API  Fawkes Development Version
feature_blackboard.cpp
1 
2 /***************************************************************************
3  * feature_blackboard.cpp - CLIPS blackboard feature
4  *
5  * Created: Thu Oct 03 11:48:58 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_blackboard.h"
24 
25 #include <blackboard/blackboard.h>
26 #include <blackboard/exceptions.h>
27 #include <core/threading/mutex_locker.h>
28 #include <interface/interface_info.h>
29 #include <logging/logger.h>
30 #include <utils/misc/string_conversions.h>
31 #include <utils/misc/string_split.h>
32 #include <utils/time/time.h>
33 
34 #include <clipsmm.h>
35 
36 using namespace fawkes;
37 
38 /** @class BlackboardCLIPSFeature "feature_blackboard.h"
39  * CLIPS blackboard feature.
40  * @author Tim Niemueller
41  */
42 
43 /** Constructor.
44  * @param logger message logger
45  * @param blackboard blackboard to use for opening interfaces
46  * @param retract_early Retract blackboard facts at the end of the same
47  * execution cycle they have been asserted in. If false (default),
48  * blackboard facts are only retracted immediately before a new
49  * fact representing a particular interface is asserted.
50  */
52  fawkes::BlackBoard *blackboard,
53  bool retract_early)
54 : CLIPSFeature("blackboard"),
55  logger_(logger),
56  blackboard_(blackboard),
57  cfg_retract_early_(retract_early)
58 {
59 }
60 
61 /** Destructor. */
63 {
64  for (auto &iface_map : interfaces_) {
65  for (auto &iface_list : iface_map.second.reading) {
66  for (auto iface : iface_list.second) {
67  blackboard_->close(iface);
68  }
69  }
70  for (auto &iface_list : iface_map.second.writing) {
71  for (auto iface : iface_list.second) {
72  blackboard_->close(iface);
73  }
74  }
75  }
76  interfaces_.clear();
77  envs_.clear();
78 }
79 
80 void
81 BlackboardCLIPSFeature::clips_context_init(const std::string & env_name,
83 {
84  envs_[env_name] = clips;
85  clips->evaluate("(path-load \"blackboard.clp\")");
86  clips->add_function(
87  "blackboard-enable-time-read",
88  sigc::slot<void>(sigc::bind<0>(
89  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_enable_time_read), env_name)));
90  clips->add_function(
91  "blackboard-open",
92  sigc::slot<void, std::string, std::string>(sigc::bind<0>(
93  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_open_interface_reading),
94  env_name)));
95  clips->add_function(
96  "blackboard-open-reading",
97  sigc::slot<void, std::string, std::string>(sigc::bind<0>(
98  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_open_interface_reading),
99  env_name)));
100  clips->add_function(
101  "blackboard-open-writing",
102  sigc::slot<void, std::string, std::string>(sigc::bind<0>(
103  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_open_interface_writing),
104  env_name)));
105  clips->add_function(
106  "blackboard-close",
107  sigc::slot<void, std::string, std::string>(
108  sigc::bind<0>(sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_close_interface),
109  env_name)));
110  clips->add_function("blackboard-preload",
111  sigc::slot<void, std::string>(sigc::bind<0>(
112  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_preload),
113  env_name)));
114  clips->add_function("blackboard-read",
115  sigc::slot<void>(sigc::bind<0>(
116  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_read),
117  env_name)));
118  clips->add_function("blackboard-write",
119  sigc::slot<void, std::string>(sigc::bind<0>(
120  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_write),
121  env_name)));
122  clips->add_function("blackboard-get-info",
123  sigc::slot<void>(sigc::bind<0>(
124  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_get_info),
125  env_name)));
126  clips->add_function("blackboard-set",
127  sigc::slot<void, std::string, std::string, CLIPS::Value>(sigc::bind<0>(
128  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_set),
129  env_name)));
130  clips->add_function(
131  "blackboard-set-multifield",
132  sigc::slot<void, std::string, std::string, CLIPS::Values>(
133  sigc::bind<0>(sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_set_multifield),
134  env_name)));
135  clips->add_function("blackboard-create-msg",
136  sigc::slot<CLIPS::Value, std::string, std::string>(sigc::bind<0>(
137  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_create_msg),
138  env_name)));
139  clips->add_function(
140  "blackboard-list-msg-fields",
141  sigc::slot<CLIPS::Values, void *>(
142  sigc::bind<0>(sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_list_msg_fields),
143  env_name)));
144  clips->add_function(
145  "blackboard-set-msg-field",
146  sigc::slot<void, void *, std::string, CLIPS::Value>(
147  sigc::bind<0>(sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_set_msg_field),
148  env_name)));
149  clips->add_function("blackboard-set-msg-multifield",
150  sigc::slot<void, void *, std::string, CLIPS::Values>(sigc::bind<0>(
151  sigc::mem_fun(*this,
152  &BlackboardCLIPSFeature::clips_blackboard_set_msg_multifield),
153  env_name)));
154  clips->add_function("blackboard-send-msg",
155  sigc::slot<CLIPS::Value, void *>(sigc::bind<0>(
156  sigc::mem_fun(*this, &BlackboardCLIPSFeature::clips_blackboard_send_msg),
157  env_name)));
158 }
159 
160 void
161 BlackboardCLIPSFeature::clips_context_destroyed(const std::string &env_name)
162 {
163  if (interfaces_.find(env_name) != interfaces_.end()) {
164  for (auto &iface_map : interfaces_[env_name].reading) {
165  for (auto iface : iface_map.second) {
166  logger_->log_debug(("BBCLIPS|" + env_name).c_str(),
167  "Closing reading interface %s",
168  iface->uid());
169  blackboard_->close(iface);
170  }
171  }
172  for (auto &iface_map : interfaces_[env_name].writing) {
173  for (auto iface : iface_map.second) {
174  logger_->log_debug(("BBCLIPS|" + env_name).c_str(),
175  "Closing writing interface %s",
176  iface->uid());
177  blackboard_->close(iface);
178  }
179  }
180  interfaces_.erase(env_name);
181  }
182  envs_.erase(env_name);
183 }
184 
185 void
186 BlackboardCLIPSFeature::clips_blackboard_enable_time_read(const std::string &env_name)
187 {
188  if (envs_.find(env_name) == envs_.end()) {
189  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
190  "Cannot enable reading for environment %s "
191  "(not defined)",
192  env_name.c_str());
193  return;
194  }
195 
196  std::string bb_read_defrule = "(defrule blackboard-read\n"
197  " (declare (salience 1000))\n"
198  " (time $?)\n"
199  " =>\n"
200  " (blackboard-read)\n"
201  ")";
202 
203  fawkes::MutexLocker lock(envs_[env_name].objmutex_ptr());
204  envs_[env_name]->build(bb_read_defrule);
205 }
206 
207 bool
208 BlackboardCLIPSFeature::clips_assert_interface_type(const std::string &env_name,
209  const std::string &log_name,
210  fawkes::Interface *iface,
211  const std::string &type)
212 {
213  std::string deftemplate = "(deftemplate " + type + "\n" + " (slot id (type STRING))\n"
214  + " (multislot time (type INTEGER) (cardinality 2 2))\n";
215 
216  InterfaceFieldIterator f, f_end = iface->fields_end();
217 
218  for (f = iface->fields(); f != f_end; ++f) {
219  std::string type;
220 
221  switch (f.get_type()) {
222  case IFT_BOOL:
223  deftemplate += std::string() + " (" + ((f.get_length() > 1) ? "multi" : "") + "slot "
224  + f.get_name() + " (type SYMBOL) (allowed-values TRUE FALSE))\n";
225  break;
226 
227  case IFT_INT8:
228  case IFT_UINT8:
229  case IFT_INT16:
230  case IFT_UINT16:
231  case IFT_INT32:
232  case IFT_UINT32:
233  case IFT_INT64:
234  case IFT_UINT64:
235  case IFT_BYTE:
236  deftemplate += std::string() + " (" + ((f.get_length() > 1) ? "multi" : "") + "slot "
237  + f.get_name() + " (type INTEGER))\n";
238  break;
239 
240  case IFT_FLOAT:
241  case IFT_DOUBLE:
242  deftemplate += std::string() + " (" + ((f.get_length() > 1) ? "multi" : "") + "slot "
243  + f.get_name() + " (type FLOAT))\n";
244  break;
245 
246  case IFT_STRING:
247  deftemplate += std::string() + " (slot " + f.get_name() + " (type STRING))\n";
248  break;
249 
250  case IFT_ENUM:
251  deftemplate += std::string() + " (" + ((f.get_length() > 1) ? "multi" : "") + "slot "
252  + f.get_name() + " (type SYMBOL))\n";
253  break;
254  }
255  }
256 
257  deftemplate += ")";
258 
259  std::string retract;
260  std::string logstr;
261 
262  if (cfg_retract_early_) {
263  retract = "(defrule " + type + "-cleanup\n" + " (declare (salience -10000))\n" + " ?f <- ("
264  + type + ")\n"
265  + " =>\n"
266  " (retract ?f)\n"
267  ")";
268  logstr = "Defrule";
269  } else {
270  retract = "(deffunction " + type
271  + "-cleanup-late (?id)\n"
272  " (delayed-do-for-all-facts ((?f "
273  + type
274  + "))\n"
275  " (eq ?f:id ?id)\n"
276  " (retract ?f)\n"
277  " )\n"
278  ")";
279  logstr = "Deffunction";
280  }
281 
282  if (envs_[env_name]->build(deftemplate) && envs_[env_name]->build(retract)) {
283  logger_->log_debug(log_name.c_str(), "Deftemplate:\n%s", deftemplate.c_str());
284  logger_->log_debug(log_name.c_str(), "%s:\n%s", logstr.c_str(), retract.c_str());
285  return true;
286  } else {
287  logger_->log_warn(log_name.c_str(),
288  "Defining blackboard type for %s in %s failed",
289  type.c_str(),
290  env_name.c_str());
291  return false;
292  }
293 }
294 
295 void
296 BlackboardCLIPSFeature::clips_blackboard_preload(const std::string &env_name,
297  const std::string &type)
298 {
299  std::string name = "BBCLIPS|" + env_name;
300 
301  if (envs_.find(env_name) == envs_.end()) {
302  logger_->log_warn(name.c_str(),
303  "Environment %s has not been registered "
304  "for blackboard feature",
305  env_name.c_str());
306  return;
307  }
308 
309  if (interfaces_[env_name].reading.find(type) == interfaces_[env_name].reading.end()
310  && interfaces_[env_name].writing.find(type) == interfaces_[env_name].writing.end()) {
311  // no interface of this type registered yet, add deftemplate for it
312  Interface *iface = NULL;
313  try {
314  iface = blackboard_->open_for_reading(type.c_str(), "__clips_blackboard_preload__");
315  clips_assert_interface_type(env_name, name, iface, type);
316  blackboard_->close(iface);
317  interfaces_[env_name].reading.insert(std::make_pair(type, std::list<fawkes::Interface *>()));
318  } catch (Exception &e) {
319  logger_->log_warn(name.c_str(),
320  "Failed to preload interface type %s, "
321  "exception follows",
322  type.c_str());
323  logger_->log_warn(name.c_str(), e);
324  return;
325  }
326  }
327 }
328 
329 void
330 BlackboardCLIPSFeature::clips_blackboard_open_interface(const std::string &env_name,
331  const std::string &type,
332  const std::string &id,
333  bool writing)
334 {
335  std::string name = "BBCLIPS|" + env_name;
336  std::string owner = "CLIPS:" + env_name;
337 
338  if (envs_.find(env_name) == envs_.end()) {
339  logger_->log_warn(name.c_str(),
340  "Environment %s has not been registered "
341  "for blackboard feature",
342  env_name.c_str());
343  return;
344  }
345 
346  fawkes::LockPtr<CLIPS::Environment> clips = envs_[env_name];
347 
348  Interface * iface = NULL;
349  InterfaceMap &iface_map = writing ? interfaces_[env_name].writing : interfaces_[env_name].reading;
350 
351  if (iface_map.find(type) == iface_map.end()) {
352  // no interface of this type registered yet, add deftemplate for it
353  try {
354  if (writing) {
355  iface = blackboard_->open_for_writing(type.c_str(), id.c_str(), owner.c_str());
356  } else {
357  iface = blackboard_->open_for_reading(type.c_str(), id.c_str(), owner.c_str());
358  }
359  } catch (Exception &e) {
360  logger_->log_warn(name.c_str(),
361  "Failed to open interface %s:%s, exception follows",
362  type.c_str(),
363  id.c_str());
364  logger_->log_warn(name.c_str(), e);
365  return;
366  }
367 
368  if (!clips_assert_interface_type(env_name, name, iface, type)) {
369  blackboard_->close(iface);
370  } else {
371  logger_->log_info(name.c_str(),
372  "Added interface %s for %s",
373  iface->uid(),
374  iface->is_writer() ? "writing" : "reading");
375  iface_map.insert(std::make_pair(type, std::list<fawkes::Interface *>(1, iface)));
376  fawkes::MutexLocker lock(clips.objmutex_ptr());
377  clips->assert_fact_f("(blackboard-interface (id \"%s\") (type \"%s\") (uid \"%s\") "
378  " (hash \"%s\") (serial %u) (writing %s))",
379  iface->id(),
380  iface->type(),
381  iface->uid(),
382  iface->hash_printable(),
383  iface->serial(),
384  writing ? "TRUE" : "FALSE");
385  }
386  } else {
387  auto &iface_list = iface_map[type];
388  if (std::none_of(iface_list.begin(),
389  iface_list.end(),
390  [&type, &id](const Interface *i) -> bool {
391  return (type == i->type()) && (id == i->id());
392  })) {
393  try {
394  if (writing) {
395  iface = blackboard_->open_for_writing(type.c_str(), id.c_str(), owner.c_str());
396  } else {
397  iface = blackboard_->open_for_reading(type.c_str(), id.c_str(), owner.c_str());
398  }
399  iface_map[type].push_back(iface);
400  logger_->log_info(name.c_str(),
401  "Added interface %s for %s",
402  iface->uid(),
403  iface->is_writer() ? "writing" : "reading");
404  fawkes::MutexLocker lock(clips.objmutex_ptr());
405  clips->assert_fact_f("(blackboard-interface (id \"%s\") (type \"%s\") (uid \"%s\") "
406  " (hash \"%s\") (serial %u) (writing %s))",
407  iface->id(),
408  iface->type(),
409  iface->uid(),
410  iface->hash_printable(),
411  iface->serial(),
412  writing ? "TRUE" : "FALSE");
413  } catch (Exception &e) {
414  logger_->log_warn(name.c_str(),
415  "Failed to open interface %s:%s, exception follows",
416  type.c_str(),
417  id.c_str());
418  logger_->log_warn(name.c_str(), e);
419  return;
420  }
421  }
422  }
423 }
424 
425 void
426 BlackboardCLIPSFeature::clips_blackboard_open_interface_reading(const std::string &env_name,
427  const std::string &type,
428  const std::string &id)
429 {
430  clips_blackboard_open_interface(env_name, type, id, /* writing */ false);
431 }
432 
433 void
434 BlackboardCLIPSFeature::clips_blackboard_open_interface_writing(const std::string &env_name,
435  const std::string &type,
436  const std::string &id)
437 {
438  clips_blackboard_open_interface(env_name, type, id, /* writing */ true);
439 }
440 
441 void
442 BlackboardCLIPSFeature::clips_blackboard_close_interface(const std::string &env_name,
443  const std::string &type,
444  const std::string &id)
445 {
446  std::string name = "BBCLIPS|" + env_name;
447 
448  if (envs_.find(env_name) == envs_.end()) {
449  logger_->log_warn(name.c_str(),
450  "Environment %s has not been registered "
451  "for blackboard feature",
452  env_name.c_str());
453  return;
454  }
455 
456  if (interfaces_[env_name].reading.find(type) != interfaces_[env_name].reading.end()) {
457  auto &l = interfaces_[env_name].reading[type];
458  auto iface_it =
459  find_if(l.begin(), l.end(), [&id](const Interface *iface) { return id == iface->id(); });
460  if (iface_it != l.end()) {
461  blackboard_->close(*iface_it);
462  l.erase(iface_it);
463  // do NOT remove the list, even if empty, because we need to remember
464  // that we already built the deftemplate and added the cleanup rule
465  }
466  }
467  if (interfaces_[env_name].writing.find(type) != interfaces_[env_name].writing.end()) {
468  auto &l = interfaces_[env_name].writing[type];
469  auto iface_it =
470  find_if(l.begin(), l.end(), [&id](const Interface *iface) { return id == iface->id(); });
471  if (iface_it != l.end()) {
472  blackboard_->close(*iface_it);
473  l.erase(iface_it);
474  // do NOT remove the list, even if empty, because we need to remember
475  // that we already built the deftemplate and added the cleanup rule
476  }
477  }
478 }
479 
480 void
481 BlackboardCLIPSFeature::clips_blackboard_read(const std::string &env_name)
482 {
483  // no interfaces registered, that's fine
484  if (interfaces_.find(env_name) == interfaces_.end())
485  return;
486  if (envs_.find(env_name) == envs_.end()) {
487  // Environment not registered, big bug
488  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
489  "Environment %s not registered,"
490  " cannot read interfaces",
491  env_name.c_str());
492  return;
493  }
494 
495  fawkes::MutexLocker lock(envs_[env_name].objmutex_ptr());
496  CLIPS::Environment &env = **(envs_[env_name]);
497  for (auto &iface_map : interfaces_[env_name].reading) {
498  for (auto i : iface_map.second) {
499  i->read();
500  if (i->changed()) {
501  if (!cfg_retract_early_) {
502  std::string fun = std::string("(") + i->type() + "-cleanup-late \"" + i->id() + "\")";
503  env.evaluate(fun);
504  }
505  const Time *t = i->timestamp();
506 
507  std::string fact = std::string("(") + i->type() + " (id \"" + i->id() + "\")" + " (time "
508  + StringConversions::to_string(t->get_sec()) + " "
509  + StringConversions::to_string(t->get_usec()) + ")";
510 
511  InterfaceFieldIterator f, f_end = i->fields_end();
512  for (f = i->fields(); f != f_end; ++f) {
513  std::string value;
514  if (f.get_type() == IFT_STRING) {
515  value = f.get_value_string();
516  std::string::size_type pos = 0;
517  while ((pos = value.find("\"", pos)) != std::string::npos) {
518  value.replace(pos, 1, "\\\"");
519  pos += 2;
520  }
521  value = std::string("\"") + value + "\"";
522  } else {
523  value = f.get_value_string();
524  std::string::size_type pos;
525  while ((pos = value.find(",")) != std::string::npos) {
526  value = value.erase(pos, 1);
527  }
528 
529  if (f.get_type() == IFT_FLOAT || f.get_type() == IFT_DOUBLE) {
530  std::string::size_type pos;
531  while ((pos = value.find("-inf")) != std::string::npos) {
532  value = value.replace(pos, 4, std::to_string(std::numeric_limits<double>::min()));
533  }
534  while ((pos = value.find("inf")) != std::string::npos) {
535  value = value.replace(pos, 3, std::to_string(std::numeric_limits<double>::max()));
536  }
537  while ((pos = value.find("-nan")) != std::string::npos) {
538  value =
539  value.replace(pos, 4, std::to_string(std::numeric_limits<double>::min() + 1));
540  }
541  while ((pos = value.find("nan")) != std::string::npos) {
542  value =
543  value.replace(pos, 3, std::to_string(std::numeric_limits<double>::max() - 1));
544  }
545  } else if (f.get_type() == IFT_BOOL) {
546  std::string::size_type pos;
547  while ((pos = value.find("false")) != std::string::npos) {
548  value = value.replace(pos, 5, "FALSE");
549  }
550  while ((pos = value.find("true")) != std::string::npos) {
551  value = value.replace(pos, 4, "TRUE");
552  }
553  }
554  }
555  fact += std::string(" (") + f.get_name() + " " + value + ")";
556  }
557  fact += ")";
558  env.assert_fact(fact);
559  }
560  }
561  }
562 }
563 
564 void
565 BlackboardCLIPSFeature::clips_blackboard_write(const std::string &env_name, const std::string &uid)
566 {
567  // no interfaces registered, that's fine
568  if (interfaces_.find(env_name) == interfaces_.end())
569  return;
570  if (envs_.find(env_name) == envs_.end()) {
571  // Environment not registered, big bug
572  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
573  "Environment %s not registered,"
574  " cannot write interface %s",
575  env_name.c_str(),
576  uid.c_str());
577  return;
578  }
579  std::string type, id;
580  Interface::parse_uid(uid.c_str(), type, id);
581  if (interfaces_[env_name].writing.find(type) != interfaces_[env_name].writing.end()) {
582  auto i = std::find_if(interfaces_[env_name].writing[type].begin(),
583  interfaces_[env_name].writing[type].end(),
584  [&uid](const Interface *iface) -> bool { return uid == iface->uid(); });
585  if (i != interfaces_[env_name].writing[type].end()) {
586  (*i)->write();
587  } else {
588  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
589  "Interface %s not opened for writing,"
590  " in environment %s",
591  uid.c_str(),
592  env_name.c_str());
593  return;
594  }
595  } else {
596  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
597  "No interface of type %s opened for,"
598  " writing in environment %s",
599  type.c_str(),
600  env_name.c_str());
601  return;
602  }
603 }
604 
605 void
606 BlackboardCLIPSFeature::clips_blackboard_get_info(const std::string &env_name)
607 {
608  if (envs_.find(env_name) == envs_.end()) {
609  // Environment not registered, big bug
610  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
611  "Environment %s not registered,"
612  " cannot read interfaces",
613  env_name.c_str());
614  return;
615  }
616 
617  fawkes::LockPtr<CLIPS::Environment> &clips = envs_[env_name];
618 
619  InterfaceInfoList *iil = blackboard_->list_all();
620 
621  fawkes::MutexLocker lock(clips.objmutex_ptr());
622  for (auto ii : *iil) {
623  const Time * timestamp = ii.timestamp();
624  std::list<std::string> quoted_readers;
625  std::list<std::string> readers = ii.readers();
626  std::for_each(readers.begin(), readers.end(), [&quoted_readers](const std::string &r) {
627  quoted_readers.push_back(std::string("\"") + r + "\"");
628  });
629  std::string quoted_readers_s = str_join(quoted_readers, ' ');
630  clips->assert_fact_f("(blackboard-interface-info (id \"%s\") (type \"%s\") "
631  "(hash \"%s\") (has-writer %s) (num-readers %u) "
632  "(writer \"%s\") (readers %s) (timestamp %u %u))",
633  ii.id(),
634  ii.type(),
635  ii.hash_printable().c_str(),
636  ii.has_writer() ? "TRUE" : "FALSE",
637  ii.num_readers(),
638  ii.writer().c_str(),
639  quoted_readers_s.c_str(),
640  timestamp->get_sec(),
641  timestamp->get_usec());
642  }
643 
644  delete iil;
645 }
646 
647 void
648 BlackboardCLIPSFeature::clips_blackboard_set(const std::string &env_name,
649  const std::string &uid,
650  const std::string &field,
651  CLIPS::Value value)
652 {
653  // no interfaces registered, that's fine
654  if (interfaces_.find(env_name) == interfaces_.end())
655  return;
656  if (envs_.find(env_name) == envs_.end()) {
657  // Environment not registered, big bug
658  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
659  "Environment %s not registered,"
660  " cannot set %s on interface %s",
661  env_name.c_str(),
662  field.c_str(),
663  uid.c_str());
664  return;
665  }
666  std::string type, id;
667  Interface::parse_uid(uid.c_str(), type, id);
668  if (interfaces_[env_name].writing.find(type) != interfaces_[env_name].writing.end()) {
669  auto i = std::find_if(interfaces_[env_name].writing[type].begin(),
670  interfaces_[env_name].writing[type].end(),
671  [&uid](const Interface *iface) -> bool { return uid == iface->uid(); });
672  if (i != interfaces_[env_name].writing[type].end()) {
673  set_field((*i)->fields(), (*i)->fields_end(), env_name, field, value);
674  } else {
675  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
676  "Interface %s not opened for writing,"
677  " in environment %s",
678  uid.c_str(),
679  env_name.c_str());
680  return;
681  }
682  } else {
683  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
684  "No interface of type %s opened for,"
685  " writing in environment %s",
686  type.c_str(),
687  env_name.c_str());
688  return;
689  }
690 }
691 
692 void
693 BlackboardCLIPSFeature::clips_blackboard_set_multifield(const std::string &env_name,
694  const std::string &uid,
695  const std::string &field,
696  CLIPS::Values values)
697 {
698  // no interfaces registered, that's fine
699  if (interfaces_.find(env_name) == interfaces_.end())
700  return;
701  if (envs_.find(env_name) == envs_.end()) {
702  // Environment not registered, big bug
703  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
704  "Environment %s not registered,"
705  " cannot set %s on interface %s",
706  env_name.c_str(),
707  field.c_str(),
708  uid.c_str());
709  return;
710  }
711  std::string type, id;
712  Interface::parse_uid(uid.c_str(), type, id);
713  if (interfaces_[env_name].writing.find(type) != interfaces_[env_name].writing.end()) {
714  auto i = std::find_if(interfaces_[env_name].writing[type].begin(),
715  interfaces_[env_name].writing[type].end(),
716  [&uid](const Interface *iface) -> bool { return uid == iface->uid(); });
717  if (i != interfaces_[env_name].writing[type].end()) {
718  set_multifield((*i)->fields(), (*i)->fields_end(), env_name, field, values);
719  } else {
720  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
721  "Interface %s not opened for writing,"
722  " in environment %s",
723  uid.c_str(),
724  env_name.c_str());
725  return;
726  }
727  } else {
728  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
729  "No interface of type %s opened for,"
730  " writing in environment %s",
731  type.c_str(),
732  env_name.c_str());
733  return;
734  }
735 }
736 
737 CLIPS::Value
738 BlackboardCLIPSFeature::clips_blackboard_create_msg(const std::string &env_name,
739  const std::string &uid,
740  const std::string &msg_type)
741 {
742  // no interfaces registered, that's fine
743  if (interfaces_.find(env_name) == interfaces_.end()) {
744  return CLIPS::Value(new std::shared_ptr<Message>());
745  }
746  if (envs_.find(env_name) == envs_.end()) {
747  // Environment not registered, big bug
748  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
749  "Environment %s not registered,"
750  " cannot read interfaces",
751  env_name.c_str());
752  return CLIPS::Value(new std::shared_ptr<Message>());
753  }
754  fawkes::MutexLocker lock(envs_[env_name].objmutex_ptr());
755 
756  std::string if_type, id;
757  Interface::parse_uid(uid.c_str(), if_type, id);
758 
759  //get interface
760  if (interfaces_[env_name].reading.find(if_type) == interfaces_[env_name].reading.end()) {
761  logger_->log_warn(
762  ("BBCLIPS|" + env_name).c_str(),
763  "Can't create message for interface %s, because there is no opened interface with this type",
764  uid.c_str());
765  return CLIPS::Value(new std::shared_ptr<Message>());
766  }
767  auto i = std::find_if(interfaces_[env_name].reading[if_type].begin(),
768  interfaces_[env_name].reading[if_type].end(),
769  [&uid](const Interface *iface) -> bool { return uid == iface->uid(); });
770  if (i == interfaces_[env_name].reading[if_type].end()) {
771  logger_->log_warn(
772  ("BBCLIPS|" + env_name).c_str(),
773  "Can't create message for interface %s, because there is no opened interface with that uid",
774  uid.c_str());
775  return CLIPS::Value(new std::shared_ptr<Message>());
776  }
777 
778  //check if message type exists
779  std::list<const char *> available_types = (*i)->get_message_types();
780  bool type_exists = false;
781  for (std::list<const char *>::iterator it = available_types.begin();
782  it != available_types.end() && !type_exists;
783  ++it) {
784  if (std::string(*it).compare(msg_type) == 0) {
785  type_exists = true;
786  }
787  }
788  if (!type_exists) {
789  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
790  "Can't create message for interface %s, because there is no message type %s",
791  uid.c_str(),
792  msg_type.c_str());
793  return CLIPS::Value(new std::shared_ptr<Message>());
794  }
795 
796  //create message
797  Message *m = (*i)->create_message(msg_type.c_str());
798 
799  //save which interface belongs to the message
800  interface_of_msg_[m] = (*i);
801 
802  //send message to clips
803  return CLIPS::Value(new std::shared_ptr<Message>(m));
804 }
805 
806 CLIPS::Values
807 BlackboardCLIPSFeature::clips_blackboard_list_msg_fields(const std::string &env_name, void *msgptr)
808 {
809  std::shared_ptr<Message> *m = static_cast<std::shared_ptr<Message> *>(msgptr);
810  if (!*m) {
811  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
812  "Can't list message fields, the pointer is wrong.");
813  return CLIPS::Values();
814  }
815 
816  const int field_count = (*m)->num_fields();
817  CLIPS::Values field_names(field_count);
818  int i = 0;
819  for (InterfaceFieldIterator it = (*m)->fields(); it != (*m)->fields_end(); ++it) {
820  field_names[i].set(it.get_name(), true);
821  logger_->log_info(("BBCLIPS|" + env_name).c_str(), "Message has field %s", it.get_name());
822  i++;
823  }
824  return field_names;
825 }
826 
827 void
828 BlackboardCLIPSFeature::clips_blackboard_set_msg_field(const std::string &env_name,
829  void * msgptr,
830  const std::string &field_name,
831  CLIPS::Value value)
832 {
833  std::shared_ptr<Message> *m = static_cast<std::shared_ptr<Message> *>(msgptr);
834  if (!*m) {
835  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
836  "Can't set message field, the pointer is wrong.");
837  return;
838  }
839 
840  bool set_success = set_field((*m)->fields(), (*m)->fields_end(), env_name, field_name, value);
841  if (!set_success) {
842  logger_->log_warn(("BBCLIPS|" + env_name).c_str(), "Can't set message field.");
843  }
844 }
845 
846 void
847 BlackboardCLIPSFeature::clips_blackboard_set_msg_multifield(const std::string &env_name,
848  void * msgptr,
849  const std::string &field_name,
850  CLIPS::Values values)
851 {
852  std::shared_ptr<Message> *m = static_cast<std::shared_ptr<Message> *>(msgptr);
853  if (!*m) {
854  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
855  "Can't set message field, the pointer is wrong.");
856  return;
857  }
858 
859  bool set_success =
860  set_multifield((*m)->fields(), (*m)->fields_end(), env_name, field_name, values);
861  if (!set_success) {
862  logger_->log_warn(("BBCLIPS|" + env_name).c_str(), "Can't set message field.");
863  }
864 }
865 
866 CLIPS::Value
867 BlackboardCLIPSFeature::clips_blackboard_send_msg(const std::string &env_name, void *msgptr)
868 {
869  std::shared_ptr<Message> *m = static_cast<std::shared_ptr<Message> *>(msgptr);
870  if (!*m) {
871  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
872  "Can't set message field, the pointer is wrong.");
873  return CLIPS::Value(0);
874  }
875  if (!interface_of_msg_[m->get()]) {
876  logger_->log_warn(("BBCLIPS|" + env_name).c_str(), "Can't send message, was it already sent?");
877  return CLIPS::Value(0);
878  }
879 
880  //add reference to the message so we can return the message id (otherwise it is changed by sending)
881  m->get()->ref();
882 
883  unsigned int message_id = 0;
884 
885  //send message about the saved interface
886  try {
887  interface_of_msg_[m->get()]->msgq_enqueue(m->get());
888  message_id = m->get()->id();
890  // keep quiet, BlackBoardMessageManager will already have printed a warning
891  //logger_->log_warn(("BBCLIPS|" + env_name).c_str(), "Failed to send message: no writer");
892  } catch (Exception &e) {
893  logger_->log_warn(("BBCLIPS|" + env_name).c_str(),
894  "Failed to send message: %s",
895  e.what_no_backtrace());
896  }
897 
898  //delete saved pointer to interface
899  interface_of_msg_.erase(m->get());
900 
901  //remove added refference
902  m->get()->unref();
903 
904  return CLIPS::Value(message_id);
905 }
906 
907 /**
908  Set array of an InterfaceFieldIterator of an Interface or Message
909  to an CLIPS-Multifield.
910  @return if field could successfully be set
911  */
912 bool
913 BlackboardCLIPSFeature::set_multifield(InterfaceFieldIterator fit_begin,
914  InterfaceFieldIterator fit_end,
915  const std::string & env_name,
916  const std::string & field,
917  CLIPS::Values values)
918 {
919  //find field and check for length of the interface array/multifield
921  for (fit = fit_begin; fit != fit_end; ++fit) {
922  if (field == fit.get_name()) {
923  size_t min_length = fit.get_length();
924  if (values.size() < min_length) {
925  min_length = values.size();
926  }
927  //set each entry
928  for (size_t i = 0; i < min_length; i++) {
929  bool success = set_field(fit, fit_end, env_name, field, values[i], i);
930  if (!success) {
931  return false;
932  }
933  }
934  break;
935  }
936  }
937 
938  if (fit == fit_end) {
939  logger_->log_error(("BBCLIPS|" + env_name).c_str(), "Can't find field %s", field.c_str());
940  return false;
941  }
942  return true;
943 }
944 
945 /**
946  Set field of an InterfaceFieldIterator of an Interface or Message.
947  @index index in an array of the interface (leave default for non array value)
948  @return if field could successfully be set
949  */
950 bool
951 BlackboardCLIPSFeature::set_field(InterfaceFieldIterator fit_begin,
952  InterfaceFieldIterator fit_end,
953  const std::string & env_name,
954  const std::string & field,
955  CLIPS::Value value,
956  int index)
957 {
959  for (fit = fit_begin; fit != fit_end; ++fit) {
960  if (field == fit.get_name()) {
961  switch (fit.get_type()) {
962  case IFT_BOOL:
963  if (value.type() != CLIPS::TYPE_SYMBOL && value.type() != CLIPS::TYPE_STRING) {
964  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
965  "Cannot set field %s: invalid value (not a symbol)",
966  field.c_str());
967  return false;
968  } else {
969  std::string val_s = value.as_string();
970  if (value == "TRUE") {
971  fit.set_bool(true, index);
972  } else if (value == "FALSE") {
973  fit.set_bool(false, index);
974  } else {
975  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
976  "Cannot set field %s: invalid value %s (not a bool)",
977  field.c_str(),
978  val_s.c_str());
979  return false;
980  }
981  }
982  break;
983 
984  case IFT_INT8:
985  if (value.type() != CLIPS::TYPE_INTEGER) {
986  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
987  "Cannot set field %s: invalid value (not an integer)",
988  field.c_str());
989  return false;
990  } else {
991  long long int val = value.as_integer();
992  fit.set_int8((int8_t)val, index);
993  }
994  break;
995 
996  case IFT_UINT8:
997  if (value.type() != CLIPS::TYPE_INTEGER) {
998  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
999  "Cannot set field %s: invalid value (not an integer)",
1000  field.c_str());
1001  return false;
1002  } else {
1003  long long int val = value.as_integer();
1004  fit.set_uint8((uint8_t)val, index);
1005  }
1006  break;
1007 
1008  case IFT_INT16:
1009  if (value.type() != CLIPS::TYPE_INTEGER) {
1010  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1011  "Cannot set field %s: invalid value (not an integer)",
1012  field.c_str());
1013  return false;
1014  } else {
1015  long long int val = value.as_integer();
1016  fit.set_int16((int16_t)val, index);
1017  }
1018  break;
1019 
1020  case IFT_UINT16:
1021  if (value.type() != CLIPS::TYPE_INTEGER) {
1022  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1023  "Cannot set field %s: invalid value (not an integer)",
1024  field.c_str());
1025  return false;
1026  } else {
1027  long long int val = value.as_integer();
1028  fit.set_uint16((uint16_t)val, index);
1029  }
1030  break;
1031 
1032  case IFT_INT32:
1033  if (value.type() != CLIPS::TYPE_INTEGER) {
1034  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1035  "Cannot set field %s: invalid value (not an integer)",
1036  field.c_str());
1037  return false;
1038  } else {
1039  long long int val = value.as_integer();
1040  fit.set_int32((int32_t)val, index);
1041  }
1042  break;
1043 
1044  case IFT_UINT32:
1045  if (value.type() != CLIPS::TYPE_INTEGER) {
1046  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1047  "Cannot set field %s: invalid value (not an integer)",
1048  field.c_str());
1049  return false;
1050  } else {
1051  long long int val = value.as_integer();
1052  fit.set_uint32((uint32_t)val, index);
1053  }
1054  break;
1055 
1056  case IFT_INT64:
1057  if (value.type() != CLIPS::TYPE_INTEGER) {
1058  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1059  "Cannot set field %s: invalid value (not an integer)",
1060  field.c_str());
1061  return false;
1062  } else {
1063  long long int val = value.as_integer();
1064  fit.set_int64((int64_t)val, index);
1065  }
1066  break;
1067 
1068  case IFT_UINT64:
1069  if (value.type() != CLIPS::TYPE_INTEGER) {
1070  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1071  "Cannot set field %s: invalid value (not an integer)",
1072  field.c_str());
1073  return false;
1074  } else {
1075  long long int val = value.as_integer();
1076  fit.set_uint64((uint64_t)val, index);
1077  }
1078  break;
1079 
1080  case IFT_FLOAT:
1081  if (value.type() != CLIPS::TYPE_FLOAT && value.type() != CLIPS::TYPE_INTEGER) {
1082  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1083  "Cannot set field %s: invalid value "
1084  "(neither float nor integer)",
1085  field.c_str());
1086  return false;
1087  } else {
1088  if (value.type() == CLIPS::TYPE_FLOAT) {
1089  double val = value.as_float();
1090  fit.set_float((float)val, index);
1091  } else {
1092  long long int val = value.as_integer();
1093  fit.set_float((float)val, index);
1094  }
1095  }
1096  break;
1097 
1098  case IFT_DOUBLE:
1099  if (value.type() != CLIPS::TYPE_FLOAT && value.type() != CLIPS::TYPE_INTEGER) {
1100  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1101  "Cannot set field %s: invalid value "
1102  "(neither double nor integer)",
1103  field.c_str());
1104  return false;
1105  } else {
1106  if (value.type() == CLIPS::TYPE_FLOAT) {
1107  double val = value.as_float();
1108  fit.set_double((double)val, index);
1109  } else {
1110  long long int val = value.as_integer();
1111  fit.set_double((double)val, index);
1112  }
1113  }
1114  break;
1115 
1116  case IFT_STRING:
1117  if (value.type() != CLIPS::TYPE_SYMBOL && value.type() != CLIPS::TYPE_STRING) {
1118  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1119  "Cannot set field %s: invalid value "
1120  "(neither symbol nor string)",
1121  field.c_str());
1122  return false;
1123  } else {
1124  std::string val = value.as_string();
1125  fit.set_string(val.c_str());
1126  if (index != 0) {
1127  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1128  "Cannot set field %s[%d]: "
1129  "there are no string arrays in interfaces",
1130  field.c_str(),
1131  index);
1132  }
1133  }
1134  break;
1135 
1136  case IFT_ENUM:
1137  if (value.type() != CLIPS::TYPE_SYMBOL) {
1138  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1139  "Cannot set field %s: invalid value "
1140  "(not a symbol)",
1141  field.c_str());
1142  } else {
1143  try {
1144  std::string val = value.as_string();
1145  fit.set_enum_string(val.c_str(), index);
1146  } catch (Exception &e) {
1147  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1148  "Failed to set enum field %s to %s, exception follows",
1149  field.c_str(),
1150  value.as_string().c_str());
1151  logger_->log_error(("BBCLIPS|" + env_name).c_str(), e);
1152  return false;
1153  }
1154  }
1155  break;
1156 
1157  default:
1158  logger_->log_error(("BBCLIPS|" + env_name).c_str(),
1159  "Setting of field type %s for %s not supported",
1160  fit.get_typename(),
1161  field.c_str());
1162  return false;
1163  }
1164 
1165  break;
1166  }
1167  }
1168 
1169  if (fit == fit_end) {
1170  logger_->log_error(("BBCLIPS|" + env_name).c_str(), "Can't find field %s", field.c_str());
1171  return false;
1172  }
1173  return true;
1174 }
fawkes::InterfaceFieldIterator::set_enum_string
void set_enum_string(const char *e, unsigned int index=0)
Set value of current field as enum (from an integer).
Definition: field_iterator.cpp:1283
fawkes::RefCount::unref
void unref()
Decrement reference count and conditionally delete this instance.
Definition: refcount.cpp:99
BlackboardCLIPSFeature::BlackboardCLIPSFeature
BlackboardCLIPSFeature(fawkes::Logger *logger, fawkes::BlackBoard *blackboard, bool retract_early)
Constructor.
Definition: feature_blackboard.cpp:50
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:143
fawkes::IFT_UINT8
8 bit unsigned integer field
Definition: types.h:50
fawkes::Interface::fields_end
InterfaceFieldIterator fields_end()
Invalid iterator.
Definition: interface.cpp:1207
BlackboardCLIPSFeature::clips_context_init
virtual void clips_context_init(const std::string &env_name, fawkes::LockPtr< CLIPS::Environment > &clips)
Definition: feature_blackboard.cpp:80
fawkes::InterfaceFieldIterator::set_uint16
void set_uint16(uint16_t i, unsigned int index=0)
Set value of current field as unsigned integer.
Definition: field_iterator.cpp:1063
fawkes::BlackBoard::list_all
virtual InterfaceInfoList * list_all()=0
fawkes::LockPtr< CLIPS::Environment >
fawkes::InterfaceFieldIterator::set_int8
void set_int8(int8_t i, unsigned int index=0)
Set value of current field as integer.
Definition: field_iterator.cpp:991
fawkes::Time::get_sec
long get_sec() const
Definition: time.h:121
fawkes::InterfaceFieldIterator::set_bool
void set_bool(bool b, unsigned int index=0)
Set value of current field as bool.
Definition: field_iterator.cpp:967
fawkes::IFT_UINT64
64 bit unsigned integer field
Definition: types.h:56
fawkes::Interface::is_writer
bool is_writer() const
Check if this is a writing instance.
Definition: interface.cpp:441
fawkes::Message
Definition: message.h:40
fawkes::Interface::hash_printable
const char * hash_printable() const
Get printable interface hash.
Definition: interface.cpp:310
fawkes::InterfaceFieldIterator::get_value_string
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
Definition: field_iterator.cpp:306
BlackboardCLIPSFeature::~BlackboardCLIPSFeature
virtual ~BlackboardCLIPSFeature()
Destructor.
Definition: feature_blackboard.cpp:61
fawkes::IFT_INT8
8 bit integer field
Definition: types.h:49
fawkes::IFT_BOOL
boolean field
Definition: types.h:48
fawkes::IFT_FLOAT
float field
Definition: types.h:57
fawkes::IFT_ENUM
field with interface specific enum type
Definition: types.h:61
fawkes::IFT_UINT16
16 bit unsigned integer field
Definition: types.h:52
fawkes::Logger::log_info
virtual void log_info(const char *component, const char *format,...)=0
fawkes::IFT_UINT32
32 bit unsigned integer field
Definition: types.h:54
fawkes::InterfaceFieldIterator::set_int16
void set_int16(int16_t i, unsigned int index=0)
Set value of current field as integer.
Definition: field_iterator.cpp:1039
fawkes::MutexLocker
Definition: mutex_locker.h:37
fawkes::LockPtr::objmutex_ptr
Mutex * objmutex_ptr() const
Get object mutex.
Definition: lockptr.h:297
fawkes::BlackBoardNoWritingInstanceException
Thrown if no writer interface is alive.
Definition: exceptions.h:154
fawkes::InterfaceFieldIterator::set_int32
void set_int32(int32_t i, unsigned int index=0)
Set value of current field as integer.
Definition: field_iterator.cpp:1087
fawkes::BlackBoard
Definition: blackboard.h:48
fawkes::InterfaceFieldIterator::set_float
void set_float(float f, unsigned int index=0)
Set value of current field as float.
Definition: field_iterator.cpp:1183
fawkes::Interface::type
const char * type() const
Get type of interface.
Definition: interface.cpp:643
fawkes::Interface::id
const char * id() const
Get identifier of interface.
Definition: interface.cpp:652
fawkes::InterfaceFieldIterator::set_uint8
void set_uint8(uint8_t i, unsigned int index=0)
Set value of current field as unsigned integer.
Definition: field_iterator.cpp:1015
fawkes::InterfaceFieldIterator::set_double
void set_double(double f, unsigned int index=0)
Set value of current field as double.
Definition: field_iterator.cpp:1207
fawkes::InterfaceFieldIterator
Definition: field_iterator.h:37
fawkes::InterfaceFieldIterator::get_type
interface_fieldtype_t get_type() const
Get type of current field.
Definition: field_iterator.cpp:196
fawkes::IFT_INT32
32 bit integer field
Definition: types.h:53
fawkes::RefCount::ref
void ref()
Increment reference count.
Definition: refcount.cpp:71
fawkes::BlackBoard::close
virtual void close(Interface *interface)=0
fawkes::Logger::log_error
virtual void log_error(const char *component, const char *format,...)=0
fawkes::Logger
Definition: logger.h:40
fawkes
fawkes::Logger::log_warn
virtual void log_warn(const char *component, const char *format,...)=0
fawkes::InterfaceFieldIterator::get_name
const char * get_name() const
Get name of current field.
Definition: field_iterator.cpp:265
fawkes::InterfaceInfoList
Definition: interface_info.h:79
fawkes::Interface
Definition: interface.h:77
fawkes::CLIPSFeature
Definition: clips_feature.h:40
fawkes::Interface::uid
const char * uid() const
Get unique identifier of interface.
Definition: interface.cpp:677
fawkes::InterfaceFieldIterator::set_uint32
void set_uint32(uint32_t i, unsigned int index=0)
Set value of current field as unsigned integer.
Definition: field_iterator.cpp:1111
fawkes::IFT_INT64
64 bit integer field
Definition: types.h:55
fawkes::InterfaceFieldIterator::get_length
size_t get_length() const
Get length of current field.
Definition: field_iterator.cpp:291
fawkes::Exception::what_no_backtrace
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
Definition: exception.cpp:662
fawkes::InterfaceFieldIterator::set_string
void set_string(const char *s)
Set value of current field as string.
Definition: field_iterator.cpp:1577
fawkes::Interface::fields
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
Definition: interface.cpp:1198
fawkes::Time
Definition: time.h:96
fawkes::IFT_DOUBLE
double field
Definition: types.h:58
fawkes::Interface::serial
unsigned short serial() const
Get instance serial of interface.
Definition: interface.cpp:686
fawkes::InterfaceFieldIterator::set_int64
void set_int64(int64_t i, unsigned int index=0)
Set value of current field as integer.
Definition: field_iterator.cpp:1135
fawkes::Message::id
unsigned int id() const
Get message ID.
Definition: message.cpp:184
fawkes::BlackBoard::open_for_reading
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
fawkes::IFT_STRING
string field
Definition: types.h:59
fawkes::IFT_BYTE
byte field, alias for uint8
Definition: types.h:60
fawkes::Time::get_usec
long get_usec() const
Definition: time.h:131
BlackboardCLIPSFeature::clips_context_destroyed
virtual void clips_context_destroyed(const std::string &env_name)
Definition: feature_blackboard.cpp:160
fawkes::InterfaceFieldIterator::set_uint64
void set_uint64(uint64_t i, unsigned int index=0)
Set value of current field as unsigned integer.
Definition: field_iterator.cpp:1159
fawkes::IFT_INT16
16 bit integer field
Definition: types.h:51
fawkes::Logger::log_debug
virtual void log_debug(const char *component, const char *format,...)=0
fawkes::BlackBoard::open_for_writing
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
fawkes::InterfaceFieldIterator::get_typename
const char * get_typename() const
Get type of current field as string.
Definition: field_iterator.cpp:209
fawkes::Exception
Definition: exception.h:39