Primitive type serialization
This commit is contained in:
@@ -14,8 +14,8 @@ endif()
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
# Set for profiling
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
|
63
Core/include/Core/Serialization.hpp
Normal file
63
Core/include/Core/Serialization.hpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
/// Primitive Serialization Functions.
|
||||
|
||||
/// A data container structure which keeps track of the current position.
|
||||
struct Buffer {
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
/// Writes a 1-byte unsigned int to the buffer, in network-byte-order, and advances the index by 1.
|
||||
void write_u8(Buffer& buffer, uint8_t value);
|
||||
/// Writes a 2-byte unsigned int to the buffer, in network-byte-order, and advances the index by 2.
|
||||
void write_u16(Buffer& buffer, uint16_t value);
|
||||
/// Writes a 4-byte unsigned int to the buffer, in network-byte-order, and advances the index by 4.
|
||||
void write_u32(Buffer& buffer, uint32_t value);
|
||||
/// Writes a 8-byte unsigned int to the buffer, in network-byte-order, and advances the index by 8.
|
||||
void write_u64(Buffer& buffer, uint64_t value);
|
||||
|
||||
/// Reads a 1-byte unsigned int from the buffer, from network-byte-order, and advances the index by 1.
|
||||
uint8_t read_u8(Buffer& buffer);
|
||||
/// Reads a 2-byte unsigned int from the buffer, from network-byte-order, and advances the index by 2.
|
||||
uint16_t read_u16(Buffer& buffer);
|
||||
/// Reads a 4-byte unsigned int from the buffer, from network-byte-order, and advances the index by 4.
|
||||
uint32_t read_u32(Buffer& buffer);
|
||||
/// Reads a 8-byte unsigned int from the buffer, from network-byte-order, and advances the index by 8.
|
||||
uint64_t read_u64(Buffer& buffer);
|
||||
|
||||
/// Writes a 1-byte signed int to the buffer, in network-byte-order, and advances the index by 1.
|
||||
void write_s8(Buffer& buffer, int8_t value);
|
||||
/// Writes a 2-byte signed int to the buffer, in network-byte-order, and advances the index by 2.
|
||||
void write_s16(Buffer& buffer, int16_t value);
|
||||
/// Writes a 4-byte signed int to the buffer, in network-byte-order, and advances the index by 4.
|
||||
void write_s32(Buffer& buffer, int32_t value);
|
||||
/// Writes a 8-byte signed int to the buffer, in network-byte-order, and advances the index by 8.
|
||||
void write_s64(Buffer& buffer, int64_t value);
|
||||
|
||||
/// Reads a 1-byte signed int from the buffer, from network-byte-order, and advances the index by 1.
|
||||
int8_t read_s8(Buffer& buffer);
|
||||
/// Reads a 2-byte signed int from the buffer, from network-byte-order, and advances the index by 2.
|
||||
int16_t read_s16(Buffer& buffer);
|
||||
/// Reads a 4-byte signed int from the buffer, from network-byte-order, and advances the index by 4.
|
||||
int32_t read_s32(Buffer& buffer);
|
||||
/// Reads a 8-byte signed int from the buffer, from network-byte-order, and advances the index by 8.
|
||||
int64_t read_s64(Buffer& buffer);
|
||||
|
||||
/// Writes a 4-byte float to the buffer, via reinterpreting as uint32_t, and advances the index by 4.
|
||||
void write_f32(Buffer& buffer, float value);
|
||||
/// Writes a 8-byte float to the buffer, via reinterpreting as uint64_t, and advances the index by 8.
|
||||
void write_f64(Buffer& buffer, double value);
|
||||
|
||||
/// Reads a 4-byte float from the buffer, via reinterpreting from uint32_t, and advances the index by 4.
|
||||
float read_f32(Buffer& buffer);
|
||||
/// Reads a 8-byte float from the buffer, via reinterpreting from uint64_t, and advances the index by 8.
|
||||
double read_f64(Buffer& buffer);
|
||||
|
||||
}
|
@@ -99,6 +99,9 @@ namespace CaveGame::Core
|
||||
|
||||
/// Calculates the tile to be placed at a given x,y coordinates during the first terrain iteration.
|
||||
TileID Generator::ComputeTile(int wx, int wy) {
|
||||
|
||||
// TODO: Pre-generate height maps instead of computing perlin noise samples at runtime.
|
||||
|
||||
float depth = ComputeDepth(wx, wy);
|
||||
TileID base = HeightMap(depth, wx, wy);
|
||||
|
||||
|
@@ -7,6 +7,8 @@ namespace CaveGame::Core {
|
||||
bounding_box = {16, 24};
|
||||
}
|
||||
|
||||
void Player::Draw() {}
|
||||
|
||||
void Player::Update(float elapsed) {
|
||||
Humanoid::Update(elapsed);
|
||||
}
|
||||
|
145
Core/src/Core/Serialization.cpp
Normal file
145
Core/src/Core/Serialization.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
#include <Core/Serialization.hpp>
|
||||
#include <cstdint>
|
||||
#include <cassert>
|
||||
#include <netinet/in.h>
|
||||
#include <J3ML/Algorithm/Reinterpret.hpp>
|
||||
|
||||
namespace CaveGame::Core
|
||||
{
|
||||
void write_u8(Buffer &buffer, uint8_t value) {
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
*((uint8_t*)(buffer.data + buffer.index)) = (value);
|
||||
buffer.index += 1;
|
||||
}
|
||||
|
||||
void write_u16(Buffer &buffer, uint16_t value) {
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
*((uint16_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 2;
|
||||
}
|
||||
|
||||
void write_u32(Buffer &buffer, uint32_t value) {
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
*((uint32_t*)(buffer.data + buffer.index)) = htonl(value);
|
||||
buffer.index += 4;
|
||||
}
|
||||
|
||||
void write_u64(Buffer &buffer, uint64_t value) {
|
||||
assert(buffer.index + 8 <= buffer.size);
|
||||
*((uint64_t*)(buffer.data + buffer.index)) = htonl(value);
|
||||
buffer.index += 8;
|
||||
}
|
||||
|
||||
uint8_t read_u8(Buffer &buffer) {
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
uint8_t value;
|
||||
value = (*((uint8_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t read_u16(Buffer &buffer) {
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
uint16_t value;
|
||||
value = ntohs(*((uint16_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t read_u32(Buffer &buffer) {
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
uint32_t value;
|
||||
value = ntohl(*((uint32_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t read_u64(Buffer &buffer) {
|
||||
assert(buffer.index + 8 <= buffer.size);
|
||||
uint64_t value;
|
||||
value = ntohl(*((uint64_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void write_s8(Buffer& buffer, int8_t value)
|
||||
{
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
*((int8_t*)(buffer.data + buffer.index)) = (value);
|
||||
buffer.index += 1;
|
||||
}
|
||||
|
||||
void write_s16(Buffer& buffer, int16_t value)
|
||||
{
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
*((int16_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 2;
|
||||
}
|
||||
|
||||
void write_s32(Buffer& buffer, int32_t value)
|
||||
{
|
||||
assert(buffer.index + 3 <= buffer.size);
|
||||
*((int32_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 3;
|
||||
}
|
||||
|
||||
void write_s64(Buffer& buffer, int64_t value)
|
||||
{
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
*((int64_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 3;
|
||||
}
|
||||
|
||||
int8_t read_s8(Buffer& buffer)
|
||||
{
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
int8_t value;
|
||||
value = (*((int8_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 1;
|
||||
return value;
|
||||
}
|
||||
int16_t read_s16(Buffer& buffer)
|
||||
{
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
int16_t value;
|
||||
value = ntohs(*((int16_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 2;
|
||||
return value;
|
||||
}
|
||||
int32_t read_s32(Buffer& buffer)
|
||||
{
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
int32_t value;
|
||||
value = ntohs(*((int32_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
int64_t read_s64(Buffer& buffer)
|
||||
{
|
||||
assert(buffer.index + 8 <= buffer.size);
|
||||
int64_t value;
|
||||
value = ntohs(*((int64_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
using J3ML::ReinterpretAs;
|
||||
|
||||
void write_f32(Buffer &buffer, float value) {
|
||||
write_u32(buffer, ReinterpretAs<uint32_t>(value));
|
||||
}
|
||||
|
||||
void write_f64(Buffer &buffer, double value) {
|
||||
write_u64(buffer, ReinterpretAs<uint64_t>(value));
|
||||
}
|
||||
|
||||
float read_f32(Buffer &buffer) {
|
||||
return ReinterpretAs<float>(read_u32(buffer));
|
||||
}
|
||||
|
||||
double read_f64(Buffer &buffer) {
|
||||
return ReinterpretAs<float>(read_u64(buffer));
|
||||
}
|
||||
}
|
@@ -8,8 +8,7 @@ if (UNIX)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
add_library(CaveServer SHARED ${CaveServer_SRC}
|
||||
include/Server/ServerGameWorld.hpp)
|
||||
add_library(CaveServer SHARED ${CaveServer_SRC})
|
||||
endif()
|
||||
|
||||
target_include_directories(CaveServer PUBLIC
|
||||
|
@@ -9,35 +9,15 @@
|
||||
namespace CaveGame::Server
|
||||
{
|
||||
|
||||
struct Buffer {
|
||||
uint8_t* data;
|
||||
size_t size;
|
||||
size_t index;
|
||||
|
||||
|
||||
|
||||
|
||||
struct ServerInfoPacket
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
void write_u8(Buffer& buffer, uint8_t value);
|
||||
void write_u16(Buffer& buffer, uint16_t value);
|
||||
void write_u32(Buffer& buffer, uint32_t value);
|
||||
void write_u64(Buffer& buffer, uint64_t value);
|
||||
|
||||
uint8_t read_u8(Buffer& buffer);
|
||||
uint16_t read_u16(Buffer& buffer);
|
||||
uint32_t read_u32(Buffer& buffer);
|
||||
uint64_t read_u64(Buffer& buffer);
|
||||
|
||||
void write_s8(Buffer& buffer, int8_t value);
|
||||
void write_s16(Buffer& buffer, int16_t value);
|
||||
void write_s32(Buffer& buffer, int32_t value);
|
||||
void write_s64(Buffer& buffer, int64_t value);
|
||||
|
||||
int8_t read_s8(Buffer& buffer);
|
||||
int16_t read_s16(Buffer& buffer);
|
||||
int32_t read_s32(Buffer& buffer);
|
||||
int64_t read_s64(Buffer& buffer);
|
||||
|
||||
|
||||
|
||||
|
||||
class Peer
|
||||
{
|
||||
public:
|
||||
|
@@ -3,93 +3,6 @@
|
||||
|
||||
namespace CaveGame::Server
|
||||
{
|
||||
void write_u8(Buffer &buffer, uint8_t value) {
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
*((uint8_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 1;
|
||||
}
|
||||
|
||||
void write_u16(Buffer &buffer, uint16_t value) {
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
*((uint16_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 2;
|
||||
}
|
||||
|
||||
void write_u32(Buffer &buffer, uint32_t value) {
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
*((uint32_t*)(buffer.data + buffer.index)) = htonl(value);
|
||||
buffer.index += 4;
|
||||
}
|
||||
|
||||
void write_u64(Buffer &buffer, uint64_t value) {
|
||||
assert(buffer.index + 8 <= buffer.size);
|
||||
*((uint64_t*)(buffer.data + buffer.index)) = htonl(value);
|
||||
buffer.index += 8;
|
||||
}
|
||||
|
||||
uint8_t read_u8(Buffer &buffer) {
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
uint32_t value;
|
||||
value = ntohs(*((uint32_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t read_u16(Buffer &buffer) {
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
uint32_t value;
|
||||
value = ntohs(*((uint32_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t read_u32(Buffer &buffer) {
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
uint32_t value;
|
||||
value = ntohl(*((uint32_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t read_u64(Buffer &buffer) {
|
||||
assert(buffer.index + 8 <= buffer.size);
|
||||
uint64_t value;
|
||||
value = ntohl(*((uint64_t*)(buffer.data + buffer.index)));
|
||||
buffer.index += 8;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void write_s8(Buffer& buffer, int8_t value)
|
||||
{
|
||||
assert(buffer.index + 1 <= buffer.size);
|
||||
*((int8_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 1;
|
||||
}
|
||||
|
||||
void write_s16(Buffer& buffer, int16_t value)
|
||||
{
|
||||
assert(buffer.index + 2 <= buffer.size);
|
||||
*((int16_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 2;
|
||||
}
|
||||
|
||||
void write_s32(Buffer& buffer, int32_t value)
|
||||
{
|
||||
assert(buffer.index + 3 <= buffer.size);
|
||||
*((int32_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 3;
|
||||
}
|
||||
|
||||
void write_s64(Buffer& buffer, int64_t value)
|
||||
{
|
||||
assert(buffer.index + 4 <= buffer.size);
|
||||
*((int64_t*)(buffer.data + buffer.index)) = htons(value);
|
||||
buffer.index += 3;
|
||||
}
|
||||
|
||||
int8_t read_s8(Buffer& buffer);
|
||||
int16_t read_s16(Buffer& buffer);
|
||||
|
||||
|
||||
|
||||
|
@@ -6,13 +6,14 @@ file(GLOB_RECURSE CaveServerApp_SRC "src/*.cpp")
|
||||
add_executable(CaveServerApp main.cpp ${CaveServerApp_SRC})
|
||||
|
||||
target_include_directories(CaveServerApp PUBLIC
|
||||
${CaveCore_SOURCE_DIR}/include
|
||||
${CaveServer_SOURCE_DIR}/include
|
||||
${mcolor_SOURCE_DIR}/include
|
||||
${jlog_SOURCE_DIR}/include
|
||||
${J3ML_SOURCE_DIR}/include
|
||||
${Sockets_SOURCE_DIR}/include)
|
||||
|
||||
target_include_directories(CaveClientApp PUBLIC "include")
|
||||
target_include_directories(CaveServerApp PUBLIC "include")
|
||||
|
||||
target_link_libraries(CaveClientApp PUBLIC mcolor jlog CaveServer J3ML Sockets)
|
||||
target_link_libraries(CaveServerApp PUBLIC mcolor jlog CaveCore CaveServer J3ML Sockets)
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
#include <iostream>
|
||||
|
||||
#include <Sockets/UdpServer.hpp>
|
||||
#include <Core/Serialization.hpp>
|
||||
|
||||
/* Networking Design Notes
|
||||
*
|
||||
@@ -70,7 +71,7 @@ void RunServer() {
|
||||
|
||||
//std::string input;
|
||||
//getline(std::cin, input);
|
||||
// while (input != "exit") {
|
||||
//while (input != "exit") {
|
||||
// getline(std::cin, input);
|
||||
//}
|
||||
|
||||
@@ -111,8 +112,43 @@ void RunClient() {
|
||||
std::cout << "Client closing." << std::endl;
|
||||
}
|
||||
|
||||
void roundtrip_test()
|
||||
{
|
||||
using namespace CaveGame::Core;
|
||||
|
||||
uint8_t a = 128;
|
||||
uint16_t b = 32000;
|
||||
uint32_t c = 666420;
|
||||
|
||||
int8_t d = -64;
|
||||
float e = 3.14159f;
|
||||
|
||||
Buffer test;
|
||||
test.index = 0;
|
||||
test.size = 32;
|
||||
//test.data = ;
|
||||
|
||||
write_u8(test, a);
|
||||
write_u16(test, b);
|
||||
write_u32(test, c);
|
||||
write_s8(test, d);
|
||||
write_f32(test, e);
|
||||
|
||||
test.index = 0;
|
||||
|
||||
a = read_u8(test);
|
||||
b = read_u16(test);
|
||||
c = read_u32(test);
|
||||
d = read_s8(test);
|
||||
e = read_f32(test);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
|
||||
roundtrip_test();
|
||||
|
||||
std::cout << "Running Program" << std::endl;
|
||||
|
||||
|
Reference in New Issue
Block a user