diff --git a/README.md b/README.md index 11e7bca..cb6f084 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ Look at the numbers and features list, and decide yourself. | | binary size | data size | serialize | deserialize | |------------------------------|-------------|-----------|-------------|-------------| | **test_bitsery** | 64704 | **7565** | **1229 ms** | **1086 ms** | -| **test_bitsery_compression** | 44000 | **4784** | **1370 ms** | **2463 ms** | +| **test_bitsery_compression** | 64880 | **4784** | **1641 ms** | **2462 ms** | | test_yas | 63864 | 11311 | 1616 ms | 1712 ms | | test_yas_compression | 72688 | 8523 | 2387 ms | 2890 ms | | test_cereal | 74848 | 11261 | 6708 ms | 6799 ms | diff --git a/examples/bit_packing.cpp b/examples/bit_packing.cpp new file mode 100644 index 0000000..69e44bf --- /dev/null +++ b/examples/bit_packing.cpp @@ -0,0 +1,64 @@ +#include +#include +//we'll be using std::array as a buffer type, so include traits for this +#include +#include +#include +//include extension that will allow to compress our data +#include + +namespace MyTypes { + + struct Vec3 { float x, y, z; }; + + struct Monster { + Vec3 pos; + std::vector path; + std::string name; + }; + + template + void serialize(S& s, MyTypes::Vec3 &o) { + s.value4b(o.x); + s.value4b(o.y); + s.value4b(o.z); + } + + template + void serialize (S& s, Monster& o) { + s.text1b(o.name, 20); + s.object(o.pos); + //compress path in a range of -1.0 .. 1.0 with 0.01 precision + //enableBitPacking creates separate serializer/deserializer object, that contains bit packing operations + s.enableBitPacking([&o](typename S::BPEnabledType& sbp) { + sbp.container(o.path, 1000, [&sbp](Vec3& vec3) { + constexpr bitsery::ext::ValueRange range{-1.0f,1.0f, 0.01f}; + sbp.ext(vec3.x, range); + sbp.ext(vec3.y, range); + sbp.ext(vec3.z, range); + }); + }); + } +} + +using namespace bitsery; + +//use fixed-size buffer +using Buffer = std::array; +using OutputAdapter = OutputBufferAdapter; +using InputAdapter = InputBufferAdapter; + +int main() { + //set some random data + MyTypes::Monster data{}; + data.name = "lew"; + + //create buffer to store data to + Buffer buffer{}; + auto writtenSize = quickSerialization(buffer, data); + + MyTypes::Monster res; + auto state = quickDeserialization({buffer.begin(), writtenSize}, res); + + assert(state.first == ReaderError::NoError && state.second); +} diff --git a/examples/context_usage.cpp b/examples/context_usage.cpp new file mode 100644 index 0000000..2f623a4 --- /dev/null +++ b/examples/context_usage.cpp @@ -0,0 +1,90 @@ +#include +#include + +#include +#include + +#include + +//defines game mode parameters +struct GameMode { + uint32_t maxMonsters; + uint32_t damageRange[2]; +}; + +namespace MyTypes { + + struct Monster { + std::string name; + uint32_t minDamage; + uint32_t maxDamage; + //... + }; + + struct GameState { + std::vector monsters; + }; + + //default flow for monster + template + void serialize (S& s, Monster& o) { + s.text1b(o.name, 20); + s.value4b(o.minDamage); + s.value4b(o.maxDamage); + } + + template + void serialize(S& s, GameState &o) { + auto mode = static_cast(s.context()); + //we know max number of monsters from context + s.container(o.monsters, mode->maxMonsters, [&s, mode] (Monster& m) { + s.text1b(m.name, 20); + //we know min/max damage range for monsters, so we can use this range instead of full value + bitsery::ext::ValueRange range{mode->damageRange[0], mode->damageRange[1]}; + //enable bit packing + s.enableBitPacking([&m, &range](typename S::BPEnabledType& sbp) { + sbp.ext(m.minDamage, range); + sbp.ext(m.maxDamage, range); + }); + }); + } + +} + +using namespace bitsery; + +//use fixed-size buffer +using Buffer = std::vector; +using OutputAdapter = OutputBufferAdapter; +using InputAdapter = InputBufferAdapter; + +int main() { + MyTypes::GameState data{}; + data.monsters.push_back({"weaksy", 100, 200}); + data.monsters.push_back({"bigsy", 500, 1000}); + data.monsters.push_back({"tootoo", 350, 750}); + + //set game mode + //this store game mode parameters + GameMode mode{}; + mode.maxMonsters = 4; + mode.damageRange[0] = 100; + mode.damageRange[1] = 1000; + + //create buffer to store data to + Buffer buffer{}; + //pass game mode object to serializer as context + Serializer ser{buffer, &mode}; + ser.object(data); + + auto& w = AdapterAccess::getWriter(ser); + w.flush(); + auto writtenSize = w.writtenBytesCount(); + + MyTypes::GameState res; + Deserializer des { InputAdapter{buffer.begin(), writtenSize}, &mode}; + des.object(res); + auto& r = AdapterAccess::getReader(des); + + assert(r.error() == ReaderError::NoError && r.isCompletedSuccessfully()); +} diff --git a/examples/complex_flow.cpp b/examples/forward_backward_compatibility.cpp similarity index 100% rename from examples/complex_flow.cpp rename to examples/forward_backward_compatibility.cpp