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>
40 BlackBoard * EclExternalBlackBoard::m_blackboard = NULL;
44 EclExternalBlackBoard::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;
100 std::map<std::string, Interface *> &
110 bool process_message_args(
Message *msg, EC_word arg_list);
113 p_bb_open_interface()
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");
136 std::string uid = std::string(interface_type) +
"::" + interface_id;
137 if (interfaces.find(uid) == interfaces.end()) {
141 if (0 == strcmp(
"w", mode.name())) {
151 interfaces[iface->
uid()] = iface;
158 if (interfaces.find(uid) == interfaces.end()) {
166 p_bb_close_interface()
170 if (EC_succeed != EC_arg(1).is_string(&uid)) {
171 fprintf(stderr,
"p_bb_close_interface(): no id given\n");
177 if (interfaces.find(uid) != interfaces.end()) {
190 if (EC_succeed != EC_arg(1).is_string(&uid)) {
191 fprintf(stderr,
"p_bb_has_writer(): no uid given\n");
197 if (interfaces.find(uid) != interfaces.end()) {
198 return interfaces[uid]->has_writer() ? EC_succeed : EC_fail;
205 p_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");
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");
228 p_bb_read_interfaces()
230 for (std::map<std::string, Interface *>::iterator it =
241 p_bb_read_interface()
244 if (EC_succeed != EC_arg(1).is_string(&uid)) {
245 fprintf(stderr,
"p_read_interface(): no interface UID given\n");
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();
262 p_bb_write_interfaces()
264 for (std::map<std::string, Interface *>::iterator it =
268 if (it->second->is_writer()) {
277 p_bb_write_interface()
280 if (EC_succeed != EC_arg(1).is_string(&uid)) {
281 fprintf(stderr,
"p_read_interface(): no interface UID given\n");
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();
302 p_bb_interface_changed()
305 if (EC_succeed != EC_arg(1).is_string(&uid)) {
306 fprintf(stderr,
"p_interface_changed(): no interface UID given\n");
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");
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");
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");
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");
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);
828 p_bb_observe_pattern()
830 char *type_pattern, *id_pattern;
831 if (EC_succeed != EC_arg(1).is_string(&type_pattern)) {
833 "%s: First argument must be a string.",
837 if (EC_succeed != EC_arg(2).is_string(&id_pattern)) {
839 "%s: Second argument must be a string.",
849 p_bb_listen_for_change()
852 if (EC_succeed != EC_arg(1).is_string(&type)) {
854 "%s: First argument must be a string.",
858 if (EC_succeed != EC_arg(2).is_string(&
id)) {
860 "%s: Second argument must be a string.",
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()) {
872 "%s: Interface %s has not been opened.",
883 process_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.
virtual Interface * open_for_reading(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for reading.
virtual Interface * open_for_writing(const char *interface_type, const char *identifier, const char *owner=NULL)=0
Open interface for writing.
virtual void close(Interface *interface)=0
Close interface.
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 const char * name()
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.
virtual void log_error(const char *component, const char *format,...)=0
Log error message.
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