add basic serialization functionallity

This commit is contained in:
2022-04-26 18:54:52 +02:00
parent 2bebce2ba4
commit 7c76691df7
3 changed files with 89 additions and 170 deletions

View File

@@ -1,111 +1,94 @@
#pragma once #pragma once
#include <algorithm>
#include <boost/asio.hpp>
#include <cstddef> #include <cstddef>
#include <cstring>
#include <glm/vec2.hpp> #include <glm/vec2.hpp>
#include <glm/vec3.hpp> #include <glm/vec3.hpp>
#include <map> #include <map>
#include <memory>
namespace commons::protocol #include "spdlog/spdlog.h"
{
enum class Type namespace commons::protocol {
{
enum class Type {
DRAW_RECTANGLE = 0, DRAW_RECTANGLE = 0,
DRAW_PIXEL, DRAW_PIXEL,
COMPOSED_MESSAGE,
}; };
class generic_message_base
: std::enable_shared_from_this<generic_message_base> {
public:
virtual ~generic_message_base() { spdlog::debug("base dtor"); }
virtual constexpr Type get_type() const = 0;
virtual uint32_t get_size() const = 0;
struct header auto get_shared_ptr() { return shared_from_this(); }
{
Type type; auto serialize() const {
uint32_t message_length; const auto* void_ptr = reinterpret_cast<const void*>(this);
return boost::asio::buffer(void_ptr, get_size());
}
virtual void operator()() {
if (is_handler) {
handle_message();
return;
}
create_message();
}
virtual void handle_message() = 0;
virtual void create_message() {
spdlog::debug("create_message is not implemented yet");
}
protected:
bool is_handler = true;
}; };
struct generic_message_base class draw_rectangle;
{
virtual constexpr Type get_type() const = 0;
virtual uint32_t get_size() const = 0;
//virtual void operator()() template <Type TypeValue>
//{ class generic_message : public generic_message_base {
// if(is_handler) public:
// { virtual ~generic_message() = default;
// handle_message(); virtual constexpr Type get_type() const override { return type_; }
// return;
// }
// create_message(); protected:
//} static constexpr Type type_ = TypeValue;
//virtual void handle_message() = 0;
//virtual void create_message() = 0;
bool is_handler = false;
}; };
template<Type TypeValue> inline std::unique_ptr<generic_message_base> deserialize(
struct generic_message : public generic_message_base char* buffer, std::size_t object_size) {
{ void* base_ptr = std::malloc(object_size);
virtual ~generic_message() = default; std::memcpy(base_ptr, buffer, object_size);
virtual constexpr Type get_type() const override return std::unique_ptr<generic_message_base>(
{ reinterpret_cast<generic_message_base*>(base_ptr));
return type; }
}
virtual header get_header() const struct vec2 {
{ int x, y;
return header{get_type(), get_size()};
}
static constexpr Type type = TypeValue;
}; };
struct message struct vec3 {
{ int x, y, z;
//header head;
//generic_message_base* msg;
//bool init_header()
//{
// if(!msg)
// {
// return false;
// }
// head = msg->get_header();
// return true;
//}
//uint32_t get_size() const
//{
//}
}; };
struct composed_message : public generic_message<Type::COMPOSED_MESSAGE> class draw_rectangle : public generic_message<Type::DRAW_RECTANGLE> {
{ public:
message** messages; virtual ~draw_rectangle() { spdlog::debug("draw_rect dtor"); }
};
struct vec2 virtual uint32_t get_size() const override { return sizeof(*this); }
{
int x,y;
};
struct vec3 virtual void handle_message() override {
{ spdlog::debug("draw_rectangle::handle_message()");
int x,y,z; spdlog::debug("Position: X = {}, Y = {}", position.x, position.y);
}; std::this_thread::sleep_for(std::chrono::seconds(1));
struct draw_rectangle : public generic_message<Type::DRAW_RECTANGLE>
{
virtual ~draw_rectangle() = default;
virtual uint32_t get_size() const override
{
return sizeof(*this);
} }
vec2 position; vec2 position;
@@ -113,78 +96,22 @@ struct draw_rectangle : public generic_message<Type::DRAW_RECTANGLE>
vec3 color; vec3 color;
}; };
struct draw_pixel : public generic_message<Type::DRAW_PIXEL> class draw_pixel : public generic_message<Type::DRAW_PIXEL> {
{ public:
virtual ~draw_pixel() = default; virtual ~draw_pixel() { spdlog::debug("draw_pixel dtor"); }
virtual uint32_t get_size() const override virtual uint32_t get_size() const override { return sizeof(*this); }
{
return sizeof(*this); virtual void handle_message() override {
spdlog::debug("draw_pixel::handle_message()");
spdlog::debug("Color: ({}, {}, {})", color.x, color.y, color.z);
std::this_thread::sleep_for(std::chrono::seconds(1));
} }
vec2 position; vec2 position;
vec3 color; vec3 color;
}; };
//uint32_t get_size(Type type) class Serializer {};
//{
// static std::map<Type, uint32_t> type_map{};
//
// //initalizes map on first run
// static bool run_once = [&](){
// type_map.emplace(Type::DRAW_PIXEL, sizeof(draw_pixel));
// type_map.emplace(Type::DRAW_RECTANGLE, sizeof(draw_rectangle));
// type_map.emplace(Type::COMPOSED_MESSAGE, sizeof(composed_message));
// return true;
// }();
//
// return type_map[type];
//}
} // namespace commons::protocol
//generic_message_base* get_object(Type type, generic_message_base* msg)
//{
// switch(type)
// {
// case Type::COMPOSED_MESSAGE:
// {
// return reinterpret_cast<composed_message*>(msg);
// }
// case Type::DRAW_RECTANGLE:
// {
// return reinterpret_cast<draw_rectangle*>(msg);
// }
// case Type::DRAW_PIXEL:
// {
// return reinterpret_cast<draw_pixel*>(msg);
// }
// default:
// return nullptr;
// }
//}
//template<Type T>
//auto* get_object(generic_message_base* msg)
//{
// return nullptr;
//}
//
//template<>
//auto* get_object<Type::DRAW_PIXEL>(generic_message_base* msg)
//{
// return reinterpret_cast<draw_pixel*>(msg);
//}
//
//template<>
//auto* get_object<Type::DRAW_RECTANGLE>(generic_message_base* msg)
//{
// return reinterpret_cast<draw_rectangle*>(msg);
//}
//
//template<>
//auto* get_object<Type::COMPOSED_MESSAGE>(generic_message_base* msg)
//{
// return reinterpret_cast<composed_message*>(msg);
//}
}

