add basic serialization functionallity
This commit is contained in:
@@ -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);
|
|
||||||
//}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user