Serialization for idalloc and animqueue
This commit is contained in:
@@ -6,15 +6,21 @@ AnimStep::AnimStep() {}
|
|||||||
AnimStep::~AnimStep() {}
|
AnimStep::~AnimStep() {}
|
||||||
|
|
||||||
AnimQueue::AnimQueue() {
|
AnimQueue::AnimQueue() {
|
||||||
|
id_ = 0;
|
||||||
size_limit_ = 10; // Default size limit.
|
size_limit_ = 10; // Default size limit.
|
||||||
|
clear_steps();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::clear_steps() {
|
||||||
|
steps_.clear();
|
||||||
steps_.emplace_back();
|
steps_.emplace_back();
|
||||||
AnimStep &init = steps_.back();
|
AnimStep &init = steps_.back();
|
||||||
init.id_ = 0;
|
init.id_ = 0;
|
||||||
|
init.bits_ = AnimStep::HAS_EVERYTHING;
|
||||||
init.facing_ = 0;
|
init.facing_ = 0;
|
||||||
init.xyz_ = util::XYZ(0,0,0);
|
init.xyz_ = util::XYZ(0,0,0);
|
||||||
init.graphic_ = "nothing";
|
init.graphic_ = "nothing";
|
||||||
init.plane_ = "nowhere";
|
init.plane_ = "nowhere";
|
||||||
init.bits_ = AnimStep::HAS_EVERYTHING;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimQueue::set_size_limit(int n) {
|
void AnimQueue::set_size_limit(int n) {
|
||||||
@@ -163,6 +169,94 @@ void AnimQueue::set_plane(const std::string &p) {
|
|||||||
last.plane_ = p;
|
last.plane_ = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AnimQueue::valid() {
|
||||||
|
// Animqueue must have at least one step.
|
||||||
|
if (steps_.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// First action should be blank.
|
||||||
|
if (steps_[0].action_ != "") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// First step should have all bits.
|
||||||
|
if (steps_[0].bits_ != AnimStep::HAS_EVERYTHING) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Any unset bit should correspond to a value copied from the previous step.
|
||||||
|
for (size_t i = 1; i < steps_.size(); i++) {
|
||||||
|
const AnimStep &prev = steps_[i - 1];
|
||||||
|
const AnimStep &curr = steps_[i];
|
||||||
|
if (!curr.has_facing() && (curr.facing_ != prev.facing_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!curr.has_xyz() && (curr.xyz_ != prev.xyz_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!curr.has_graphic() && (curr.graphic_ != prev.graphic_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!curr.has_plane() && (curr.plane_ != prev.plane_)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::serialize(StreamBuffer *sb) {
|
||||||
|
assert(valid()); // can't serialize an invalid animqueue.
|
||||||
|
sb->write_int64(id_);
|
||||||
|
sb->write_int32(size_limit_);
|
||||||
|
sb->write_size(steps_.size());
|
||||||
|
for (const AnimStep &step : steps_) {
|
||||||
|
sb->write_int64(step.id_);
|
||||||
|
sb->write_int16(step.bits_);
|
||||||
|
sb->write_string(step.action_);
|
||||||
|
if (step.has_facing()) {
|
||||||
|
sb->write_float(step.facing_);
|
||||||
|
}
|
||||||
|
if (step.has_xyz()) {
|
||||||
|
sb->write_float(step.xyz_.x);
|
||||||
|
sb->write_float(step.xyz_.y);
|
||||||
|
sb->write_float(step.xyz_.z);
|
||||||
|
}
|
||||||
|
if (step.has_graphic()) {
|
||||||
|
sb->write_string(step.graphic_);
|
||||||
|
}
|
||||||
|
if (step.has_plane()) {
|
||||||
|
sb->write_string(step.plane_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimQueue::deserialize(StreamBuffer *sb) {
|
||||||
|
id_ = sb->read_int64();
|
||||||
|
size_limit_ = sb->read_int32();
|
||||||
|
size_t nsteps = sb->read_size();
|
||||||
|
steps_.clear();
|
||||||
|
steps_.resize(nsteps);
|
||||||
|
for (size_t i = 0; i < nsteps; i++) {
|
||||||
|
AnimStep &step = steps_[i];
|
||||||
|
if (i > 0) step = steps_[i - 1];
|
||||||
|
step.id_ = sb->read_int64();
|
||||||
|
step.bits_ = sb->read_int16();
|
||||||
|
step.action_ = sb->read_string();
|
||||||
|
if (step.has_facing()) {
|
||||||
|
step.facing_ = sb->read_float();
|
||||||
|
}
|
||||||
|
if (step.has_xyz()) {
|
||||||
|
step.xyz_.x = sb->read_float();
|
||||||
|
step.xyz_.y = sb->read_float();
|
||||||
|
step.xyz_.z = sb->read_float();
|
||||||
|
}
|
||||||
|
if (step.has_graphic()) {
|
||||||
|
step.graphic_ = sb->read_string();
|
||||||
|
}
|
||||||
|
if (step.has_plane()) {
|
||||||
|
step.plane_ = sb->read_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const std::string &AnimQueue::get_graphic() const {
|
const std::string &AnimQueue::get_graphic() const {
|
||||||
const AnimStep &last = steps_.back();
|
const AnimStep &last = steps_.back();
|
||||||
return last.graphic_;
|
return last.graphic_;
|
||||||
@@ -181,8 +275,11 @@ const util::XYZ &AnimQueue::get_xyz() const {
|
|||||||
LuaDefine(unittests_animqueue, "c") {
|
LuaDefine(unittests_animqueue, "c") {
|
||||||
// Check initial state.
|
// Check initial state.
|
||||||
AnimQueue aq;
|
AnimQueue aq;
|
||||||
|
StreamBuffer sb;
|
||||||
|
AnimQueue aqds;
|
||||||
aq.set_size_limit(3);
|
aq.set_size_limit(3);
|
||||||
|
|
||||||
|
LuaAssert(L, aq.valid());
|
||||||
LuaAssert(L, aq.size() == 1);
|
LuaAssert(L, aq.size() == 1);
|
||||||
const AnimStep *st = &aq.nth(0);
|
const AnimStep *st = &aq.nth(0);
|
||||||
LuaAssert(L, st->id() == 0);
|
LuaAssert(L, st->id() == 0);
|
||||||
@@ -195,6 +292,7 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
|
|
||||||
// Add a step.
|
// Add a step.
|
||||||
aq.add(12345, "walk");
|
aq.add(12345, "walk");
|
||||||
|
LuaAssert(L, aq.valid());
|
||||||
LuaAssert(L, aq.size() == 2);
|
LuaAssert(L, aq.size() == 2);
|
||||||
st = &aq.nth(1);
|
st = &aq.nth(1);
|
||||||
LuaAssert(L, st->id() == 12345);
|
LuaAssert(L, st->id() == 12345);
|
||||||
@@ -218,6 +316,7 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
aq.set_graphic("something");
|
aq.set_graphic("something");
|
||||||
LuaAssert(L, st->graphic() == "something");
|
LuaAssert(L, st->graphic() == "something");
|
||||||
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE | AnimStep::HAS_GRAPHIC));
|
LuaAssert(L, st->bits() == (AnimStep::HAS_FACING | AnimStep::HAS_XYZ | AnimStep::HAS_PLANE | AnimStep::HAS_GRAPHIC));
|
||||||
|
LuaAssert(L, aq.valid());
|
||||||
|
|
||||||
// Exceed the length limit, dropping first element.
|
// Exceed the length limit, dropping first element.
|
||||||
aq.add(12346, "walk");
|
aq.add(12346, "walk");
|
||||||
@@ -228,5 +327,56 @@ LuaDefine(unittests_animqueue, "c") {
|
|||||||
LuaAssert(L, aq.nth(0).bits() == AnimStep::HAS_EVERYTHING);
|
LuaAssert(L, aq.nth(0).bits() == AnimStep::HAS_EVERYTHING);
|
||||||
LuaAssert(L, aq.nth(1).id() == 12346);
|
LuaAssert(L, aq.nth(1).id() == 12346);
|
||||||
LuaAssert(L, aq.nth(2).id() == 12347);
|
LuaAssert(L, aq.nth(2).id() == 12347);
|
||||||
|
LuaAssert(L, aq.valid());
|
||||||
|
|
||||||
|
// Test serialization and deserialization.
|
||||||
|
aq.set_id(123);
|
||||||
|
aq.set_size_limit(5);
|
||||||
|
aq.clear_steps();
|
||||||
|
aq.add(12345, "walk");
|
||||||
|
aq.set_xyz(util::XYZ(3,4,5));
|
||||||
|
aq.add(12346, "setgraphic");
|
||||||
|
aq.set_graphic("banana");
|
||||||
|
aq.add(12347, "setfacing");
|
||||||
|
aq.set_facing(301.0);
|
||||||
|
aq.serialize(&sb);
|
||||||
|
aqds.deserialize(&sb);
|
||||||
|
|
||||||
|
LuaAssert(L, aqds.get_id() == 123);
|
||||||
|
LuaAssert(L, aqds.size_limit() == 5);
|
||||||
|
LuaAssert(L, aqds.size() == 4);
|
||||||
|
|
||||||
|
LuaAssert(L, aqds.nth(0).id() == 0);
|
||||||
|
LuaAssert(L, aqds.nth(0).bits() == AnimStep::HAS_EVERYTHING);
|
||||||
|
LuaAssert(L, aqds.nth(0).action() == "");
|
||||||
|
LuaAssert(L, aqds.nth(0).facing() == 0.0);
|
||||||
|
LuaAssert(L, aqds.nth(0).xyz() == util::XYZ(0,0,0));
|
||||||
|
LuaAssert(L, aqds.nth(0).graphic() == "nothing");
|
||||||
|
LuaAssert(L, aqds.nth(0).plane() == "nowhere");
|
||||||
|
|
||||||
|
LuaAssert(L, aqds.nth(1).id() == 12345);
|
||||||
|
LuaAssert(L, aqds.nth(1).bits() == AnimStep::HAS_XYZ);
|
||||||
|
LuaAssert(L, aqds.nth(1).action() == "walk");
|
||||||
|
LuaAssert(L, aqds.nth(1).facing() == 0.0);
|
||||||
|
LuaAssert(L, aqds.nth(1).xyz() == util::XYZ(3,4,5));
|
||||||
|
LuaAssert(L, aqds.nth(1).graphic() == "nothing");
|
||||||
|
LuaAssert(L, aqds.nth(1).plane() == "nowhere");
|
||||||
|
|
||||||
|
LuaAssert(L, aqds.nth(2).id() == 12346);
|
||||||
|
LuaAssert(L, aqds.nth(2).bits() == AnimStep::HAS_GRAPHIC);
|
||||||
|
LuaAssert(L, aqds.nth(2).action() == "setgraphic");
|
||||||
|
LuaAssert(L, aqds.nth(2).facing() == 0.0);
|
||||||
|
LuaAssert(L, aqds.nth(2).xyz() == util::XYZ(3,4,5));
|
||||||
|
LuaAssert(L, aqds.nth(2).graphic() == "banana");
|
||||||
|
LuaAssert(L, aqds.nth(2).plane() == "nowhere");
|
||||||
|
|
||||||
|
LuaAssert(L, aqds.nth(3).id() == 12347);
|
||||||
|
LuaAssert(L, aqds.nth(3).bits() == AnimStep::HAS_FACING);
|
||||||
|
LuaAssert(L, aqds.nth(3).action() == "setfacing");
|
||||||
|
LuaAssert(L, aqds.nth(3).facing() == 301.0);
|
||||||
|
LuaAssert(L, aqds.nth(3).xyz() == util::XYZ(3,4,5));
|
||||||
|
LuaAssert(L, aqds.nth(3).graphic() == "banana");
|
||||||
|
LuaAssert(L, aqds.nth(3).plane() == "nowhere");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include <deque>
|
#include <deque>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include "streambuffer.hpp"
|
||||||
#include "util.hpp"
|
#include "util.hpp"
|
||||||
|
|
||||||
|
|
||||||
@@ -45,8 +46,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
int64_t id_;
|
int64_t id_;
|
||||||
|
int16_t bits_;
|
||||||
std::string action_;
|
std::string action_;
|
||||||
int bits_;
|
|
||||||
|
|
||||||
float facing_;
|
float facing_;
|
||||||
util::XYZ xyz_;
|
util::XYZ xyz_;
|
||||||
@@ -58,8 +59,8 @@ public:
|
|||||||
~AnimStep();
|
~AnimStep();
|
||||||
|
|
||||||
int64_t id() const { return id_; }
|
int64_t id() const { return id_; }
|
||||||
const std::string &action() const { return action_; }
|
|
||||||
int bits() const { return bits_; }
|
int bits() const { return bits_; }
|
||||||
|
const std::string &action() const { return action_; }
|
||||||
|
|
||||||
double facing() const { return facing_; }
|
double facing() const { return facing_; }
|
||||||
util::XYZ xyz() const { return xyz_; }
|
util::XYZ xyz() const { return xyz_; }
|
||||||
@@ -75,15 +76,21 @@ public:
|
|||||||
class AnimQueue {
|
class AnimQueue {
|
||||||
private:
|
private:
|
||||||
int64_t id_;
|
int64_t id_;
|
||||||
int size_limit_;
|
int32_t size_limit_;
|
||||||
std::deque<AnimStep> steps_;
|
std::deque<AnimStep> steps_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AnimQueue();
|
AnimQueue();
|
||||||
|
|
||||||
int64_t get_id() const { return id_; }
|
int64_t get_id() const { return id_; }
|
||||||
void set_id(int64_t id) { id_ = id; }
|
void set_id(int64_t id) { id_ = id; }
|
||||||
const AnimStep &nth(int n) const { return steps_[n]; }
|
const AnimStep &nth(int n) const { return steps_[n]; }
|
||||||
int size() const { return steps_.size(); }
|
size_t size() const { return steps_.size(); }
|
||||||
|
int32_t size_limit() const { return size_limit_; }
|
||||||
|
|
||||||
|
// Clear the steps. Doesn't affect size_limit or id.
|
||||||
|
void clear_steps();
|
||||||
|
|
||||||
// Mutators to create new steps from C++
|
// Mutators to create new steps from C++
|
||||||
//
|
//
|
||||||
void add(int64_t id, const std::string &action);
|
void add(int64_t id, const std::string &action);
|
||||||
@@ -92,6 +99,10 @@ public:
|
|||||||
void set_graphic(const std::string &g);
|
void set_graphic(const std::string &g);
|
||||||
void set_plane(const std::string &p);
|
void set_plane(const std::string &p);
|
||||||
|
|
||||||
|
// Serialize or deserialize to a StreamBuffer
|
||||||
|
void serialize(StreamBuffer *sb);
|
||||||
|
void deserialize(StreamBuffer *sb);
|
||||||
|
|
||||||
// Mutator to create new steps from lua.
|
// Mutator to create new steps from lua.
|
||||||
//
|
//
|
||||||
// Lua stack must contain a table, which may contain:
|
// Lua stack must contain a table, which may contain:
|
||||||
@@ -113,8 +124,11 @@ public:
|
|||||||
const std::string &get_plane() const;
|
const std::string &get_plane() const;
|
||||||
const util::XYZ &get_xyz() const;
|
const util::XYZ &get_xyz() const;
|
||||||
|
|
||||||
// Functions for unit testing.
|
// (For testing): change the size limit.
|
||||||
void set_size_limit(int n);
|
void set_size_limit(int32_t n);
|
||||||
|
|
||||||
|
// (For testing): make sure the invariants are preserved.
|
||||||
|
bool valid();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ANIMQUEUE_HPP
|
#endif // ANIMQUEUE_HPP
|
||||||
|
|||||||
@@ -84,24 +84,24 @@ int64_t IdGlobalPool::alloc_id_for_thread(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IdGlobalPool::serialize(StreamBuffer *sb) {
|
void IdGlobalPool::serialize(StreamBuffer *sb) {
|
||||||
sb->write_int64(salvaged_.size());
|
sb->write_int64(next_batch_);
|
||||||
|
sb->write_int64(next_id_);
|
||||||
|
sb->write_int32(queue_fill_);
|
||||||
|
sb->write_size(salvaged_.size());
|
||||||
for (int64_t batch : salvaged_) {
|
for (int64_t batch : salvaged_) {
|
||||||
sb->write_int64(batch);
|
sb->write_int64(batch);
|
||||||
}
|
}
|
||||||
sb->write_int64(next_batch_);
|
|
||||||
sb->write_int64(next_id_);
|
|
||||||
sb->write_int64(queue_fill_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdGlobalPool::deserialize(StreamBuffer *sb) {
|
void IdGlobalPool::deserialize(StreamBuffer *sb) {
|
||||||
int64_t salvaged_size = sb->read_int64();
|
|
||||||
salvaged_.resize(salvaged_size);
|
|
||||||
for (int i=0; i < salvaged_size; i++) {
|
|
||||||
salvaged_[i] = sb->read_int64();
|
|
||||||
}
|
|
||||||
next_batch_ = sb->read_int64();
|
next_batch_ = sb->read_int64();
|
||||||
next_id_ = sb->read_int64();
|
next_id_ = sb->read_int64();
|
||||||
queue_fill_ = sb->read_int64();
|
queue_fill_ = sb->read_int32();
|
||||||
|
size_t salvaged_size = sb->read_size();
|
||||||
|
salvaged_.resize(salvaged_size);
|
||||||
|
for (int i=0; i < int(salvaged_size); i++) {
|
||||||
|
salvaged_[i] = sb->read_int64();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IdPlayerPool::IdPlayerPool(IdGlobalPool *gp) {
|
IdPlayerPool::IdPlayerPool(IdGlobalPool *gp) {
|
||||||
@@ -155,16 +155,16 @@ void IdPlayerPool::prepare_thread(lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IdPlayerPool::serialize(StreamBuffer *sb) {
|
void IdPlayerPool::serialize(StreamBuffer *sb) {
|
||||||
sb->write_int64(ranges_.size());
|
sb->write_size(ranges_.size());
|
||||||
for (int64_t batch : ranges_) {
|
for (int64_t batch : ranges_) {
|
||||||
sb->write_int64(batch);
|
sb->write_int64(batch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IdPlayerPool::deserialize(StreamBuffer *sb) {
|
void IdPlayerPool::deserialize(StreamBuffer *sb) {
|
||||||
int64_t ranges_size = sb->read_int64();
|
size_t ranges_size = sb->read_size();
|
||||||
ranges_.resize(ranges_size);
|
ranges_.resize(ranges_size);
|
||||||
for (int i=0; i < ranges_size; i++) {
|
for (int i=0; i < int(ranges_size); i++) {
|
||||||
ranges_[i] = sb->read_int64();
|
ranges_[i] = sb->read_int64();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,6 +172,9 @@ void IdPlayerPool::deserialize(StreamBuffer *sb) {
|
|||||||
LuaDefine(unittests_idalloc, "c") {
|
LuaDefine(unittests_idalloc, "c") {
|
||||||
IdGlobalPool gp;
|
IdGlobalPool gp;
|
||||||
IdPlayerPool pp(&gp);
|
IdPlayerPool pp(&gp);
|
||||||
|
IdGlobalPool gpds;
|
||||||
|
IdPlayerPool ppds(&gpds);
|
||||||
|
StreamBuffer sb;
|
||||||
|
|
||||||
// Synchronous pools produce IDs starting at 0x001E000000000000
|
// Synchronous pools produce IDs starting at 0x001E000000000000
|
||||||
gp.init_synch(3);
|
gp.init_synch(3);
|
||||||
@@ -277,5 +280,35 @@ LuaDefine(unittests_idalloc, "c") {
|
|||||||
LuaAssert(L, gp.alloc_id_for_thread(L) == 0x0010000000000000);
|
LuaAssert(L, gp.alloc_id_for_thread(L) == 0x0010000000000000);
|
||||||
LuaAssert(L, lua_getnextid(L) == 0);
|
LuaAssert(L, lua_getnextid(L) == 0);
|
||||||
|
|
||||||
|
// Serialize and deserialize a global pool.
|
||||||
|
gp.init_master(3);
|
||||||
|
gpds.init_master(10);
|
||||||
|
LuaAssert(L, gp.get_one() == 0x0010000000000000);
|
||||||
|
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||||
|
gp.salvage(nthbatch(182));
|
||||||
|
gp.salvage(nthbatch(183));
|
||||||
|
gp.serialize(&sb);
|
||||||
|
gpds.deserialize(&sb);
|
||||||
|
LuaAssert(L, gpds.queue_fill() == 3);
|
||||||
|
LuaAssert(L, gpds.get_one() == 0x0010000000000001);
|
||||||
|
LuaAssert(L, gpds.get_batch() == nthbatch(183));
|
||||||
|
LuaAssert(L, gpds.get_batch() == nthbatch(182));
|
||||||
|
LuaAssert(L, gpds.get_batch() == nthbatch(1));
|
||||||
|
|
||||||
|
// Serialize and deserialize a player pool.
|
||||||
|
gp.init_master(3);
|
||||||
|
gpds.init_synch(5);
|
||||||
|
LuaAssert(L, gp.get_batch() == nthbatch(0));
|
||||||
|
pp.purge();
|
||||||
|
pp.refill();
|
||||||
|
LuaAssert(L, pp.size() == 3);
|
||||||
|
ppds.purge();
|
||||||
|
pp.serialize(&sb);
|
||||||
|
ppds.deserialize(&sb);
|
||||||
|
LuaAssert(L, ppds.size() == 3);
|
||||||
|
LuaAssert(L, ppds.get_batch() == nthbatch(1));
|
||||||
|
LuaAssert(L, ppds.get_batch() == nthbatch(2));
|
||||||
|
LuaAssert(L, ppds.get_batch() == nthbatch(3));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ private:
|
|||||||
std::vector<int64_t> salvaged_;
|
std::vector<int64_t> salvaged_;
|
||||||
int64_t next_batch_;
|
int64_t next_batch_;
|
||||||
int64_t next_id_;
|
int64_t next_id_;
|
||||||
int queue_fill_;
|
int32_t queue_fill_;
|
||||||
friend int unittests_idalloc(lua_State *L);
|
friend int unittests_idalloc(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -120,10 +120,8 @@ public:
|
|||||||
// batch if possible. If not, fetches one ID from the global pool.
|
// batch if possible. If not, fetches one ID from the global pool.
|
||||||
int64_t alloc_id_for_thread(lua_State *L);
|
int64_t alloc_id_for_thread(lua_State *L);
|
||||||
|
|
||||||
// Serialize to a streambuffer.
|
// Serialize to or deserialize from a streambuffer.
|
||||||
void serialize(StreamBuffer *sb);
|
void serialize(StreamBuffer *sb);
|
||||||
|
|
||||||
// Deserialize from a streambuffer.
|
|
||||||
void deserialize(StreamBuffer *sb);
|
void deserialize(StreamBuffer *sb);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -163,10 +161,9 @@ public:
|
|||||||
// Return the size of the queue.
|
// Return the size of the queue.
|
||||||
int size() { return ranges_.size(); }
|
int size() { return ranges_.size(); }
|
||||||
|
|
||||||
// Serialize to a streambuffer.
|
// Serialize to or deserialize from a streambuffer.
|
||||||
|
// Caution: the pointer to the global pool is not serialized or deserialized.
|
||||||
void serialize(StreamBuffer *sb);
|
void serialize(StreamBuffer *sb);
|
||||||
|
|
||||||
// Deserialize from a streambuffer.
|
|
||||||
void deserialize(StreamBuffer *sb);
|
void deserialize(StreamBuffer *sb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -139,6 +139,18 @@ void StreamBuffer::write_int64(int64_t v) {
|
|||||||
write_cursor_ += 8;
|
write_cursor_ += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StreamBuffer::write_float(float f) {
|
||||||
|
make_space(4);
|
||||||
|
memcpy(write_cursor_, &f, 4);
|
||||||
|
write_cursor_ += 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StreamBuffer::write_double(double d) {
|
||||||
|
make_space(8);
|
||||||
|
memcpy(write_cursor_, &d, 8);
|
||||||
|
write_cursor_ += 8;
|
||||||
|
}
|
||||||
|
|
||||||
void StreamBuffer::write_bytes(const char *s, int64_t len) {
|
void StreamBuffer::write_bytes(const char *s, int64_t len) {
|
||||||
make_space(len);
|
make_space(len);
|
||||||
memcpy(write_cursor_, s, len);
|
memcpy(write_cursor_, s, len);
|
||||||
@@ -212,6 +224,34 @@ int64_t StreamBuffer::read_int64() {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float StreamBuffer::read_float() {
|
||||||
|
check_available(4);
|
||||||
|
float f;
|
||||||
|
memcpy(&f, read_cursor_, 4);
|
||||||
|
read_cursor_ += 4;
|
||||||
|
return f;
|
||||||
|
}
|
||||||
|
|
||||||
|
double StreamBuffer::read_double() {
|
||||||
|
check_available(8);
|
||||||
|
double d;
|
||||||
|
memcpy(&d, read_cursor_, 8);
|
||||||
|
read_cursor_ += 8;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t StreamBuffer::read_size() {
|
||||||
|
return read_size_limit(0xFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t StreamBuffer::read_size_limit(size_t limit) {
|
||||||
|
int64_t value = read_int64();
|
||||||
|
if ((value < 0)||(value > int64_t(limit))) {
|
||||||
|
throw StreamCorruption();
|
||||||
|
}
|
||||||
|
return size_t(value);
|
||||||
|
}
|
||||||
|
|
||||||
const char *StreamBuffer::read_bytes(int64_t bytes) {
|
const char *StreamBuffer::read_bytes(int64_t bytes) {
|
||||||
check_available(bytes);
|
check_available(bytes);
|
||||||
char *data = read_cursor_;
|
char *data = read_cursor_;
|
||||||
@@ -219,7 +259,11 @@ const char *StreamBuffer::read_bytes(int64_t bytes) {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StreamBuffer::read_string(int64_t max_allowed) {
|
std::string StreamBuffer::read_string() {
|
||||||
|
return read_string_limit(0xFFFFFFF);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string StreamBuffer::read_string_limit(int64_t max_allowed) {
|
||||||
int64_t len = read_uint8();
|
int64_t len = read_uint8();
|
||||||
if (len == 255) {
|
if (len == 255) {
|
||||||
len = read_int64();
|
len = read_int64();
|
||||||
@@ -388,9 +432,9 @@ LuaDefine(unittests_streambuffer, "c") {
|
|||||||
sb11.write_string("");
|
sb11.write_string("");
|
||||||
sb11.write_string("de");
|
sb11.write_string("de");
|
||||||
assert(sb11.layout_is(0, 8, 3));
|
assert(sb11.layout_is(0, 8, 3));
|
||||||
assert(sb11.read_string(1000) == "abc");
|
assert(sb11.read_string() == "abc");
|
||||||
assert(sb11.read_string(1000) == "");
|
assert(sb11.read_string() == "");
|
||||||
assert(sb11.read_string(1000) == "de");
|
assert(sb11.read_string() == "de");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -308,18 +308,22 @@ public:
|
|||||||
char *alloc_space(int64_t bytes);
|
char *alloc_space(int64_t bytes);
|
||||||
void wrote_space(int64_t bytes);
|
void wrote_space(int64_t bytes);
|
||||||
|
|
||||||
// Write values into the buffer.
|
// Write numbers into the buffer.
|
||||||
void write_int8(int8_t v);
|
void write_int8(int8_t v);
|
||||||
void write_int16(int16_t v);
|
void write_int16(int16_t v);
|
||||||
void write_int32(int32_t v);
|
void write_int32(int32_t v);
|
||||||
void write_int64(int64_t v);
|
void write_int64(int64_t v);
|
||||||
|
void write_float(float f);
|
||||||
|
void write_double(double d);
|
||||||
void write_uint8(uint8_t v) { write_int8(v); }
|
void write_uint8(uint8_t v) { write_int8(v); }
|
||||||
void write_uint16(uint16_t v) { write_int16(v); }
|
void write_uint16(uint16_t v) { write_int16(v); }
|
||||||
void write_uint32(uint32_t v) { write_int32(v); }
|
void write_uint32(uint32_t v) { write_int32(v); }
|
||||||
void write_uint64(uint64_t v) { write_int64(v); }
|
void write_uint64(uint64_t v) { write_int64(v); }
|
||||||
|
void write_size(size_t sz) { write_int64(sz); }
|
||||||
void write_bytes(const char *bytes, int64_t len);
|
|
||||||
|
// Write strings or blocks of bytes into the buffer.
|
||||||
void write_string(const std::string &s);
|
void write_string(const std::string &s);
|
||||||
|
void write_bytes(const char *bytes, int64_t len);
|
||||||
void write_ztbytes(const char *bytes);
|
void write_ztbytes(const char *bytes);
|
||||||
|
|
||||||
// Overwrite values previously written to the buffer.
|
// Overwrite values previously written to the buffer.
|
||||||
@@ -332,19 +336,26 @@ public:
|
|||||||
void overwrite_uint32(int64_t write_count_after, uint32_t v) { overwrite_int32(write_count_after, v); }
|
void overwrite_uint32(int64_t write_count_after, uint32_t v) { overwrite_int32(write_count_after, v); }
|
||||||
void overwrite_uint64(int64_t write_count_after, uint64_t v) { overwrite_int64(write_count_after, v); }
|
void overwrite_uint64(int64_t write_count_after, uint64_t v) { overwrite_int64(write_count_after, v); }
|
||||||
|
|
||||||
// Read integers from the buffer. May throw StreamEof.
|
// Read numbers from the buffer. May throw StreamEof.
|
||||||
int8_t read_int8();
|
int8_t read_int8();
|
||||||
int16_t read_int16();
|
int16_t read_int16();
|
||||||
int32_t read_int32();
|
int32_t read_int32();
|
||||||
int64_t read_int64();
|
int64_t read_int64();
|
||||||
|
float read_float();
|
||||||
|
double read_double();
|
||||||
uint8_t read_uint8() { return read_int8(); }
|
uint8_t read_uint8() { return read_int8(); }
|
||||||
uint16_t read_uint16() { return read_int16(); }
|
uint16_t read_uint16() { return read_int16(); }
|
||||||
uint32_t read_uint32() { return read_int32(); }
|
uint32_t read_uint32() { return read_int32(); }
|
||||||
uint64_t read_uint64() { return read_int64(); }
|
uint64_t read_uint64() { return read_int64(); }
|
||||||
|
|
||||||
// Read a string of no more than the specified length. May throw StreamEof
|
// May throw StreamEof or StreamCorruption.
|
||||||
// or StreamCorruption.
|
size_t read_size();
|
||||||
std::string read_string(int64_t max_allowed);
|
size_t read_size_limit(size_t limit);
|
||||||
|
|
||||||
|
// Read a string of no more than the specified length.
|
||||||
|
// May throw StreamEof or StreamCorruption.
|
||||||
|
std::string read_string();
|
||||||
|
std::string read_string_limit(int64_t max_allowed);
|
||||||
|
|
||||||
// Read a block of bytes. May throw StreamEof.
|
// Read a block of bytes. May throw StreamEof.
|
||||||
const char *read_bytes(int64_t bytes);
|
const char *read_bytes(int64_t bytes);
|
||||||
|
|||||||
@@ -52,7 +52,8 @@ struct XYZ {
|
|||||||
float x, y, z;
|
float x, y, z;
|
||||||
XYZ() { x=0; y=0; z=0; }
|
XYZ() { x=0; y=0; z=0; }
|
||||||
XYZ(float ix, float iy, float iz) { x=ix; y=iy; z=iz; }
|
XYZ(float ix, float iy, float iz) { x=ix; y=iy; z=iz; }
|
||||||
bool operator ==(const XYZ &o) { return x==o.x && y == o.y && z==o.z; }
|
bool operator ==(const XYZ &o) const { return x==o.x && y == o.y && z==o.z; }
|
||||||
|
bool operator !=(const XYZ &o) const { return x!=o.x || y != o.y || z!=o.z; }
|
||||||
};
|
};
|
||||||
std::ostream & operator << (std::ostream &out, const XYZ &xyz);
|
std::ostream & operator << (std::ostream &out, const XYZ &xyz);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user