mal-packet-weaver
C++20 packet serialization/deserialization library.
Loading...
Searching...
No Matches
packet-factory.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "packet.hpp"
4
5namespace mal_packet_weaver
6{
7 template <typename T>
13 {
14 public:
24 template <IsPacket PacketType>
25 static inline void RegisterDeserializer()
26 {
27 if (auto it = instance().packet_deserializers_.find(PacketType::static_unique_id);
28 it != instance().packet_deserializers_.end())
29 {
30 std::unique_ptr<Packet> (*const *ptr)(const ByteView) =
31 it->second.target<std::unique_ptr<Packet> (*)(const ByteView)>();
32 if (ptr && ptr == &(&PacketType::deserialize)) // Same target
33 {
34 return;
35 }
36 std::string exception_msg =
37 "An error occured while trying to register packet deserializer: it is already initialized for this unique packet id with different function!";
38#if _DEBUG
39 auto t = instance().type_names.at(PacketType::static_unique_id);
40 auto hex = [](int value) -> std::string
41 {
42 std::stringstream stream;
43 stream << std::hex << value;
44 return stream.str();
45 };
46
47 exception_msg += "\n It is already initialized for type with name: " + std::string(t) +
48 " with an ID of 0x" + hex(PacketType::static_unique_id);
49 exception_msg += ".\n You are passing " + std::string(typeid(PacketType).name()) +
50 " with an ID of 0x" + hex(PacketType::static_unique_id);
51 exception_msg += ".\n Please check static unique IDs for these packets.";
52#endif
53 spdlog::critical(exception_msg);
54 throw std::invalid_argument(exception_msg.c_str());
55 }
56 instance().packet_deserializers_[PacketType::static_unique_id] = PacketType::deserialize;
57
58 const char *type_name = typeid(PacketType).name();
59
60 spdlog::info("Registered deserializer for {} with id {}", type_name, PacketType::static_unique_id);
61#if _DEBUG
62 instance().type_names[PacketType::static_unique_id] = type_name;
63#endif
64 }
65
76 {
77 if (auto it = instance().packet_deserializers_.find(packet_id);
78 it != instance().packet_deserializers_.end())
79 {
80 std::unique_ptr<Packet> (*const *ptr)(const ByteView) =
81 factory.target<std::unique_ptr<Packet> (*)(const ByteView)>();
82 if (!ptr || ptr == it->second.target<std::unique_ptr<Packet> (*)(const ByteView)>())
83 {
84 throw std::invalid_argument("Packet deserializer already initialized with different function!");
85 }
86 return;
87 }
88 instance().packet_deserializers_[packet_id] = factory;
89 }
90
101 [[nodiscard]] static inline std::unique_ptr<Packet> Deserialize(const ByteView &bytearray,
102 UniquePacketID packet_type)
103 {
104 auto it = instance().packet_deserializers_.find(packet_type);
105 if (it != instance().packet_deserializers_.end())
106 {
107 return it->second(bytearray);
108 }
109 // TODO: MAL_PACKET_WEAVER_VERBOSE_LEVEL, output to spdlog if there's no deserializer.
110 return nullptr;
111 }
116 {
117 if (instance_ == nullptr)
118 {
119 instance_ = std::unique_ptr<PacketFactory>(new PacketFactory);
120 }
121 return *instance_;
122 }
123
124 private:
125 PacketFactory() = default;
126 static std::unique_ptr<PacketFactory> instance_;
130 std::unordered_map<UniquePacketID, PacketDeserializeFunc> packet_deserializers_;
131#if _DEBUG
132 std::unordered_map<UniquePacketID, const char *> type_names;
133#endif
134 };
135
145 template <typename T>
153
154} // namespace mal_packet_weaver
A class responsible for registering and creating packet deserializers.
static void RegisterDeserializer(UniquePacketID packet_id, PacketDeserializeFunc factory)
Register a packet deserializer function for a specific packet ID.
static void RegisterDeserializer()
Register a packet deserializer function for a specific PacketType.
std::unordered_map< UniquePacketID, PacketDeserializeFunc > packet_deserializers_
Map storing registered packet deserializer functions.
static PacketFactory & instance()
Instance of the Packet Factory.
static std::unique_ptr< PacketFactory > instance_
static std::unique_ptr< Packet > Deserialize(const ByteView &bytearray, UniquePacketID packet_type)
Deserialize a byte view into a unique pointer of the specified packet type.
This is the main namespace for the Mal Packet Weaver library.
Definition common.hpp:42
std::function< std::unique_ptr< Packet >(const ByteView)> PacketDeserializeFunc
Type alias for packet deserialization function.
Definition packet.hpp:19
uint32_t UniquePacketID
Unique identifier for a packet, combining subsystem and packet IDs.
Definition packet.hpp:16
Helper class for registering a packet type with the PacketFactory.
PacketTypeRegistrationHelper()
Constructor. Registers the packet type with the PacketFactory.
A lightweight view over a sequence of bytes.