#pragma once #include "defs.h" #include namespace dBus { //-------------------------------------------------------------- class Message : public std::enable_shared_from_this { friend class Bus; public: Message() = default; // Default constructor virtual ~Message(); // Default destructor Message(const Message &obj) = delete; // Copy constructor Message(Message &&obj) noexcept = delete; // Move constructor Message &operator=(const Message &obj) = delete; // Copy assignment operator Message &operator=(Message &&obj) noexcept = delete; // Move assignment operator explicit Message(const HashID &messageTypeID, // Constructor const MessageCategory &category); // Message management TimePoint getPostedAt() const; // Get the timestamp of when the message was posted [[nodiscard]] std::chrono::microseconds getAge() const; // Get the age of the message in microseconds [[nodiscard]] bool isType(const HashID &eventType) const; // Check if the message is of a specific type // Trace information [[nodiscard]] HashID getMessageTypeID() const; // Get the unique identifier for the message type [[nodiscard]] MessageCategory getCategory() const; // Get the log category of the message [[nodiscard]] virtual std::string serializeData() const; // Serialize the message data to a string [[nodiscard]] virtual std::string toString() const; // Get a string representation of the message for logging purposes [[nodiscard]] virtual std::string toLogLine() const; // Get a formatted log line representation of the message for logging purposes template [[nodiscard]] std::shared_ptr as(); // Template method to cast the message to a specific derived type template [[nodiscard]] std::shared_ptr as() const; // Template method to cast the message to a specific derived type protected: HashID m_messageTypeID = 0; // Unique identifier for the message type MessageCategory m_category = MessageCategory::None; // Log category of the message Bus *m_bus = nullptr; // Pointer to the bus this message is posted to (to be set by the bus when the message is posted) TimePoint m_postedAt; // Timestamp of when the message was posted private: void linkToBus(Bus *bus); // Set the message parameters when the message is posted to the bus }; //-------------------------------------------------------------- /* Template method to cast the message to a specific derived type */ template std::shared_ptr Message::as() { return std::dynamic_pointer_cast(shared_from_this()); } //-------------------------------------------------------------- /* Template method to cast the message to a specific derived type */ template std::shared_ptr Message::as() const { return std::dynamic_pointer_cast(shared_from_this()); } //-------------------------------------------------------------- /* --- */ //-------------------------------------------------------------- template class EventMessage : public Message { public: T value; // Value associated with the event message EventMessage() = delete; // Default constructor virtual ~EventMessage() = default; // Default destructor EventMessage(const EventMessage &obj) = delete; // Copy constructor EventMessage(EventMessage &&obj) noexcept = delete; // Move constructor EventMessage &operator=(const EventMessage &obj) = delete; // Copy assignment operator EventMessage &operator=(EventMessage &&obj) noexcept = delete; // Move assignment operator explicit EventMessage(const HashID &messageTypeID, // Constructor const MessageCategory &category, T v); [[nodiscard]] std::string serializeData() const override; // Serialize the message data to a string }; //-------------------------------------------------------------- /* Constructor */ template EventMessage::EventMessage(const HashID &messageTypeID, const MessageCategory &category, T v) : Message(messageTypeID, category) , value(std::move(v)) { } //-------------------------------------------------------------- /* Serialize the message data to a string */ template std::string EventMessage::serializeData() const { if constexpr (std::is_arithmetic_v) return std::to_string(value); return ""; } //-------------------------------------------------------------- /* --- */ //-------------------------------------------------------------- template class RequestMessage : public Message { public: T value; // Value associated with the event message std::promise responsePromise; // Promise to be fulfilled with the response data once the request is processed RequestMessage() = delete; // Default constructor virtual ~RequestMessage() = default; // Default destructor RequestMessage(const RequestMessage &obj) = delete; // Copy constructor RequestMessage(RequestMessage &&obj) noexcept = delete; // Move constructor RequestMessage &operator=(const RequestMessage &obj) = delete; // Copy assignment operator RequestMessage &operator=(RequestMessage &&obj) noexcept = delete; // Move assignment operator explicit RequestMessage(const HashID &messageTypeID, // Constructor const MessageCategory &category, T v, std::shared_ptr p); std::future getFuture(); // Get the future associated with the response promise }; //-------------------------------------------------------------- /* Constructor */ template RequestMessage::RequestMessage(const HashID &messageTypeID, const MessageCategory &category, T v, std::shared_ptr p) : Message(messageTypeID, category) , value(std::move(v)) , responsePromise(std::promise{}) { } //-------------------------------------------------------------- /* Get the future associated with the response promise */ template std::future RequestMessage::getFuture() { return std::move(responsePromise.get_future()); } //-------------------------------------------------------------- } // namespace dBus