mal-packet-weaver
C++20 packet serialization/deserialization library.
Loading...
Searching...
No Matches
packet.hpp
Go to the documentation of this file.
1#pragma once
2#include "../common.hpp"
3#include <cereal/archives/portable_binary.hpp>
4#include <cereal/types/map.hpp>
5#include <cereal/types/vector.hpp>
6#include <cereal/types/string.hpp>
7namespace mal_packet_weaver
8{
10 class Packet;
11
12 using PacketSubsystemID = uint16_t;
13 using PacketID = uint16_t;
14
16 using UniquePacketID = uint32_t;
17
19 using PacketDeserializeFunc = std::function<std::unique_ptr<Packet>(const ByteView)>;
20
22 constexpr uint32_t PacketSubsystemIDToUint32(PacketSubsystemID subsystem_type) noexcept
23 {
24 return static_cast<uint32_t>(subsystem_type) << 16;
25 }
26
29 {
30 return static_cast<PacketSubsystemID>((subsystem_type & 0xFFFF0000) >> 16);
31 }
32
34 constexpr PacketID UniquePacketIDToPacketID(UniquePacketID subsystem_type) noexcept
35 {
36 return static_cast<PacketID>(subsystem_type & 0xFFFF);
37 }
38
40 constexpr UniquePacketID CreatePacketID(PacketSubsystemID subsystem_id, PacketID packet_id) noexcept
41 {
42 return (static_cast<UniquePacketID>(subsystem_id) << 16) | packet_id;
43 }
44
46 class Packet : public non_copyable
47 {
48 private:
50 public:
52 explicit Packet(const UniquePacketID type, const float time_to_live)
54 {
55 }
56
57 Packet(Packet &&) = default;
58 Packet &operator=(Packet &&) = default;
59
61
63 virtual ~Packet() = default;
64
65 virtual const char* packet_name() const = 0;
66
68 virtual void serialize_to_bytearray(ByteArray &buffer) const = 0;
69
71 [[nodiscard]] float timestamp() const noexcept { return timestamp_; }
72
74 [[nodiscard]] float get_packet_time_alive() const noexcept { return measurer.elapsed() - timestamp_; }
75
77 [[nodiscard]] bool expired() const noexcept { return get_packet_time_alive() > time_to_live; }
78
80 const float time_to_live;
81 const float timestamp_;
82
83 private:
84 friend class cereal::access;
85 // Base serialize method for classes.
86 // This may be used for empty packets, so there's minimum boilerplate in packets.
87 // This will just return an empty payload.
88 template <class Archive>
89 void serialize(Archive &, const unsigned int)
90 {
91 }
92 };
93
112 template <typename PacketType>
113 class DerivedPacket : public Packet
114 {
115 public:
121 DerivedPacket() : Packet(PacketType::static_unique_id, PacketType::time_to_live) {}
122
126 virtual ~DerivedPacket() = default;
127
136 void serialize_to_bytearray(ByteArray &buffer) const override
137 {
139 std::ostringstream oss(std::ios::out | std::ios::binary);
140 cereal::PortableBinaryOutputArchive oa(oss);
141 oa << static_cast<const PacketType &>(*this);
142 std::string const &s = oss.str();
143 buffer.append(s);
144 }
145
155 [[nodiscard]] static std::unique_ptr<Packet> deserialize(const ByteView buffer)
156 {
158 const auto char_view = buffer.as<char>();
159 const std::string s(char_view, buffer.size());
160 std::istringstream iss(s, std::ios::in | std::ios::binary);
161 cereal::PortableBinaryInputArchive ia(iss);
162 std::unique_ptr<PacketType> derived_packet = std::make_unique<PacketType>();
163 ia >> *derived_packet;
164 return derived_packet;
165 }
166 };
167
169 template <typename T>
170 concept IsPacket = requires(T packet)
171 {
172 std::is_final_v<T>;
173 std::is_base_of_v<DerivedPacket<T>, T>;
174 std::same_as<std::decay_t<decltype(T::static_unique_id)>, UniquePacketID>;
175 std::same_as<std::decay_t<decltype(T::time_to_live)>, float>;
176 };
177} // namespace mal_packet_weaver
A templated class representing a derived packet from the base Packet class.
Definition packet.hpp:114
static std::unique_ptr< Packet > deserialize(const ByteView buffer)
Deserialize a byte view into a unique pointer of the specified packet type.
Definition packet.hpp:155
void serialize_to_bytearray(ByteArray &buffer) const override
Serialize the derived packet data into a ByteArray.
Definition packet.hpp:136
DerivedPacket()
Constructor for the DerivedPacket class.
Definition packet.hpp:121
virtual ~DerivedPacket()=default
Virtual destructor for the DerivedPacket class.
Base class for all packets.
Definition packet.hpp:47
static Measurer< std::chrono::steady_clock > measurer
Measurer for packet timestamps.
Definition packet.hpp:49
float timestamp() const noexcept
Get the timestamp when the packet was received.
Definition packet.hpp:71
bool expired() const noexcept
Check if the packet has expired based on its time-to-live.
Definition packet.hpp:77
Packet(Packet &&)=default
void serialize(Archive &, const unsigned int)
Definition packet.hpp:89
Packet(const UniquePacketID type, const float time_to_live)
Constructor for Packet class.
Definition packet.hpp:52
const UniquePacketID type
Unique packet ID.
Definition packet.hpp:79
virtual const char * packet_name() const =0
virtual ~Packet()=default
Virtual destructor for Packet class.
Packet & operator=(Packet &&)=default
virtual void serialize_to_bytearray(ByteArray &buffer) const =0
Serialize the packet into a ByteArray.
friend class cereal::access
Definition packet.hpp:84
const float timestamp_
Timestamp when the packet was received.
Definition packet.hpp:81
const float time_to_live
Time-to-live for the packet.
Definition packet.hpp:80
float get_packet_time_alive() const noexcept
Get the time elapsed since the packet was received.
Definition packet.hpp:74
A class that can't be copied.
Concept to check if a given type satisfies the requirements of being a packet.
Definition packet.hpp:170
This is the main namespace for the Mal Packet Weaver library.
Definition common.hpp:42
constexpr PacketSubsystemID UniquePacketIDToPacketSubsystemID(UniquePacketID subsystem_type) noexcept
Extract PacketSubsystemID from a UniquePacketID.
Definition packet.hpp:28
constexpr uint32_t PacketSubsystemIDToUint32(PacketSubsystemID subsystem_type) noexcept
Convert a PacketSubsystemID to a uint32_t value.
Definition packet.hpp:22
uint16_t PacketSubsystemID
Type alias for packet subsystem IDs.
Definition packet.hpp:12
constexpr UniquePacketID CreatePacketID(PacketSubsystemID subsystem_id, PacketID packet_id) noexcept
Create a UniquePacketID from subsystem and packet IDs.
Definition packet.hpp:40
std::function< std::unique_ptr< Packet >(const ByteView)> PacketDeserializeFunc
Type alias for packet deserialization function.
Definition packet.hpp:19
constexpr PacketID UniquePacketIDToPacketID(UniquePacketID subsystem_type) noexcept
Extract PacketID from a UniquePacketID.
Definition packet.hpp:34
uint32_t UniquePacketID
Unique identifier for a packet, combining subsystem and packet IDs.
Definition packet.hpp:16
uint16_t PacketID
Type alias for packet IDs.
Definition packet.hpp:13
A dynamically resizable array of bytes.
void append(First &&first, Second &&second, Args &&...args)
Append multiple data sources to the byte array.
A lightweight view over a sequence of bytes.
const T * as() const
Convert the ByteView to a typed view.
A class for measuring and logging the execution time of functions.
Definition measurer.hpp:17
float elapsed()
Get the total elapsed time since the start of the measurement.
Definition measurer.hpp:184