22 #include <plugins/openprs/mod_utils.h> 24 #include <blackboard/remote.h> 25 #include <utils/misc/string_conversions.h> 26 #include <utils/time/time.h> 28 #include <oprs-type_f-pub.h> 29 #include <oprs-array_f-pub.h> 30 #include <oprs_f-pub.h> 31 #include <slistPack_f.h> 32 #include <lisp-list_f-pub.h> 36 extern "C" void finalize();
41 std::map<std::string, Interface *> g_interfaces_read;
42 std::map<std::string, Interface *> g_interfaces_write;
44 Symbol g_bb_write_sym;
49 action_blackboard_open(TermList terms)
51 int terms_len = sl_slist_length(terms);
53 fprintf(stderr,
"Error[bb-open-interface]: invalid number of " 54 "arguments: req 3, got %i\n", terms_len);
58 Term *type = (Term *)get_list_pos(terms, 1);
59 Term *
id = (Term *)get_list_pos(terms, 2);
60 Term *mode = (Term *)get_list_pos(terms, 3);
61 if (type->type != STRING) {
62 fprintf(stderr,
"Error[bb-open-interface]: interface type is not a STRING\n");
65 if (id->type != STRING) {
66 fprintf(stderr,
"Error[bb-open-interface]: interface ID is not a STRING\n");
69 if (id->type != STRING) {
70 fprintf(stderr,
"Error[bb-open-interface]: interface ID is not a STRING\n");
73 if (mode->type != TT_ATOM) {
74 fprintf(stderr,
"Error[bb-open-interface]: interface mode is not a symbol\n");
77 if (mode->u.id != g_bb_read_sym && mode->u.id != g_bb_write_sym) {
78 fprintf(stderr,
"Error[bb-open-interface]: interface mode must be BB-READ or BB-WRITE\n");
82 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
84 if (mode->u.id == g_bb_read_sym) {
85 if (g_interfaces_read.find(uid) == g_interfaces_read.end()) {
87 printf(
"Opening interface %s::%s for reading\n", type->u.string, id->u.string);
89 g_interfaces_read[uid] = iface;
91 fprintf(stderr,
"Failed to open interface %s::%s: %s",
97 if (g_interfaces_write.find(uid) == g_interfaces_write.end()) {
99 printf(
"Opening interface %s::%s for writing\n", type->u.string, id->u.string);
101 g_interfaces_write[uid] = iface;
103 fprintf(stderr,
"Failed to open interface %s::%s: %s\n",
116 action_blackboard_close(TermList terms)
118 int terms_len = sl_slist_length(terms);
119 if (terms_len != 2) {
120 fprintf(stderr,
"Error[bb-close-interface]: invalid number of " 121 "arguments: req 2, got %i\n", terms_len);
125 Term *type = (Term *)get_list_pos(terms, 1);
126 Term *
id = (Term *)get_list_pos(terms, 2);
127 if (type->type != STRING) {
128 fprintf(stderr,
"Error[bb-close-interface]: interface type is not a STRING\n");
131 if (id->type != STRING) {
132 fprintf(stderr,
"Error[bb-close-interface]: interface ID is not a STRING\n");
135 if (id->type != STRING) {
136 fprintf(stderr,
"Error[bb-close-interface]: interface ID is not a STRING\n");
140 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
142 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
144 printf(
"Closing reading interface %s::%s\n", type->u.string, id->u.string);
145 g_blackboard->
close(g_interfaces_read[uid]);
146 g_interfaces_read.erase(uid);
148 fprintf(stderr,
"Failed to close interface %s::%s: %s",
152 }
else if (g_interfaces_write.find(uid) != g_interfaces_write.end()) {
154 printf(
"Closing writing interface %s::%s\n", type->u.string, id->u.string);
155 g_blackboard->
close(g_interfaces_write[uid]);
156 g_interfaces_write.erase(uid);
158 fprintf(stderr,
"Failed to close interface %s::%s: %s\n",
170 action_blackboard_print(TermList terms)
172 Term *type = (Term *)get_list_pos(terms, 1);
173 Term *
id = (Term *)get_list_pos(terms, 2);
174 if (type->type != STRING) {
175 fprintf(stderr,
"Error[bb-print]: interface type is not a STRING\n");
178 if (id->type != STRING) {
179 fprintf(stderr,
"Error[bb-print]: interface ID is not a STRING\n");
182 if (id->type != STRING) {
183 fprintf(stderr,
"Error[bb-print]: interface ID is not a STRING\n");
187 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
191 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
192 i = g_interfaces_read[uid];
193 }
else if (g_interfaces_write.find(uid) != g_interfaces_write.end()) {
194 i = g_interfaces_write[uid];
196 fprintf(stderr,
"Error[bb-print]: interface %s has not been opened\n", uid.c_str());
197 fprintf(stderr,
"Error[bb-print]: Open interfaces are:\n");
198 for (
auto j : g_interfaces_read) {
199 fprintf(stderr,
"Error[bb-print]: [R] %s\n", j.second->uid());
201 for (
auto j : g_interfaces_write) {
202 fprintf(stderr,
"Error[bb-print]: [W] %s\n", j.second->uid());
204 fprintf(stderr,
"Error[bb-print]: -----\n");
212 std::string fact = std::string(
"(bb-data \"type\" \"") + i->
type() +
"\"" +
213 " \"id\" \"" + i->
id() +
"\"" +
219 for (f = i->
fields(); f != f_end; ++f) {
223 std::string::size_type pos = 0;
224 while ((pos = value.find(
"\"", pos)) != std::string::npos) {
225 value.replace(pos, 1,
"\\\"");
228 value = std::string(
"\"") + value +
"\"";
229 }
else if (f.get_type() ==
IFT_ENUM) {
230 value = std::string(
"\"") + f.get_value_string(
" ") +
"\"";
232 value = f.get_value_string(
" ");
233 std::string::size_type pos;
234 while ((pos = value.find(
",")) != std::string::npos) {
235 value = value.erase(pos, 1);
238 if (f.get_length() > 1) {
239 fact += std::string(
" \"") + f.get_name() +
"\" [ " + value +
" ]";
241 fact += std::string(
" \"") + f.get_name() +
"\" " + value;
246 printf(
"%s\n", fact.c_str());
255 #define ADD_ARRAY(src_type, target_type, array_type) \ 257 target_type *array = (target_type *)OPRS_MALLOC(sizeof(target_type) * f.get_length()); \ 258 src_type ## _t *src_array = f.get_ ## src_type ## s(); \ 259 for (unsigned int j = 0; j < f.get_length(); ++j) array[j] = src_array[j]; \ 260 data = l_add_to_tail(data, make_ ## array_type ## _array_from_array(f.get_length(), array)); \ 263 #define BUILD_FUNC(singular_type) build_ ## singular_type 264 #define GET_FUNC(src_type) get_ ## src_type 266 #define ADD_NUM_DATA(src_type, target_type, array_type, singular_type) \ 268 if (f.get_length() > 1) { \ 269 ADD_ARRAY(src_type, target_type, array_type); \ 271 data = l_add_to_tail(data, BUILD_FUNC(singular_type)(f.GET_FUNC(src_type)())); \ 283 TermList tl = sl_make_slist();
284 tl = build_term_list(tl, build_string(
"type"));
285 tl = build_term_list(tl, build_string(i->
type()));
286 tl = build_term_list(tl, build_string(
"id"));
287 tl = build_term_list(tl, build_string(i->
id()));
288 tl = build_term_list(tl, build_string(
"time"));
289 tl = build_term_list(tl, build_long_long(t->
get_sec()));
290 tl = build_term_list(tl, build_long_long(t->
get_usec()));
294 for (f = i->
fields(); f != f_end; ++f) {
295 data = l_add_to_tail(data, build_string(f.
get_name()));
299 data = l_add_to_tail(data, build_id(f.
get_bool() ? lisp_t_sym : nil_sym));
302 ADD_NUM_DATA(int8,
int,
int, integer);
305 ADD_NUM_DATA(uint8,
int,
int, integer);
308 ADD_NUM_DATA(int16,
int,
int, integer);
311 ADD_NUM_DATA(uint16,
int,
int, integer);
314 ADD_NUM_DATA(int32,
int,
int, integer);
317 ADD_NUM_DATA(uint32,
double,
float, long_long);
320 ADD_NUM_DATA(int64,
double,
float, long_long);
323 ADD_NUM_DATA(uint64,
double,
float, long_long);
326 ADD_NUM_DATA(
float,
double,
float,
float);
329 ADD_NUM_DATA(
double,
double,
float,
float);
335 ADD_NUM_DATA(uint8,
int,
int, integer);
344 tl = build_term_list(tl, build_l_list(data));
345 add_external_fact((
char *)
"bb-data", tl);
352 action_blackboard_read_all(TermList terms)
355 for (
auto &if_entry : g_interfaces_read) {
369 action_blackboard_read(TermList terms)
371 int terms_len = sl_slist_length(terms);
372 if (terms_len != 2) {
373 fprintf(stderr,
"Error[bb-read]: invalid number of " 374 "arguments: req 2, got %i\n", terms_len);
378 Term *type = (Term *)get_list_pos(terms, 1);
379 Term *
id = (Term *)get_list_pos(terms, 2);
380 if (type->type != STRING) {
381 fprintf(stderr,
"Error[bb-read]: interface type is not a STRING\n");
384 if (id->type != STRING) {
385 fprintf(stderr,
"Error[bb-read]: interface ID is not a STRING\n");
388 if (id->type != STRING) {
389 fprintf(stderr,
"Error[bb-read]: interface ID is not a STRING\n");
393 std::string uid = std::string(type->u.string) +
"::" +
id->u.string;
395 if (g_interfaces_read.find(uid) != g_interfaces_read.end()) {
397 post_interface(g_interfaces_read[uid]);
399 fprintf(stderr,
"Failed to read interface %s::%s: %s",
404 fprintf(stderr,
"Failed to read interface %s::%s: interface not opened",
405 type->u.string, id->u.string);
417 func_blackboard_value(TermList terms)
419 int terms_len = sl_slist_length(terms);
420 if (terms_len != 2) {
421 fprintf(stderr,
"Error[bb-value]: invalid number of " 422 "arguments: req 2, got %i\n", terms_len);
425 Term *dlist = (Term *)get_list_pos(terms, 1);
426 Term *name = (Term *)get_list_pos(terms, 2);
429 if (dlist->type != LISP_LIST) {
430 fprintf(stderr,
"Error[bb-value]: first argument is not a LISP_LIST\n");
433 if (name->type != STRING) {
434 fprintf(stderr,
"Error[bb-value]: interface ID is not a STRING\n");
437 char* pattern = name->u.string;
439 while (i < l_length(dlist->u.l_list) - 1) {
440 Term *t1 = get_term_from_l_car(l_nth(dlist->u.l_list, i));
442 if (t1->type == STRING) {
443 char* searched = t1->u.string;
444 if (strcmp(pattern, searched) == 0) {
445 restemp = get_term_from_l_car(l_nth((dlist->u).l_list, i+1));
448 if (restemp->type == STRING) {
449 std::string outputs = std::string(restemp->u.string);
450 std::transform(outputs.begin(), outputs.end(), outputs.begin(), ::tolower);
451 restemp = build_id(declare_atom(outputs.c_str()));
453 return copy_term(restemp);
458 fprintf(stderr,
"Error[bb-value]: wanted entry in bb-data not present\n");
466 printf(
"*** LOADING mod_blackboard\n");
468 std::string fawkes_host;
469 unsigned short fawkes_port = 0;
470 get_fawkes_host_port(fawkes_host, fawkes_port);
472 printf(
"Connecting to Fawkes at %s:%u\n", fawkes_host.c_str(), fawkes_port);
476 fprintf(stderr,
"Error: cannot establish blackboard connection: %s\n",
480 g_bb_read_sym = declare_atom(
"BB-READ");
481 g_bb_write_sym = declare_atom(
"BB-WRITE");
482 g_bb_data_sym = declare_atom(
"bb-data");
483 declare_pred_from_symbol(g_bb_data_sym);
484 make_and_declare_eval_funct(
"bb-value", func_blackboard_value ,2);
485 make_and_declare_action(
"bb-open", action_blackboard_open, 3);
486 make_and_declare_action(
"bb-close", action_blackboard_close, 2);
487 make_and_declare_action(
"bb-read", action_blackboard_read, 2);
488 make_and_declare_action(
"bb-read-all", action_blackboard_read_all, 0);
489 make_and_declare_action(
"bb-print", action_blackboard_print, 2);
490 add_user_end_kernel_hook(finalize);
497 printf(
"*** DESTROYING mod_skiller\n");
498 for (
auto &iface : g_interfaces_read) {
499 g_blackboard->
close(iface.second);
501 g_interfaces_read.clear();
502 for (
auto &iface : g_interfaces_write) {
503 g_blackboard->
close(iface.second);
505 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.