Files
kwa.fr/src/dBus/message.h
2026-03-12 16:32:03 +01:00

153 lines
6.8 KiB
C++

#pragma once
#include "defs.h"
#include <future>
namespace dBus
{
//--------------------------------------------------------------
class Message : public std::enable_shared_from_this<Message>
{
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<class Derived>
[[nodiscard]] std::shared_ptr<Derived> as(); // Template method to cast the message to a specific derived type
template<class Derived>
[[nodiscard]] std::shared_ptr<const Derived> 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<class Derived>
std::shared_ptr<Derived> Message::as()
{
return std::dynamic_pointer_cast<Derived>(shared_from_this());
}
//--------------------------------------------------------------
/* Template method to cast the message to a specific derived type */
template<class Derived>
std::shared_ptr<const Derived> Message::as() const
{
return std::dynamic_pointer_cast<const Derived>(shared_from_this());
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
template<class T>
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<class T>
EventMessage<T>::EventMessage(const HashID &messageTypeID, const MessageCategory &category, T v)
: Message(messageTypeID, category)
, value(std::move(v))
{
}
//--------------------------------------------------------------
/* Serialize the message data to a string */
template<class T>
std::string EventMessage<T>::serializeData() const
{
if constexpr (std::is_arithmetic_v<T>)
return std::to_string(value);
return "";
}
//--------------------------------------------------------------
/* --- */
//--------------------------------------------------------------
template<class T, class U>
class RequestMessage : public Message
{
public:
T value; // Value associated with the event message
std::promise<U> 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<U> p);
std::future<U> getFuture(); // Get the future associated with the response promise
};
//--------------------------------------------------------------
/* Constructor */
template<class T, class U>
RequestMessage<T, U>::RequestMessage(const HashID &messageTypeID, const MessageCategory &category, T v, std::shared_ptr<U> p)
: Message(messageTypeID, category)
, value(std::move(v))
, responsePromise(std::promise<U>{})
{
}
//--------------------------------------------------------------
/* Get the future associated with the response promise */
template<class T, class U>
std::future<U> RequestMessage<T, U>::getFuture()
{
return std::move(responsePromise.get_future());
}
//--------------------------------------------------------------
} // namespace dBus