From 7c76691df70fd31a4063467679039dad61e4fa67 Mon Sep 17 00:00:00 2001 From: kalipso Date: Tue, 26 Apr 2022 18:54:52 +0200 Subject: [PATCH] add basic serialization functionallity --- include/protocol.hpp | 223 +++++++++++++++---------------------------- include/server.hpp | 23 ++--- src/client.cpp | 13 +-- 3 files changed, 89 insertions(+), 170 deletions(-) diff --git a/include/protocol.hpp b/include/protocol.hpp index 8abb098..00ab4ee 100644 --- a/include/protocol.hpp +++ b/include/protocol.hpp @@ -1,111 +1,94 @@ #pragma once +#include +#include #include - +#include #include #include #include +#include -namespace commons::protocol -{ +#include "spdlog/spdlog.h" -enum class Type -{ +namespace commons::protocol { + +enum class Type { DRAW_RECTANGLE = 0, DRAW_PIXEL, - COMPOSED_MESSAGE, }; +class generic_message_base + : std::enable_shared_from_this { + 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 -{ - Type type; - uint32_t message_length; + auto get_shared_ptr() { return shared_from_this(); } + + auto serialize() const { + const auto* void_ptr = reinterpret_cast(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 -{ - virtual constexpr Type get_type() const = 0; - virtual uint32_t get_size() const = 0; +class draw_rectangle; - //virtual void operator()() - //{ - // if(is_handler) - // { - // handle_message(); - // return; - // } +template +class generic_message : public generic_message_base { + public: + virtual ~generic_message() = default; + virtual constexpr Type get_type() const override { return type_; } - // create_message(); - //} - - //virtual void handle_message() = 0; - //virtual void create_message() = 0; - - bool is_handler = false; + protected: + static constexpr Type type_ = TypeValue; }; -template -struct generic_message : public generic_message_base -{ - virtual ~generic_message() = default; +inline std::unique_ptr deserialize( + char* buffer, std::size_t object_size) { + void* base_ptr = std::malloc(object_size); + std::memcpy(base_ptr, buffer, object_size); - virtual constexpr Type get_type() const override - { - return type; - } + return std::unique_ptr( + reinterpret_cast(base_ptr)); +} - virtual header get_header() const - { - return header{get_type(), get_size()}; - } - - static constexpr Type type = TypeValue; +struct vec2 { + int x, y; }; -struct message -{ - //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 vec3 { + int x, y, z; }; -struct composed_message : public generic_message -{ - message** messages; -}; +class draw_rectangle : public generic_message { + public: + virtual ~draw_rectangle() { spdlog::debug("draw_rect dtor"); } -struct vec2 -{ - int x,y; -}; + virtual uint32_t get_size() const override { return sizeof(*this); } -struct vec3 -{ - int x,y,z; -}; - -struct draw_rectangle : public generic_message -{ - virtual ~draw_rectangle() = default; - - virtual uint32_t get_size() const override - { - return sizeof(*this); + virtual void handle_message() override { + spdlog::debug("draw_rectangle::handle_message()"); + spdlog::debug("Position: X = {}, Y = {}", position.x, position.y); + std::this_thread::sleep_for(std::chrono::seconds(1)); } vec2 position; @@ -113,78 +96,22 @@ struct draw_rectangle : public generic_message vec3 color; }; -struct draw_pixel : public generic_message -{ - virtual ~draw_pixel() = default; +class draw_pixel : public generic_message { + public: + virtual ~draw_pixel() { spdlog::debug("draw_pixel dtor"); } - virtual uint32_t get_size() const override - { - return sizeof(*this); + virtual uint32_t get_size() const override { 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; vec3 color; }; -//uint32_t get_size(Type type) -//{ -// static std::map 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]; -//} +class Serializer {}; - -//generic_message_base* get_object(Type type, generic_message_base* msg) -//{ -// switch(type) -// { -// case Type::COMPOSED_MESSAGE: -// { -// return reinterpret_cast(msg); -// } -// case Type::DRAW_RECTANGLE: -// { -// return reinterpret_cast(msg); -// } -// case Type::DRAW_PIXEL: -// { -// return reinterpret_cast(msg); -// } -// default: -// return nullptr; -// } -//} - -//template -//auto* get_object(generic_message_base* msg) -//{ -// return nullptr; -//} -// -//template<> -//auto* get_object(generic_message_base* msg) -//{ -// return reinterpret_cast(msg); -//} -// -//template<> -//auto* get_object(generic_message_base* msg) -//{ -// return reinterpret_cast(msg); -//} -// -//template<> -//auto* get_object(generic_message_base* msg) -//{ -// return reinterpret_cast(msg); -//} - -} +} // namespace commons::protocol diff --git a/include/server.hpp b/include/server.hpp index e53f937..75e1f24 100644 --- a/include/server.hpp +++ b/include/server.hpp @@ -22,24 +22,14 @@ class server { void do_receive() { spdlog::debug("do receive"); 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) { if (!ec && bytes_recvd > 0) { - std::cout << data_ << std::endl; - - auto* msg_obj = - reinterpret_cast( - data_); - spdlog::debug("Object Type: {}", - static_cast(msg_obj->get_type())); - spdlog::debug("Object Size: {}", msg_obj->get_size()); - - auto* casted_obj = - reinterpret_cast(msg_obj); - spdlog::debug("Position: X = {}, Y = {}", casted_obj->position.x, - casted_obj->position.y); + auto msg_obj = deserialize(data_.data(), bytes_recvd); + msg_obj->handle_message(); do_send(bytes_recvd); + spdlog::debug("leaving do receive"); } else { do_receive(); } @@ -47,7 +37,8 @@ class server { } 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*/, std::size_t /*bytes_sent*/) { do_receive(); }); } @@ -56,7 +47,7 @@ class server { udp::socket socket_; udp::endpoint sender_endpoint_; enum { max_length = 1024 }; - char data_[max_length]; + std::array data_; }; } // namespace commons diff --git a/src/client.cpp b/src/client.cpp index d001b95..b1c1e12 100644 --- a/src/client.cpp +++ b/src/client.cpp @@ -21,14 +21,15 @@ void client::init() { auto msg = std::make_unique(); msg->position = commons::protocol::vec2{3, 2}; - void* void_ptr = reinterpret_cast(msg.get()); - auto size = sizeof(*msg.get()); - spdlog::debug("Object Type: {}", static_cast(msg->get_type())); - spdlog::debug("Object Size: {}", size); - spdlog::debug("Position: X = {}, Y = {}", msg->position.x, msg->position.y); + socket_.async_send_to( + msg->serialize(), endpoint_, + std::bind(&client::handle_send_to, this, std::placeholders::_1)); + + auto msg2 = std::make_unique(); + msg2->color = commons::protocol::vec3{255, 0, 0}; socket_.async_send_to( - boost::asio::buffer(void_ptr, size), endpoint_, + msg2->serialize(), endpoint_, std::bind(&client::handle_send_to, this, std::placeholders::_1)); }