22 #include <blackboard/remote.h> 23 #include <plugins/openprs/mod_utils.h> 24 #include <utils/misc/string_conversions.h> 25 #include <utils/time/time.h> 27 #include <lisp-list_f-pub.h> 28 #include <oprs-array_f-pub.h> 29 #include <oprs-type_f-pub.h> 30 #include <oprs_f-pub.h> 31 #include <slistPack_f.h> 35 extern "C" void finalize();
39 std::map<std::string, Interface *> g_interfaces_read;
40 std::map<std::string, Interface *> g_interfaces_write;
42 Symbol g_bb_write_sym;
46 action_blackboard_open(TermList terms)
48 int terms_len = sl_slist_length(terms);
51 "Error[bb-open-interface]: invalid number of " 52 "arguments: req 3, got %i\n",
57 Term *type = (Term *)get_list_pos(terms, 1);
58 Term *
id = (Term *)get_list_pos(terms, 2);
59 Term *mode = (Term *)get_list_pos(terms, 3);
60 if (type->type != STRING) {
61 fprintf(stderr,
"Error[bb-open-interface]: interface type is not a STRING\n");
64 if (id->type != STRING) {
65 fprintf(stderr,
"Error[bb-open-interface]: interface ID is not a STRING\n");
68 if (id->type != STRING) {
69 fprintf(stderr,
"Error[bb-open-interface]: interface ID is not a STRING\n");
72 if (mode->type != TT_ATOM) {
73 fprintf(stderr,
"Error[bb-open-interface]: interface mode is not a symbol\n");
76 if (mode->u.id != g_bb_read_sym && mode->u.id != g_bb_write_sym) {
77 fprintf(stderr,
"Error[bb-open-interface]: interface mode must be BB-READ or BB-WRITE\n");
81 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
83 if (mode->u.id == g_bb_read_sym) {
84 if (g_interfaces_read.find(uid) == g_interfaces_read.end()) {
86 printf(
"Opening interface %s::%s for reading\n", type->u.string, id->u.string);
88 g_interfaces_read[uid] = iface;
91 "Failed to open interface %s::%s: %s",
99 if (g_interfaces_write.find(uid) == g_interfaces_write.end()) {
101 printf(
"Opening interface %s::%s for writing\n", type->u.string, id->u.string);
103 g_interfaces_write[uid] = iface;
106 "Failed to open interface %s::%s: %s\n",
119 action_blackboard_close(TermList terms)
121 int terms_len = sl_slist_length(terms);
122 if (terms_len != 2) {
124 "Error[bb-close-interface]: invalid number of " 125 "arguments: req 2, got %i\n",
130 Term *type = (Term *)get_list_pos(terms, 1);
131 Term *
id = (Term *)get_list_pos(terms, 2);
132 if (type->type != STRING) {
133 fprintf(stderr,
"Error[bb-close-interface]: interface type is not a STRING\n");
136 if (id->type != STRING) {
137 fprintf(stderr,
"Error[bb-close-interface]: interface ID is not a STRING\n");
140 if (id->type != STRING) {
141 fprintf(stderr,
"Error[bb-close-interface]: interface ID is not a STRING\n");
145 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
147 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
149 printf(
"Closing reading interface %s::%s\n", type->u.string, id->u.string);
150 g_blackboard->
close(g_interfaces_read[uid]);
151 g_interfaces_read.erase(uid);
154 "Failed to close interface %s::%s: %s",
160 }
else if (g_interfaces_write.find(uid) != g_interfaces_write.end()) {
162 printf(
"Closing writing interface %s::%s\n", type->u.string, id->u.string);
163 g_blackboard->
close(g_interfaces_write[uid]);
164 g_interfaces_write.erase(uid);
167 "Failed to close interface %s::%s: %s\n",
179 action_blackboard_print(TermList terms)
181 Term *type = (Term *)get_list_pos(terms, 1);
182 Term *
id = (Term *)get_list_pos(terms, 2);
183 if (type->type != STRING) {
184 fprintf(stderr,
"Error[bb-print]: interface type is not a STRING\n");
187 if (id->type != STRING) {
188 fprintf(stderr,
"Error[bb-print]: interface ID is not a STRING\n");
191 if (id->type != STRING) {
192 fprintf(stderr,
"Error[bb-print]: interface ID is not a STRING\n");
196 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
200 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
201 i = g_interfaces_read[uid];
202 }
else if (g_interfaces_write.find(uid) != g_interfaces_write.end()) {
203 i = g_interfaces_write[uid];
205 fprintf(stderr,
"Error[bb-print]: interface %s has not been opened\n", uid.c_str());
206 fprintf(stderr,
"Error[bb-print]: Open interfaces are:\n");
207 for (
auto j : g_interfaces_read) {
208 fprintf(stderr,
"Error[bb-print]: [R] %s\n", j.second->uid());
210 for (
auto j : g_interfaces_write) {
211 fprintf(stderr,
"Error[bb-print]: [W] %s\n", j.second->uid());
213 fprintf(stderr,
"Error[bb-print]: -----\n");
221 std::string fact = std::string(
"(bb-data \"type\" \"") + i->
type() +
"\"" +
" \"id\" \"" 226 for (f = i->
fields(); f != f_end; ++f) {
230 std::string::size_type pos = 0;
231 while ((pos = value.find(
"\"", pos)) != std::string::npos) {
232 value.replace(pos, 1,
"\\\"");
235 value = std::string(
"\"") + value +
"\"";
236 }
else if (f.get_type() ==
IFT_ENUM) {
237 value = std::string(
"\"") + f.get_value_string(
" ") +
"\"";
239 value = f.get_value_string(
" ");
240 std::string::size_type pos;
241 while ((pos = value.find(
",")) != std::string::npos) {
242 value = value.erase(pos, 1);
245 if (f.get_length() > 1) {
246 fact += std::string(
" \"") + f.get_name() +
"\" [ " + value +
" ]";
248 fact += std::string(
" \"") + f.get_name() +
"\" " + value;
253 printf(
"%s\n", fact.c_str());
261 #define ADD_ARRAY(src_type, target_type, array_type) \ 263 target_type * array = (target_type *)OPRS_MALLOC(sizeof(target_type) * f.get_length()); \ 264 src_type##_t *src_array = f.get_##src_type##s(); \ 265 for (unsigned int j = 0; j < f.get_length(); ++j) \ 266 array[j] = src_array[j]; \ 267 data = l_add_to_tail(data, make_##array_type##_array_from_array(f.get_length(), array)); \ 270 #define BUILD_FUNC(singular_type) build_##singular_type 271 #define GET_FUNC(src_type) get_##src_type 273 #define ADD_NUM_DATA(src_type, target_type, array_type, singular_type) \ 275 if (f.get_length() > 1) { \ 276 ADD_ARRAY(src_type, target_type, array_type); \ 278 data = l_add_to_tail(data, BUILD_FUNC(singular_type)(f.GET_FUNC(src_type)())); \ 289 TermList tl = sl_make_slist();
290 tl = build_term_list(tl, build_string(
"type"));
291 tl = build_term_list(tl, build_string(i->
type()));
292 tl = build_term_list(tl, build_string(
"id"));
293 tl = build_term_list(tl, build_string(i->
id()));
294 tl = build_term_list(tl, build_string(
"time"));
295 tl = build_term_list(tl, build_long_long(t->
get_sec()));
296 tl = build_term_list(tl, build_long_long(t->
get_usec()));
300 for (f = i->
fields(); f != f_end; ++f) {
301 data = l_add_to_tail(data, build_string(f.
get_name()));
305 data = l_add_to_tail(data, build_id(f.
get_bool() ? lisp_t_sym : nil_sym));
307 case IFT_INT8: ADD_NUM_DATA(int8,
int,
int, integer);
break;
308 case IFT_UINT8: ADD_NUM_DATA(uint8,
int,
int, integer);
break;
309 case IFT_INT16: ADD_NUM_DATA(int16,
int,
int, integer);
break;
310 case IFT_UINT16: ADD_NUM_DATA(uint16,
int,
int, integer);
break;
311 case IFT_INT32: ADD_NUM_DATA(int32,
int,
int, integer);
break;
312 case IFT_UINT32: ADD_NUM_DATA(uint32,
double,
float, long_long);
break;
313 case IFT_INT64: ADD_NUM_DATA(int64,
double,
float, long_long);
break;
314 case IFT_UINT64: ADD_NUM_DATA(uint64,
double,
float, long_long);
break;
315 case IFT_FLOAT: ADD_NUM_DATA(
float,
double,
float,
float);
break;
316 case IFT_DOUBLE: ADD_NUM_DATA(
double,
double,
float,
float);
break;
318 case IFT_BYTE: ADD_NUM_DATA(uint8,
int,
int, integer);
break;
323 tl = build_term_list(tl, build_l_list(data));
324 add_external_fact((
char *)
"bb-data", tl);
329 action_blackboard_read_all(TermList terms)
332 for (
auto &if_entry : g_interfaces_read) {
344 action_blackboard_read(TermList terms)
346 int terms_len = sl_slist_length(terms);
347 if (terms_len != 2) {
349 "Error[bb-read]: invalid number of " 350 "arguments: req 2, got %i\n",
355 Term *type = (Term *)get_list_pos(terms, 1);
356 Term *
id = (Term *)get_list_pos(terms, 2);
357 if (type->type != STRING) {
358 fprintf(stderr,
"Error[bb-read]: interface type is not a STRING\n");
361 if (id->type != STRING) {
362 fprintf(stderr,
"Error[bb-read]: interface ID is not a STRING\n");
365 if (id->type != STRING) {
366 fprintf(stderr,
"Error[bb-read]: interface ID is not a STRING\n");
370 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
372 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
374 post_interface(g_interfaces_read[uid]);
377 "Failed to read interface %s::%s: %s",
385 "Failed to read interface %s::%s: interface not opened",
397 func_blackboard_value(TermList terms)
399 int terms_len = sl_slist_length(terms);
400 if (terms_len != 2) {
402 "Error[bb-value]: invalid number of " 403 "arguments: req 2, got %i\n",
407 Term *dlist = (Term *)get_list_pos(terms, 1);
408 Term *name = (Term *)get_list_pos(terms, 2);
411 if (dlist->type != LISP_LIST) {
412 fprintf(stderr,
"Error[bb-value]: first argument is not a LISP_LIST\n");
415 if (name->type != STRING) {
416 fprintf(stderr,
"Error[bb-value]: interface ID is not a STRING\n");
419 char *pattern = name->u.string;
421 while (i < l_length(dlist->u.l_list) - 1) {
422 Term *t1 = get_term_from_l_car(l_nth(dlist->u.l_list, i));
423 if (t1->type == STRING) {
424 char *searched = t1->u.string;
425 if (strcmp(pattern, searched) == 0) {
426 restemp = get_term_from_l_car(l_nth((dlist->u).l_list, i + 1));
429 if (restemp->type == STRING) {
430 std::string outputs = std::string(restemp->u.string);
431 std::transform(outputs.begin(), outputs.end(), outputs.begin(), ::tolower);
432 restemp = build_id(declare_atom(outputs.c_str()));
434 return copy_term(restemp);
439 fprintf(stderr,
"Error[bb-value]: wanted entry in bb-data not present\n");
447 printf(
"*** LOADING mod_blackboard\n");
449 std::string fawkes_host;
450 unsigned short fawkes_port = 0;
451 get_fawkes_host_port(fawkes_host, fawkes_port);
453 printf(
"Connecting to Fawkes at %s:%u\n", fawkes_host.c_str(), fawkes_port);
457 fprintf(stderr,
"Error: cannot establish blackboard connection: %s\n", e.
what_no_backtrace());
460 g_bb_read_sym = declare_atom(
"BB-READ");
461 g_bb_write_sym = declare_atom(
"BB-WRITE");
462 g_bb_data_sym = declare_atom(
"bb-data");
463 declare_pred_from_symbol(g_bb_data_sym);
464 make_and_declare_eval_funct(
"bb-value", func_blackboard_value, 2);
465 make_and_declare_action(
"bb-open", action_blackboard_open, 3);
466 make_and_declare_action(
"bb-close", action_blackboard_close, 2);
467 make_and_declare_action(
"bb-read", action_blackboard_read, 2);
468 make_and_declare_action(
"bb-read-all", action_blackboard_read_all, 0);
469 make_and_declare_action(
"bb-print", action_blackboard_print, 2);
470 add_user_end_kernel_hook(finalize);
477 printf(
"*** DESTROYING mod_skiller\n");
478 for (
auto &iface : g_interfaces_read) {
479 g_blackboard->
close(iface.second);
481 g_interfaces_read.clear();
482 for (
auto &iface : g_interfaces_write) {
483 g_blackboard->
close(iface.second);
485 g_interfaces_write.clear();
Interface field iterator.
Fawkes library namespace.
bool get_bool(unsigned int index=0) const
Get value of current field as bool.
8 bit unsigned integer field
16 bit unsigned integer field
const char * id() const
Get identifier of interface.
interface_fieldtype_t get_type() const
Get type of current field.
A class for handling time.
byte field, alias for uint8
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
Base class for all Fawkes BlackBoard interfaces.
const char * type() const
Get type of interface.
Base class for exceptions in Fawkes.
void read()
Read from BlackBoard into local copy.
const char * get_name() const
Get name of current field.
virtual const char * what_no_backtrace() const
Get primary string (does not implicitly print the back trace).
64 bit unsigned integer field
const Time * timestamp() const
Get timestamp of last write.
bool changed() const
Check if data has been changed.
long get_sec() const
Get seconds.
InterfaceFieldIterator fields_end()
Invalid iterator.
long get_usec() const
Get microseconds.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
The BlackBoard abstract class.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
static std::string to_string(unsigned int i)
Convert unsigned int value to a string.
32 bit unsigned integer field
field with interface specific enum type
virtual void close(Interface *interface)=0
Close interface.