24#include "blackboard.h"
26#include <logging/logger.h>
27#include <plugins/eclipse-clp/blackboard_listener_thread.h>
28#include <plugins/eclipse-clp/eclipse_thread.h>
40BlackBoard * EclExternalBlackBoard::m_blackboard = NULL;
44EclExternalBlackBoard::EclExternalBlackBoard(
BlackBoard *blackboard,
Logger *logger)
46 if (m_instance != NULL) {
47 throw Exception(
"There is already an instance of type "
48 "EclExternalBlackBoard instantiated");
50 m_blackboard = blackboard;
100std::map<std::string, Interface *> &
110bool process_message_args(
Message *msg, EC_word arg_list);
116 char * interface_type;
119 if (EC_succeed != EC_arg(1).is_atom(&mode)) {
120 fprintf(stderr,
"p_bb_open_interface(): no mode given\n");
124 if (EC_succeed != EC_arg(2).is_string(&interface_type)) {
125 fprintf(stderr,
"p_bb_open_interface(): no type given\n");
129 if (EC_succeed != EC_arg(3).is_string(&interface_id)) {
130 fprintf(stderr,
"p_bb_open_interface(): no id given\n");
134 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
136 std::string uid = std::string(interface_type) +
"::" + interface_id;
137 if (interfaces.find(uid) == interfaces.end()) {
141 if (0 == strcmp(
"w", mode.name())) {
143 EclExternalBlackBoard::instance()->blackboard_instance()->open_for_writing(interface_type,
147 EclExternalBlackBoard::instance()->blackboard_instance()->open_for_reading(interface_type,
151 interfaces[iface->
uid()] = iface;
158 if (interfaces.find(uid) == interfaces.end()) {
166p_bb_close_interface()
170 if (EC_succeed != EC_arg(1).is_string(&uid)) {
171 fprintf(stderr,
"p_bb_close_interface(): no id given\n");
175 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
177 if (interfaces.find(uid) != interfaces.end()) {
178 EclExternalBlackBoard::instance()->blackboard_instance()->close(interfaces[uid]);
179 EclExternalBlackBoard::instance()->interfaces().erase(uid);
190 if (EC_succeed != EC_arg(1).is_string(&uid)) {
191 fprintf(stderr,
"p_bb_has_writer(): no uid given\n");
195 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
197 if (interfaces.find(uid) != interfaces.end()) {
198 return interfaces[uid]->has_writer() ? EC_succeed : EC_fail;
205p_bb_instance_serial()
208 if (EC_succeed != EC_arg(1).is_string(&uid)) {
209 fprintf(stderr,
"p_bb_instance_serial(): no interface uid given\n");
213 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
215 if (interfaces.find(uid) != interfaces.end()) {
216 if (EC_succeed != EC_arg(2).unify(interfaces[uid]->serial().get_string().c_str())) {
217 fprintf(stderr,
"p_bb_instance_serial(): could not bind return value\n");
228p_bb_read_interfaces()
230 for (std::map<std::string, Interface *>::iterator it =
231 EclExternalBlackBoard::instance()->interfaces().begin();
232 it != EclExternalBlackBoard::instance()->interfaces().end();
244 if (EC_succeed != EC_arg(1).is_string(&uid)) {
245 fprintf(stderr,
"p_read_interface(): no interface UID given\n");
249 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
251 if (interfaces.find(uid) == interfaces.end()) {
252 fprintf(stderr,
"p_bb_read_interface: interface %s has not been opened\n", uid);
256 interfaces[uid]->read();
262p_bb_write_interfaces()
264 for (std::map<std::string, Interface *>::iterator it =
265 EclExternalBlackBoard::instance()->interfaces().begin();
266 it != EclExternalBlackBoard::instance()->interfaces().end();
268 if (it->second->is_writer()) {
277p_bb_write_interface()
280 if (EC_succeed != EC_arg(1).is_string(&uid)) {
281 fprintf(stderr,
"p_read_interface(): no interface UID given\n");
285 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
287 if (interfaces.find(uid) == interfaces.end()) {
288 fprintf(stderr,
"p_bb_read_interface: interface %s has not been opened\n", uid);
292 if (!interfaces[uid]->is_writer()) {
293 fprintf(stderr,
"p_bb_set(): interface %s not a writer\n", uid);
297 interfaces[uid]->write();
302p_bb_interface_changed()
305 if (EC_succeed != EC_arg(1).is_string(&uid)) {
306 fprintf(stderr,
"p_interface_changed(): no interface UID given\n");
310 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
312 if (interfaces.find(uid) == interfaces.end()) {
313 fprintf(stderr,
"p_bb_interface_changed: interface %s has not been opened\n", uid);
317 return interfaces[uid]->refreshed() ? EC_succeed : EC_fail;
326 if (EC_succeed != EC_arg(1).is_string(&uid)) {
327 fprintf(stderr,
"p_bb_get(): no interface uid given\n");
331 if (EC_succeed != EC_arg(2).is_string(&field)) {
332 fprintf(stderr,
"p_bb_get(): no field given\n");
336 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
338 if (interfaces.find(uid) != interfaces.end()) {
343 if (0 == strcmp(field, fit.
get_name())) {
347 if (EC_succeed != EC_arg(3).unify(EC_atom((
char *)
"true"))) {
348 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
352 if (EC_succeed != EC_arg(3).unify(EC_atom((
char *)
"false"))) {
353 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
360 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_int8()))) {
361 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
367 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_uint8()))) {
368 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
374 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_int16()))) {
375 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
381 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_uint16()))) {
382 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
388 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_int32()))) {
389 fprintf(stderr,
"p_bb_get: could not bind value\n");
395 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_uint32()))) {
396 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
402 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_int64()))) {
403 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
409 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_uint64()))) {
410 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
419 for (
int i = fit.
get_length() - 1; i >= 0; --i)
420 res = ::list(EC_word(f_array[i]), res);
421 if (EC_succeed != EC_arg(3).unify(res)) {
422 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
426 if (EC_succeed != EC_arg(3).unify(EC_word((
double)fit.
get_float()))) {
427 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
437 for (
int i = fit.
get_length() - 1; i >= 0; --i)
438 res = ::list(EC_word(double_array[i]), res);
439 if (EC_succeed != EC_arg(3).unify(res)) {
440 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
444 if (EC_succeed != EC_arg(3).unify(EC_word((
double)fit.
get_double()))) {
445 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
452 if (EC_succeed != EC_arg(3).unify(EC_word(fit.
get_string()))) {
453 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
462 for (
int i = fit.
get_length() - 1; i >= 0; i--)
463 res = ::list(EC_word((
long)array[i]), res);
464 if (EC_succeed != EC_arg(3).unify(res)) {
465 printf(
"p_bb_get(): could not bind return value\n");
469 if (EC_succeed != EC_arg(3).unify(EC_word((
long)fit.
get_byte()))) {
470 printf(
"p_bb_get(): could not bind return value\n");
478 fprintf(stderr,
"p_bb_get(): could not bind return value\n");
485 "p_bb_get(): could not find type of interface! Type: %s (%d)",
495 fprintf(stderr,
"p_bb_get(): interface %s has no field %s\n", uid, field);
500 fprintf(stderr,
"p_bb_get(): no interface with id %s found\n", uid);
513 if (EC_succeed != EC_arg(1).is_string(&uid)) {
514 fprintf(stderr,
"p_bb_set(): no interface id given\n");
518 if (EC_succeed != EC_arg(2).is_string(&field)) {
519 fprintf(stderr,
"p_bb_set(): no field given\n");
523 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
525 if (interfaces.find(uid) != interfaces.end()) {
529 fprintf(stderr,
"p_bb_set(): interface %s not a writer\n", uid);
535 if (0 == strcmp(field, fit.
get_name())) {
539 if (EC_succeed != EC_arg(3).is_atom(&val)) {
540 fprintf(stderr,
"p_bb_set(): no value_given\n");
544 if (0 == strcmp(
"true", val.name())) {
546 }
else if (0 == strcmp(
"false", val.name())) {
549 fprintf(stderr,
"p_bb_set(): boolean value neither true nor false\n");
556 if (EC_succeed != EC_arg(3).is_long(&val)) {
557 fprintf(stderr,
"p_bb_set(): no value given\n");
566 if (EC_succeed != EC_arg(3).is_long(&val)) {
567 fprintf(stderr,
"p_bb_set(): no value given\n");
576 if (EC_succeed != EC_arg(3).is_long(&val)) {
577 fprintf(stderr,
"p_bb_set(): no value given\n");
586 if (EC_succeed != EC_arg(3).is_long(&val)) {
587 fprintf(stderr,
"p_bb_set(): no value given\n");
596 if (EC_succeed != EC_arg(3).is_long(&val)) {
597 fprintf(stderr,
"p_bb_set(): no value given\n");
606 if (EC_succeed != EC_arg(3).is_long(&val)) {
607 fprintf(stderr,
"p_bb_set(): no value given\n");
616 if (EC_succeed != EC_arg(3).is_long(&val)) {
617 fprintf(stderr,
"p_bb_set(): no value given\n");
626 if (EC_succeed != EC_arg(3).is_long(&val)) {
627 fprintf(stderr,
"p_bb_set(): no value given\n");
636 if (EC_succeed != EC_arg(3).is_double(&val)) {
637 fprintf(stderr,
"p_bb_set(): no value given\n");
646 if (EC_succeed != EC_arg(3).is_string(&val)) {
647 fprintf(stderr,
"p_bb_set(): no value given\n");
655 case IFT_ENUM: fprintf(stderr,
"p_bb_set(): NOT YET IMPLEMENTET\n");
break;
664 fprintf(stderr,
"p_bb_set(): interface %s has no field %s\n", uid, field);
669 fprintf(stderr,
"p_bb_set(): no interface with id %s found\n", uid);
683 if (EC_succeed != EC_arg(1).is_string(&uid)) {
684 fprintf(stderr,
"p_bb_send_message(): no interface id given\n");
688 if (EC_succeed != EC_arg(2).is_string(&message_type)) {
689 fprintf(stderr,
"p_bb_send_message(): no message type given\n");
693 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
695 if (interfaces.find(uid) != interfaces.end()) {
699 fprintf(stderr,
"p_bb_send_message(): interface with uid %s is a writer\n", uid);
708 if (EC_succeed == EC_arg(3).is_list(head, tail)) {
709 if (!process_message_args(msg, ::list(head, tail))) {
716 (iface)->msgq_enqueue(msg);
718 EC_arg(4).unify((
int)(msg->
id()));
731 fprintf(stderr,
"p_bb_send_message(): no interface with name %s\n", uid);
743 if (EC_succeed != EC_arg(1).is_string(&uid)) {
744 fprintf(stderr,
"p_bb_recv_messages(): no interface uid given\n");
748 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
750 if (interfaces.find(uid) != interfaces.end()) {
754 fprintf(stderr,
"p_bb_recv_messages(): interface with uid %s is not a writer\n", uid);
758 EC_word msg_list = nil();
764 EC_word args = nil();
771 value = EC_atom((
char *)
"true");
773 value = EC_atom((
char *)
"false");
799 case IFT_ENUM: fprintf(stderr,
"p_bb_recv_messages(): NOT YET IMPLEMENTED\n");
break;
801 default: fprintf(stderr,
"p_bb_recv_messages(): unknown field type\n");
804 EC_word field = ::list(EC_word(fit.
get_name()), ::list(value, nil()));
805 args = ::list(field, args);
809 msg_list = ::list(::list(EC_word(msg->
type()), ::list(args, nil())), msg_list);
814 if (EC_succeed != EC_arg(2).unify(msg_list)) {
815 fprintf(stderr,
"p_bb_recv_messages(): could not bind return value\n");
820 fprintf(stderr,
"p_bb_recv_messages(): no interface with id %s found\n", uid);
828p_bb_observe_pattern()
830 char *type_pattern, *id_pattern;
831 if (EC_succeed != EC_arg(1).is_string(&type_pattern)) {
832 EclExternalBlackBoard::logger()->log_error(EclExternalBlackBoard::name(),
833 "%s: First argument must be a string.",
837 if (EC_succeed != EC_arg(2).is_string(&id_pattern)) {
838 EclExternalBlackBoard::logger()->log_error(EclExternalBlackBoard::name(),
839 "%s: Second argument must be a string.",
849p_bb_listen_for_change()
852 if (EC_succeed != EC_arg(1).is_string(&type)) {
853 EclExternalBlackBoard::logger()->log_error(EclExternalBlackBoard::name(),
854 "%s: First argument must be a string.",
858 if (EC_succeed != EC_arg(2).is_string(&
id)) {
859 EclExternalBlackBoard::logger()->log_error(EclExternalBlackBoard::name(),
860 "%s: Second argument must be a string.",
865 std::map<std::string, Interface *> &interfaces = EclExternalBlackBoard::instance()->interfaces();
867 std::string uid = std::string(type) +
"::" + id;
868 std::map<std::string, Interface *>::iterator iface_it = interfaces.find(uid);
870 if (iface_it == interfaces.end()) {
871 EclExternalBlackBoard::logger()->log_error(EclExternalBlackBoard::name(),
872 "%s: Interface %s has not been opened.",
883process_message_args(
Message *msg, EC_word arg_list)
888 for (; EC_succeed == arg_list.is_list(head, tail); arg_list = tail) {
895 if (EC_succeed != head.is_list(field, t1) || EC_succeed != t1.is_list(value, t2)) {
896 fprintf(stderr,
"p_bb_send_messge(): could not parse argument list\n");
901 if (EC_succeed != field.is_string(&field_name)) {
902 fprintf(stderr,
"p_bb_send_message(): malformed argument list\n");
908 if (0 == strcmp(fit.
get_name(), field_name)) {
912 if (EC_succeed != value.is_atom(&val)) {
913 fprintf(stderr,
"p_bb_send_message(): no value_given (bool)\n");
917 if (0 == strcmp(
"true", val.name())) {
919 }
else if (0 == strcmp(
"false", val.name())) {
922 fprintf(stderr,
"p_bb_send_message(): boolean value neither true nor false\n");
931 if (EC_succeed != value.is_long(&val)) {
932 fprintf(stderr,
"p_bb_send_message(): no value given (int8)\n");
943 if (EC_succeed != value.is_long(&val)) {
944 fprintf(stderr,
"p_bb_send_message(): no value given (uint8)\n");
955 if (EC_succeed != value.is_long(&val)) {
956 fprintf(stderr,
"p_bb_send_message(): no value given (int16)\n");
967 if (EC_succeed != value.is_long(&val)) {
968 fprintf(stderr,
"p_bb_send_message(): no value given (uint16)\n");
979 if (EC_succeed != value.is_long(&val)) {
980 fprintf(stderr,
"p_bb_send_message(): no value given (int32)\n");
991 if (EC_succeed != value.is_long(&val)) {
992 fprintf(stderr,
"p_bb_send_message(): no value given (uint32)\n");
1003 if (EC_succeed != value.is_long(&val)) {
1004 fprintf(stderr,
"p_bb_send_message(): no value given (int64)\n");
1015 if (EC_succeed != value.is_long(&val)) {
1016 fprintf(stderr,
"p_bb_send_message(): no value given (uint64)\n");
1027 if (EC_succeed != value.is_double(&val)) {
1028 fprintf(stderr,
"p_bb_send_message(): no value given (float)\n");
1039 if (EC_succeed != value.is_string(&val)) {
1040 fprintf(stderr,
"p_bb_send_message(): no value given (string)\n");
1050 case IFT_ENUM: fprintf(stderr,
"p_bb_send_message(): NOT YET IMPLEMENTET\n");
break;
1060 fprintf(stderr,
"p_bb_send_message(): message has no field with name %s\n", field_name);
static BlackboardListenerThread * instance()
Get the singleton instance of this thread.
void listen_for_change(Interface *interface) noexcept
Register.
void observe_pattern(const char *type_pattern, const char *id_pattern) noexcept
Trigger events if an interface matching the pattern is created or destroyed.
The BlackBoard abstract class.
Wrapper class for using the blackboard in the implementation of the external predicates.
std::map< std::string, Interface * > & interfaces()
Obtain the list of opened interfaces.
static void create_initial_object(BlackBoard *bb, Logger *logger)
Creates the initial EclExternalBlackBoard object.
~EclExternalBlackBoard()
Destructor.
static BlackBoard * blackboard_instance()
Access the BlackBoard instance.
static void cleanup_instance()
Delete the current EclExternalBlackBoard instance and set it to NULL.
static EclExternalBlackBoard * instance()
Get the EclExternalBlackBoard instance.
Base class for exceptions in Fawkes.
void print_trace() noexcept
Prints trace to stderr.
virtual const char * what_no_backtrace() const noexcept
Get primary string (does not implicitly print the back trace).
Interface field iterator.
float get_float(unsigned int index=0) const
Get value of current field as float.
int16_t get_int16(unsigned int index=0) const
Get value of current field as integer.
void set_int64(int64_t i, unsigned int index=0)
Set value of current field as integer.
int8_t get_int8(unsigned int index=0) const
Get value of current field as integer.
float * get_floats() const
Get value of current field as float array.
int32_t get_int32(unsigned int index=0) const
Get value of current field as integer.
uint8_t * get_bytes() const
Get value of current field as byte array.
void set_string(const char *s)
Set value of current field as string.
size_t get_length() const
Get length of current field.
int64_t get_int64(unsigned int index=0) const
Get value of current field as integer.
uint64_t get_uint64(unsigned int index=0) const
Get value of current field as unsigned integer.
void set_int16(int16_t i, unsigned int index=0)
Set value of current field as integer.
uint16_t get_uint16(unsigned int index=0) const
Get value of current field as unsigned integer.
double get_double(unsigned int index=0) const
Get value of current field as double.
uint32_t get_uint32(unsigned int index=0) const
Get value of current field as unsigned integer.
void set_uint64(uint64_t i, unsigned int index=0)
Set value of current field as unsigned integer.
interface_fieldtype_t get_type() const
Get type of current field.
const char * get_name() const
Get name of current field.
void set_float(float f, unsigned int index=0)
Set value of current field as float.
void set_uint16(uint16_t i, unsigned int index=0)
Set value of current field as unsigned integer.
void set_int32(int32_t i, unsigned int index=0)
Set value of current field as integer.
const char * get_string() const
Get value of current field as string.
uint8_t get_byte(unsigned int index=0) const
Get value of current field as byte.
uint8_t get_uint8(unsigned int index=0) const
Get value of current field as unsigned integer.
bool get_bool(unsigned int index=0) const
Get value of current field as bool.
const char * get_value_string(const char *array_sep=", ")
Get value of current field as string.
double * get_doubles() const
Get value of current field as double array.
void set_bool(bool b, unsigned int index=0)
Set value of current field as bool.
void set_int8(int8_t i, unsigned int index=0)
Set value of current field as integer.
void set_uint8(uint8_t i, unsigned int index=0)
Set value of current field as unsigned integer.
void set_uint32(uint32_t i, unsigned int index=0)
Set value of current field as unsigned integer.
const char * get_typename() const
Get type of current field as string.
Base class for all Fawkes BlackBoard interfaces.
void msgq_pop()
Erase first message from queue.
Message * msgq_first()
Get the first message from the message queue.
InterfaceFieldIterator fields_end()
Invalid iterator.
virtual Message * create_message(const char *type) const =0
Create message based on type name.
bool is_writer() const
Check if this is a writing instance.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
bool msgq_empty()
Check if queue is empty.
const char * uid() const
Get unique identifier of interface.
Base class for all messages passed through interfaces in Fawkes BlackBoard.
InterfaceFieldIterator fields()
Get iterator over all fields of this interface instance.
const char * type() const
Get message type.
InterfaceFieldIterator fields_end()
Invalid iterator.
unsigned int id() const
Get message ID.
void unref()
Decrement reference count and conditionally delete this instance.
void ref()
Increment reference count.
Fawkes library namespace.
@ IFT_INT8
8 bit integer field
@ IFT_UINT32
32 bit unsigned integer field
@ IFT_BYTE
byte field, alias for uint8
@ IFT_UINT64
64 bit unsigned integer field
@ IFT_UINT16
16 bit unsigned integer field
@ IFT_INT32
32 bit integer field
@ IFT_INT64
64 bit integer field
@ IFT_INT16
16 bit integer field
@ IFT_ENUM
field with interface specific enum type
@ IFT_UINT8
8 bit unsigned integer field