22#ifndef BLACKBOARD_MANAGER_H
23#define BLACKBOARD_MANAGER_H
25#include "protoboard_types.h"
26#include "protobuf_thread.h"
28#include <aspect/blackboard.h>
29#include <aspect/blocked_timing.h>
30#include <aspect/clock.h>
31#include <aspect/configurable.h>
32#include <aspect/logging.h>
33#include <blackboard/utils/on_message_waker.h>
34#include <core/threading/thread.h>
35#include <interfaces/ProtobufPeerInterface.h>
37#include <boost/fusion/include/any.hpp>
38#include <boost/fusion/include/for_each.hpp>
39#include <boost/fusion/include/std_tuple.hpp>
41#include <unordered_map>
50template <
class IfaceT>
51std::string iface_id_for_type();
55std::vector<std::string> proto_dirs();
62template <
class IfaceT,
class MessageTypeList>
78 blackboard_ = blackboard;
79 interface_ = blackboard_->
open_for_writing<IfaceT>(iface_id_for_type<IfaceT>().c_str());
93 if (blackboard_ && interface_)
94 blackboard_->
close(interface_);
151 template <
class IfaceT,
class MessageT>
161 template <
class IfaceT,
class MessageT1,
class... MessageTs>
171template <
class... IfaceManagerTs>
179 virtual void init()
override;
189 std::tuple<IfaceManagerTs...> bb_sending_interfaces_;
216 virtual void init()
override;
218 virtual void loop()
override;
225 template <
class InterfaceT,
class MessageT>
233 pb_conversion_map bb_receiving_interfaces_;
235 unsigned int next_peer_idx_;
236 std::unique_ptr<AbstractProtobufSender> pb_sender_;
240 template <
class MessageT,
class InterfaceT>
241 void handle_message_type(InterfaceT *iface);
243 template <
class InterfaceT>
249 on_interface(InterfaceT *iface,
BlackboardManager *manager) : iface(iface), manager(manager)
253 template <
class MessageT>
257 manager->handle_message_type<MessageT>(iface);
261 template <
class MessageT1,
class... MessageTs>
262 typename std::enable_if<(
sizeof...(MessageTs) > 0)>::type
265 handle_msg_types<MessageT1>();
266 handle_msg_types<MessageTs...>();
271template <
class... IfaceManagerTs>
277template <
class... IfaceManagerTs>
281 boost::fusion::for_each(bb_sending_interfaces_, [
this](
auto &iface_mgr) {
282 iface_mgr.init(this->bb_manager->get_blackboard(), this->bb_manager);
286template <
class... IfaceManagerTs>
290 boost::fusion::for_each(bb_sending_interfaces_,
291 [
this](
auto &iface_mgr) { iface_mgr.finalize(); });
294template <
class IfaceT,
class MessageT>
299 manager->handle_message_type<MessageT>(pair.interface());
302template <
class IfaceT,
class MessageT1,
class... MessageTs>
307 BlackboardManager::on_interface<IfaceT>{iface_mgr.interface(), manager}
308 .template handle_msg_types<MessageTs...>();
310 manager->handle_message_type<MessageT1>(iface_mgr.interface());
313template <
class MessageT,
class InterfaceT>
315BlackboardManager::handle_message_type(InterfaceT *iface)
317 if (!iface->msgq_empty()) {
318 while (MessageT *msg = iface->msgq_first_safe(msg)) {
320 handle_message(iface, msg);
322 }
catch (std::exception &e) {
324 name(),
"Exception handling %s on %s: %s", msg->type(), iface->uid(), e.what());
Thread aspect to access to BlackBoard.
Wake threads on receiving a blackboard message.
The BlackBoard abstract class.
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.
Thread aspect that allows to obtain the current time from the clock.
Thread aspect to access configuration data.
Thread aspect to log output.
virtual void log_error(const char *component, const char *format,...)
Log error message.
ProtobufPeerInterface Fawkes BlackBoard Interface.
Thread class encapsulation of pthreads.
Abstract superclass for sending out ProtoBuf messages.
virtual void process_sending_interfaces()=0
Go through all interface managers, empty all blackboard message queues and send out ProtoBuf messages...
virtual void init()=0
Deferred initialization, coincides with the main thread.
BlackboardManager * bb_manager
Pointer to the main thread that uses this.
AbstractProtobufSender(BlackboardManager *bb_mgr)
Constructor.
virtual void finalize()=0
Deferred cleanup, concides with the main thread.
virtual ~AbstractProtobufSender()
Destructor.
The main thread that is woken each time a message arrives on any of the interfaces watched by a bb_if...
virtual void finalize() override
Finalize the thread.
void set_protobuf_sender(AbstractProtobufSender *sender)
The ProtoBuf sender must be initialized after construction to beak a dependency loop.
fawkes::BlackBoard * get_blackboard()
Helper for other classes to get access to the blackboard.
virtual void init() override
Initialize the thread.
virtual void loop() override
Code to execute in the thread.
void handle_message(InterfaceT *iface, MessageT *msg)
Act on a given message on a given blackboard interface.
BlackboardManager(ProtobufThead *msg_handler)
Main thread constructor.
Sends out ProtoBuf messages for all given interface managers.
virtual void process_sending_interfaces() override
Go through all interface managers, empty all blackboard message queues and send out ProtoBuf messages...
virtual void finalize() override
Deferred cleanup, concides with the main thread.
virtual void init() override
Deferred initialization, coincides with the main thread.
ProtobufSender(BlackboardManager *bb_mgr)
Constructor.
Receive incoming ProtoBuf messages and pass them on to the BlackboardManager for publication to the a...
Container for an opened interface of type.
IfaceT * interface() const
bb_iface_manager()
Constructor. Not responsible for actual initialization.
void init(fawkes::BlackBoard *blackboard, fawkes::Thread *thread)
Open an interface of the given type with the ID supplied by iface_id_for_type and register to wake th...
Functor that iterates over all message types that should be handled on a given interface type and cal...
BlackboardManager * manager
Pointer to the main thread.
void operator()(const bb_iface_manager< IfaceT, type_list< MessageT > > &iface_mgr) const
Handle a specific blackboard message type on a given interface manager.
Helper structure to wrap a list of types into a single type.