TinyRobotics
Loading...
Searching...
No Matches
MessageSource.h
1#pragma once
2#include <vector>
3
4#include "Message.h"
6#include "TinyRobotics/control/MotionState3D.h"
7#include "TinyRobotics/coordinates/Coordinates.h"
8#include "TinyRobotics/coordinates/GPSCoordinate.h"
9
10namespace tinyrobotics {
11
12/**
13 * @class MessageSource
14 * @ingroup communication
15 * @brief Base class for message sources in the TinyRobotics communication
16 * framework.
17 *
18 * MessageSource manages a list of MessageHandler objects and provides methods
19 * to add, clear, and forward messages to all registered handlers. This enables
20 * a flexible publish/subscribe or observer pattern for distributing messages
21 * (such as sensor data, commands, or events) to multiple consumers in a
22 * robotics system.
23 *
24 * Typical usage:
25 * @code
26 * MessageSource source;
27 * source.subscribe(handler1);
28 * source.subscribe(handler2);
29 * source.sendMessage(msg); // Forwards to all handlers
30 * @endcode
31 *
32 * Extend this class to implement custom message-producing components (e.g.,
33 * sensors, controllers) that need to broadcast messages to other system parts.
34 */
35class MessageSource {
36 public:
37 /**
38 * @brief Subscribe a message handler to this source, with optional filtering.
39 *
40 * Registers a MessageHandler to receive messages published by this source.
41 * Optionally, you can specify a filter for message origin and content. Only
42 * messages matching the filter (or with filter set to Undefined) will be
43 * delivered to the handler.
44 *
45 * @param handler Reference to a MessageHandler to add.
46 * @param origin (Optional) Only deliver messages with this origin. Use
47 * MessageOrigin::Undefined to accept all origins.
48 * @param content (Optional) Only deliver messages with this content type. Use
49 * MessageContent::Undefined to accept all content types.
50 *
51 * Example:
52 * @code
53 * source.subscribe(handler); // Receives all messages
54 * source.subscribe(handler, MessageOrigin::RemoteControl); // Only messages
55 * from remote control source.subscribe(handler, MessageOrigin::Undefined,
56 * MessageContent::Throttle); // Only throttle messages
57 * @endcode
58 */
59 void subscribe(MessageHandler& handler,
60 MessageOrigin origin = MessageOrigin::Undefined,
61 MessageContent content = MessageContent::Undefined) {
62 MessageHandlerEntry entry{handler, origin, content};
63 messageHandlers_.push_back(entry);
64 }
65
66 /**
67 * @brief Remove all registered message handlers.
68 */
69 void unsubscribeAll() { messageHandlers_.clear(); }
70
71 /**
72 * @brief Publish a message to all registered handlers.
73 *
74 * Forwards the given message to each handler in the messageHandlers_ list.
75 * @param msg The message to publish.
76 */
77 void sendMessage(Message<float>& msg) {
78 for (auto& entry : messageHandlers_) {
79 if (!entry.handler) continue;
80 if ((entry.origin == MessageOrigin::Undefined ||
81 entry.origin == msg.origin) &&
82 (entry.content == MessageContent::Undefined ||
83 entry.content == msg.content)) {
84 entry.handler->onMessage(msg);
85 }
86 }
87 }
88
89 /**
90 * @brief Publish a message to all registered handlers.
91 *
92 * Forwards the given message to each handler in the messageHandlers_ list.
93 * @param msg The message to publish.
94 */
95 void sendMessage(const Message<Coordinate<float>>& msg) {
96 for (auto& entry : messageHandlers_) {
97 if (!entry.handler) continue;
98 if ((entry.origin == MessageOrigin::Undefined ||
99 entry.origin == msg.origin) &&
100 (entry.content == MessageContent::Undefined ||
101 entry.content == msg.content)) {
102 entry.handler->onMessage(msg);
103 }
104 }
105 }
106
107 /**
108 * @brief Publish a message to all registered handlers.
109 *
110 * Forwards the given message to each handler in the messageHandlers_ list.
111 * @param msg The message to publish.
112 */
113 void sendMessage(const Message<GPSCoordinate>& msg) {
114 for (auto& entry : messageHandlers_) {
115 if (!entry.handler) continue;
116 if ((entry.origin == MessageOrigin::Undefined ||
117 entry.origin == msg.origin) &&
118 (entry.content == MessageContent::Undefined ||
119 entry.content == msg.content)) {
120 entry.handler->onMessage(msg);
121 }
122 }
123 }
124
125 /// Overload for MotionState3D messages
126 void sendMessage(const Message<MotionState3D>& msg) {
127 for (auto& entry : messageHandlers_) {
128 if (!entry.handler) continue;
129 if ((entry.origin == MessageOrigin::Undefined ||
130 entry.origin == msg.origin) &&
131 (entry.content == MessageContent::Undefined ||
132 entry.content == msg.content)) {
133 entry.handler->onMessage(msg);
134 }
135 }
136 }
137
138 protected:
139 struct MessageHandlerEntry {
140 MessageHandler* handler = nullptr;
141 MessageOrigin origin = MessageOrigin::Undefined; // origin filter
142 MessageContent content = MessageContent::Undefined; // content filter
143
144 MessageHandlerEntry() = default;
145 MessageHandlerEntry(MessageHandler& h,
146 MessageOrigin o = MessageOrigin::Undefined,
147 MessageContent c = MessageContent::Undefined)
148 : handler(&h), origin(o), content(c) {}
149
150 bool operator==(const MessageHandlerEntry& other) const {
151 return handler == other.handler && origin == other.origin &&
152 content == other.content;
153 }
154 };
155 std::vector<MessageHandlerEntry> messageHandlers_;
156};
157
158} // namespace tinyrobotics
A generic 3D coordinate class for robotics, navigation, and spatial calculations.
Definition: Coordinate.h:57
Represents a geodetic GPS coordinate with latitude, longitude, and optional altitude.
Definition: GPSCoordinate.h:52
Interface for handling messages in the TinyRobotics framework.
Definition: MessageHandler.h:18
Base class for message sources in the TinyRobotics communication framework.
Definition: MessageSource.h:35
void sendMessage(const Message< MotionState3D > &msg)
Overload for MotionState3D messages.
Definition: MessageSource.h:126
void unsubscribeAll()
Remove all registered message handlers.
Definition: MessageSource.h:69
void sendMessage(const Message< GPSCoordinate > &msg)
Publish a message to all registered handlers.
Definition: MessageSource.h:113
void sendMessage(Message< float > &msg)
Publish a message to all registered handlers.
Definition: MessageSource.h:77
void subscribe(MessageHandler &handler, MessageOrigin origin=MessageOrigin::Undefined, MessageContent content=MessageContent::Undefined)
Subscribe a message handler to this source, with optional filtering.
Definition: MessageSource.h:59
void sendMessage(const Message< Coordinate< float > > &msg)
Publish a message to all registered handlers.
Definition: MessageSource.h:95
Represents the full 3D motion state of a robot or vehicle.
Definition: MotionState3D.h:53
Generic message structure for communication, parameterized by value type.
Definition: Message.h:72