View File

@@ -22,24 +22,14 @@ class server {
void do_receive() { void do_receive() {
spdlog::debug("do receive"); spdlog::debug("do receive");
socket_.async_receive_from( socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_, boost::asio::buffer(data_.data(), max_length), sender_endpoint_,
[this](boost::system::error_code ec, std::size_t bytes_recvd) { [this](boost::system::error_code ec, std::size_t bytes_recvd) {
if (!ec && bytes_recvd > 0) { if (!ec && bytes_recvd > 0) {
std::cout << data_ << std::endl; auto msg_obj = deserialize(data_.data(), bytes_recvd);
msg_obj->handle_message();
auto* msg_obj =
reinterpret_cast<commons::protocol::generic_message_base*>(
data_);
spdlog::debug("Object Type: {}",
static_cast<int>(msg_obj->get_type()));
spdlog::debug("Object Size: {}", msg_obj->get_size());
auto* casted_obj =
reinterpret_cast<commons::protocol::draw_rectangle*>(msg_obj);
spdlog::debug("Position: X = {}, Y = {}", casted_obj->position.x,
casted_obj->position.y);
do_send(bytes_recvd); do_send(bytes_recvd);
spdlog::debug("leaving do receive");
} else { } else {
do_receive(); do_receive();
} }
@@ -47,7 +37,8 @@ class server {
} }
void do_send(std::size_t length) { void do_send(std::size_t length) {
socket_.async_send_to(boost::asio::buffer(data_, length), sender_endpoint_, socket_.async_send_to(boost::asio::buffer(data_.data(), length),
sender_endpoint_,
[this](boost::system::error_code /*ec*/, [this](boost::system::error_code /*ec*/,
std::size_t /*bytes_sent*/) { do_receive(); }); std::size_t /*bytes_sent*/) { do_receive(); });
} }
@@ -56,7 +47,7 @@ class server {
udp::socket socket_; udp::socket socket_;
udp::endpoint sender_endpoint_; udp::endpoint sender_endpoint_;
enum { max_length = 1024 }; enum { max_length = 1024 };
char data_[max_length]; std::array<char, max_length> data_;
}; };
} // namespace commons } // namespace commons

View File

@@ -21,14 +21,15 @@ void client::init() {
auto msg = std::make_unique<commons::protocol::draw_rectangle>(); auto msg = std::make_unique<commons::protocol::draw_rectangle>();
msg->position = commons::protocol::vec2{3, 2}; msg->position = commons::protocol::vec2{3, 2};
void* void_ptr = reinterpret_cast<void*>(msg.get()); socket_.async_send_to(
auto size = sizeof(*msg.get()); msg->serialize(), endpoint_,
spdlog::debug("Object Type: {}", static_cast<int>(msg->get_type())); std::bind(&client::handle_send_to, this, std::placeholders::_1));
spdlog::debug("Object Size: {}", size);
spdlog::debug("Position: X = {}, Y = {}", msg->position.x, msg->position.y); auto msg2 = std::make_unique<commons::protocol::draw_pixel>();
msg2->color = commons::protocol::vec3{255, 0, 0};
socket_.async_send_to( socket_.async_send_to(
boost::asio::buffer(void_ptr, size), endpoint_, msg2->serialize(), endpoint_,
std::bind(&client::handle_send_to, this, std::placeholders::_1)); std::bind(&client::handle_send_to, this, std::placeholders::_1));
} }