event.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /////////////////////////////////////////////////////////////////////////////
  2. /// @file event.h
  3. /// Declaration of MQTT event-related classes
  4. /// @date July 6, 2024
  5. /// @author Frank Pagliughi
  6. /////////////////////////////////////////////////////////////////////////////
  7. /*******************************************************************************
  8. * Copyright (c) 2024 Frank Pagliughi <fpagliughi@mindspring.com>
  9. *
  10. * All rights reserved. This program and the accompanying materials
  11. * are made available under the terms of the Eclipse Public License v2.0
  12. * and Eclipse Distribution License v1.0 which accompany this distribution.
  13. *
  14. * The Eclipse Public License is available at
  15. * http://www.eclipse.org/legal/epl-v20.html
  16. * and the Eclipse Distribution License is available at
  17. * http://www.eclipse.org/org/documents/edl-v10.php.
  18. *
  19. * Contributors:
  20. * Frank Pagliughi - initial implementation and documentation
  21. *******************************************************************************/
  22. #ifndef __mqtt_event_h
  23. #define __mqtt_event_h
  24. #include <variant>
  25. #include "mqtt/message.h"
  26. #include "mqtt/properties.h"
  27. #include "mqtt/reason_code.h"
  28. #include "mqtt/types.h"
  29. namespace mqtt {
  30. /////////////////////////////////////////////////////////////////////////////
  31. /** Event for when the client is connected/reconnected */
  32. struct connected_event
  33. {
  34. string cause;
  35. };
  36. /** Event for when the connection is lost */
  37. struct connection_lost_event
  38. {
  39. string cause;
  40. };
  41. /** Event for when we receive a DISCONNECT packet from the server */
  42. struct disconnected_event
  43. {
  44. properties props;
  45. ReasonCode reasonCode;
  46. };
  47. /** Event for when the consumer queue is shutdown from another thread */
  48. struct shutdown_event
  49. {
  50. };
  51. /* Event for when a message arrives is just a message pointer */
  52. /////////////////////////////////////////////////////////////////////////////
  53. /**
  54. * An MQTT event.
  55. *
  56. * This is used by the client consumer to pass events and state changes from
  57. * the client to the application without the need for any additional
  58. * callbacks or client queries.
  59. *
  60. * Each instance carries the relevant data for specific event that caused
  61. * it. For example an incoming message event contains a shared pointer to
  62. * the message that arrived.
  63. *
  64. * The supported event types are:
  65. * @li **message** A message arrived from the server.
  66. * @li **connected** The client connected. If the client was configured for
  67. * automatic reconnects, this can be from a reconnection. (No data)
  68. * @li **connection lost** The client lost the connection. (No data)
  69. * @li **disconnected** (v5) The client received a DISCONNECT packet from
  70. * the server. This includes the reason code and properties for the
  71. * disconnect.
  72. */
  73. class event
  74. {
  75. public:
  76. /** The variant type for any possible event. */
  77. using event_type = std::variant<
  78. const_message_ptr, connected_event, connection_lost_event, disconnected_event,
  79. shutdown_event>;
  80. private:
  81. event_type evt_{};
  82. public:
  83. /**
  84. * Constructs an empty event.
  85. * This shows as a message, but the message pointer is null.
  86. */
  87. event() {}
  88. /**
  89. * Constructs an event from an event type variant.
  90. * @param evt The event type variant.
  91. */
  92. event(event_type evt) : evt_{std::move(evt)} {}
  93. /**
  94. * Constructs a message event.
  95. * @param msg A shared message pointer.
  96. */
  97. event(message_ptr msg) : evt_{std::move(msg)} {}
  98. /**
  99. * Constructs a message event.
  100. * @param msg A shared const message pointer.
  101. */
  102. event(const_message_ptr msg) : evt_{std::move(msg)} {}
  103. /**
  104. * Constructs a 'connected' event.
  105. * @param evt A connected event.
  106. */
  107. event(connected_event evt) : evt_{std::move(evt)} {}
  108. /**
  109. * Constructs a 'connection lost' event.
  110. * @param evt A connection lost event.
  111. */
  112. event(connection_lost_event evt) : evt_{std::move(evt)} {}
  113. /**
  114. * Constructs a 'disconnected' event.
  115. * @param evt A disconnected event.
  116. */
  117. event(disconnected_event evt) : evt_{std::move(evt)} {}
  118. /**
  119. * Constructs a 'shutdown' event.
  120. * @param evt A shutdown event.
  121. */
  122. event(shutdown_event evt) : evt_{std::move(evt)} {}
  123. /**
  124. * Copy constructor.
  125. * @param evt The event to copy.
  126. */
  127. event(const event& evt) : evt_{evt.evt_} {}
  128. /**
  129. * Move constructor.
  130. * @param evt The event to move.
  131. */
  132. event(event&& evt) : evt_{std::move(evt.evt_)} {}
  133. /**
  134. * Assignment from an event type variant.
  135. * @param evt The event type variant.
  136. * @return A reference to this object.
  137. */
  138. event& operator=(event_type evt) {
  139. evt_ = std::move(evt);
  140. return *this;
  141. }
  142. /**
  143. * Copy assignment.
  144. * @param rhs The event to copy.
  145. * @return A reference to this object.
  146. */
  147. event& operator=(const event& rhs) {
  148. if (&rhs != this)
  149. evt_ = rhs.evt_;
  150. return *this;
  151. }
  152. /**
  153. * Move assignment.
  154. * @param rhs The event to move.
  155. * @return A reference to this object.
  156. */
  157. event& operator=(event&& rhs) {
  158. if (&rhs != this)
  159. evt_ = std::move(rhs.evt_);
  160. return *this;
  161. }
  162. /**
  163. * Determines if this event is an incoming message.
  164. * @return @em true if this event is an incoming message, @em false
  165. * otherwise.
  166. */
  167. bool is_message() const { return std::holds_alternative<const_message_ptr>(evt_); }
  168. /**
  169. * Determines if this event is a client (re)connection.
  170. * @return @em true if this event is a client connection, @em false
  171. * otherwise.
  172. */
  173. bool is_connected() const { return std::holds_alternative<connected_event>(evt_); }
  174. /**
  175. * Determines if this event is a client connection lost.
  176. * @return @em true if this event is a client connection lost, @em false
  177. * otherwise.
  178. */
  179. bool is_connection_lost() const {
  180. return std::holds_alternative<connection_lost_event>(evt_);
  181. }
  182. /**
  183. * Determines if this event is a client disconnected.
  184. * @return @em true if this event is a client disconnected, @em false
  185. * otherwise.
  186. */
  187. bool is_disconnected() const { return std::holds_alternative<disconnected_event>(evt_); }
  188. /**
  189. * Determines if this event is an internal shutdown request.
  190. * @return @em true if this event is a shutdown request, @em false
  191. * otherwise.
  192. */
  193. bool is_shutdown() const { return std::holds_alternative<disconnected_event>(evt_); }
  194. /**
  195. * Determines if this is any type of client disconnect or shutdown.
  196. * @return @em true if this event is any type of client disconnect such
  197. * as a 'connection lost', 'disconnected', or shutdown event.
  198. */
  199. bool is_any_disconnect() const {
  200. return std::holds_alternative<connection_lost_event>(evt_) ||
  201. std::holds_alternative<disconnected_event>(evt_) ||
  202. std::holds_alternative<shutdown_event>(evt_);
  203. }
  204. /**
  205. * Gets the message from the event, iff this is a message event.
  206. * @return A message pointer, if this is a message event.
  207. * @throw std::bad_variant_access if this is not a 'message' event.
  208. */
  209. const_message_ptr get_message() { return std::get<const_message_ptr>(evt_); }
  210. /**
  211. * Gets the underlying information for a disconnected event iff this is
  212. * a 'disconnected' event.
  213. * This contains the reason code and properties that the server sent in
  214. * the DISCONNECT packet.
  215. * @return The disconnected event object containing information about
  216. * why the server disconnected.
  217. * @throw std::bad_variant_access if this is not a 'disconnected' event.
  218. */
  219. disconnected_event get_disconnected() { return std::get<disconnected_event>(evt_); }
  220. /**
  221. * Gets a pointer to the message in the event, iff this is a message
  222. * event.
  223. * @return A pointer to a message pointer, if this is a message event.
  224. * Returns nulltr if this is not a message event.
  225. */
  226. constexpr std::add_pointer_t<const_message_ptr> get_message_if() noexcept {
  227. return std::get_if<const_message_ptr>(&evt_);
  228. }
  229. /**
  230. * Gets a pointer the underlying information for a disconnected event,
  231. * iff this is a 'disconnected' event.
  232. * This contains the reason code and properties that the server sent in
  233. * the DISCONNECT packet.
  234. * @return The disconnected event object containing information about
  235. * why the server disconnected.
  236. * @throw std::bad_variant_access if this is not a 'disconnected' event.
  237. */
  238. constexpr std::add_pointer_t<disconnected_event> get_disconnected_if() noexcept {
  239. return std::get_if<disconnected_event>(&evt_);
  240. }
  241. };
  242. /////////////////////////////////////////////////////////////////////////////
  243. } // namespace mqtt
  244. #endif // __mqtt_event_h