More work on debug_string
This commit is contained in:
@@ -324,14 +324,15 @@ bool AnimStep::from_string(const std::string &config) {
|
||||
}
|
||||
|
||||
AnimQueue::AnimQueue(util::WorldType wt) {
|
||||
world_type_ = wt;
|
||||
version_autoinc_ = (wt == util::WORLD_TYPE_MASTER);
|
||||
size_limit_ = 10; // Default size limit.
|
||||
clear_steps();
|
||||
version_number_ = (wt == util::WORLD_TYPE_MASTER) ? 1 : 0;
|
||||
steps_.emplace_back();
|
||||
steps_.front().keep_state_only();
|
||||
version_number_ = version_autoinc_ ? 1 : 0;
|
||||
}
|
||||
|
||||
void AnimQueue::mutated() {
|
||||
if (world_type_ == util::WORLD_TYPE_MASTER) {
|
||||
if (version_autoinc_) {
|
||||
version_number_ += 1;
|
||||
} else {
|
||||
version_number_ = 0;
|
||||
@@ -353,30 +354,23 @@ bool AnimQueue::size_and_steps_equal(const AnimQueue &other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void AnimQueue::clear_steps() {
|
||||
steps_.clear();
|
||||
steps_.emplace_back();
|
||||
AnimStep &init = steps_.back();
|
||||
init.bits_ = AnimStep::HAS_EVERYTHING;
|
||||
init.action_ = "";
|
||||
init.graphic_ = "";
|
||||
init.plane_ = "";
|
||||
mutated();
|
||||
}
|
||||
|
||||
void AnimQueue::full_clear_and_set_limit(int n) {
|
||||
assert(n >= 1);
|
||||
clear_steps();
|
||||
steps_.clear();
|
||||
steps_.emplace_back();
|
||||
steps_.front().keep_state_only();
|
||||
size_limit_ = n;
|
||||
version_number_ = 1;
|
||||
version_number_ = version_autoinc_ ? 1 : 0;
|
||||
}
|
||||
void AnimQueue::set_limit(int n) {
|
||||
assert(n >= 1);
|
||||
size_limit_ = n;
|
||||
while (int(steps_.size()) > n) {
|
||||
steps_.pop_front();
|
||||
if (int(steps_.size()) > n) {
|
||||
while (int(steps_.size()) > n) {
|
||||
steps_.pop_front();
|
||||
}
|
||||
steps_.front().keep_state_only();
|
||||
}
|
||||
steps_.front().keep_state_only();
|
||||
mutated();
|
||||
}
|
||||
|
||||
@@ -549,12 +543,23 @@ const AnimStep &AnimQueue::back() const {
|
||||
return steps_.back();
|
||||
}
|
||||
|
||||
static bool diff_works(const AnimQueue &master, AnimQueue &sync) {
|
||||
StreamBuffer sb;
|
||||
sync.make_patch(master, &sb);
|
||||
sync.apply_patch(&sb);
|
||||
return sync.size_and_steps_equal(master);
|
||||
}
|
||||
|
||||
LuaDefine(unittests_animqueue, "c") {
|
||||
// Check initial state.
|
||||
// Useful objects.
|
||||
AnimStep stp;
|
||||
AnimQueue aq(util::WORLD_TYPE_MASTER);
|
||||
StreamBuffer sb;
|
||||
AnimQueue aqds(util::WORLD_TYPE_S_SYNC);
|
||||
StreamBuffer sb;
|
||||
|
||||
// Debug string of a newly initialized queue
|
||||
LuaAssert(L, aq.valid());
|
||||
LuaAssertStrEq(L, aq.debug_string(), "version=1; limit=10; id=0 action= plane= x=0 y=0 z=0 facing=0 graphic=");
|
||||
|
||||
// Test the step setters.
|
||||
stp.clear();
|
||||
@@ -572,11 +577,11 @@ LuaDefine(unittests_animqueue, "c") {
|
||||
stp.set_graphic("something");
|
||||
LuaAssertStrEq(L, stp.debug_string(), "id=0 action= plane=somewhere x=3 y=4 z=5 facing=180 graphic=something");
|
||||
|
||||
// Test the step parser.
|
||||
// Test the step debug string parser.
|
||||
LuaAssert(L, stp.from_string("id=123 action=walk x=1 y=2 z=3 facing=4 plane=p graphic=g"));
|
||||
LuaAssertStrEq(L, stp.debug_string(), "id=123 action=walk plane=p x=1 y=2 z=3 facing=4 graphic=g");
|
||||
|
||||
// Test a blank queue.
|
||||
// Test that we can clear a queue.
|
||||
aq.full_clear_and_set_limit(3);
|
||||
LuaAssert(L, aq.valid());
|
||||
LuaAssertStrEq(L, aq.debug_string(), "version=1; limit=3; id=0 action= plane= x=0 y=0 z=0 facing=0 graphic=");
|
||||
@@ -630,28 +635,16 @@ LuaDefine(unittests_animqueue, "c") {
|
||||
// Add a single action to the queue and DT
|
||||
LuaAssert(L, stp.from_string("action=walk x=3 y=4 z=5"));
|
||||
aq.add(12345, stp);
|
||||
sb.clear();
|
||||
LuaAssert(L, aqds.make_patch(aq, &sb));
|
||||
aqds.apply_patch(&sb);
|
||||
LuaAssert(L, aqds.size_and_steps_equal(aq));
|
||||
LuaAssert(L, diff_works(aq, aqds));
|
||||
|
||||
// Add another action and DT
|
||||
LuaAssert(L, stp.from_string("action=fnord plane=where facing=123"));
|
||||
aq.add(232, stp);
|
||||
sb.clear();
|
||||
LuaAssert(L, aqds.make_patch(aq, &sb));
|
||||
sb.write_uint32(0);
|
||||
aqds.apply_patch(&sb);
|
||||
LuaAssert(L, sb.total_writes() - sb.total_reads() == 4);
|
||||
LuaAssert(L, aqds.size_and_steps_equal(aq));
|
||||
LuaAssert(L, diff_works(aq, aqds));
|
||||
|
||||
// Change the queue size limit.
|
||||
aq.set_limit(13);
|
||||
sb.clear();
|
||||
LuaAssert(L, !aqds.size_and_steps_equal(aq));
|
||||
LuaAssert(L, aqds.make_patch(aq, &sb));
|
||||
aqds.apply_patch(&sb);
|
||||
LuaAssert(L, aqds.size_and_steps_equal(aq));
|
||||
LuaAssert(L, diff_works(aq, aqds));
|
||||
|
||||
// compare again, should be no differences.
|
||||
sb.clear();
|
||||
@@ -661,11 +654,7 @@ LuaDefine(unittests_animqueue, "c") {
|
||||
|
||||
// Discard all but the last action.
|
||||
aq.set_limit(1);
|
||||
|
||||
sb.clear();
|
||||
LuaAssert(L, aqds.make_patch(aq, &sb));
|
||||
aqds.apply_patch(&sb);
|
||||
LuaAssert(L, aqds.size_and_steps_equal(aq));
|
||||
LuaAssert(L, diff_works(aq, aqds));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
// equal to the version number in the master model, then the two animqueues are
|
||||
// guaranteed to be equal. Here's how we achieve that invariant:
|
||||
//
|
||||
// * In the master model, the version number starts at 1 and is incremented
|
||||
// * In the master model, the version number starts at 1 and is auto-incremented
|
||||
// every time the animation queue is mutated.
|
||||
//
|
||||
// * In the synchronous model, the version number is set to zero every time the
|
||||
@@ -38,7 +38,7 @@
|
||||
// * The routine 'update_version' should be called after difference
|
||||
// transmission. This copies the version number from the master to the
|
||||
// synchronous model. This is guaranteed to be safe because we just finished
|
||||
// difference transmission, therefore, the animatio queues should match.
|
||||
// difference transmission, therefore, the queues should match.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -67,22 +67,8 @@ public:
|
||||
HAS_GRAPHIC = 16,
|
||||
HAS_PLANE = 32,
|
||||
HAS_EVERYTHING = 63,
|
||||
};
|
||||
};
|
||||
|
||||
private:
|
||||
int64_t id_;
|
||||
int16_t bits_;
|
||||
std::string action_;
|
||||
|
||||
float facing_;
|
||||
util::XYZ xyz_;
|
||||
std::string graphic_;
|
||||
std::string plane_;
|
||||
|
||||
void from_lua_store_string(lua_State *L, int idx, std::string *target, int16_t bits, const char *name);
|
||||
void from_lua_store_number(lua_State *L, int idx, float *target, float offset, int16_t bits, const char *name);
|
||||
|
||||
public:
|
||||
AnimStep();
|
||||
~AnimStep();
|
||||
|
||||
@@ -162,22 +148,27 @@ public:
|
||||
|
||||
// Convert a string to an animstep (for testing only).
|
||||
bool from_string(const std::string &s);
|
||||
|
||||
private:
|
||||
int64_t id_;
|
||||
int16_t bits_;
|
||||
std::string action_;
|
||||
|
||||
float facing_;
|
||||
util::XYZ xyz_;
|
||||
std::string graphic_;
|
||||
std::string plane_;
|
||||
|
||||
void from_lua_store_string(lua_State *L, int idx, std::string *target, int16_t bits, const char *name);
|
||||
void from_lua_store_number(lua_State *L, int idx, float *target, float offset, int16_t bits, const char *name);
|
||||
};
|
||||
|
||||
|
||||
class AnimQueue {
|
||||
private:
|
||||
util::WorldType world_type_;
|
||||
int32_t size_limit_;
|
||||
std::deque<AnimStep> steps_;
|
||||
int64_t version_number_;
|
||||
|
||||
// Called whenever the animation queue is mutated.
|
||||
// serialization and deserialization
|
||||
void mutated();
|
||||
public:
|
||||
public:
|
||||
// World type determines whether versions increment or autozero
|
||||
AnimQueue(util::WorldType wt);
|
||||
|
||||
|
||||
// Simple getters.
|
||||
const AnimStep &nth(int n) const { return steps_[n]; }
|
||||
size_t size() const { return steps_.size(); }
|
||||
@@ -187,11 +178,6 @@ public:
|
||||
// Return true if the size limit and steps are identical.
|
||||
bool size_and_steps_equal(const AnimQueue &aq) const;
|
||||
|
||||
// Clear the steps. Doesn't affect size_limit.
|
||||
// The resulting steps aren't empty. There will be one
|
||||
// step in the queue, which will be on the plane "", at (0,0,0).
|
||||
void clear_steps();
|
||||
|
||||
// Mutator to create a new step.
|
||||
void add(int64_t id, const AnimStep &step);
|
||||
|
||||
@@ -216,6 +202,16 @@ public:
|
||||
|
||||
// Convert to a string for debugging purposes.
|
||||
std::string debug_string() const;
|
||||
|
||||
private:
|
||||
bool version_autoinc_;
|
||||
int32_t size_limit_;
|
||||
std::deque<AnimStep> steps_;
|
||||
int64_t version_number_;
|
||||
|
||||
// Called whenever the animation queue is mutated.
|
||||
// serialization and deserialization
|
||||
void mutated();
|
||||
};
|
||||
|
||||
#endif // ANIMQUEUE_HPP
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#include "idalloc.hpp"
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
|
||||
|
||||
static int64_t nthbatch(int64_t n) {
|
||||
return int64_t(0x0001000000000000) + n*256;
|
||||
}
|
||||
|
||||
static bool ranges_equal(const std::deque<int64_t> &dq, int64_t a, int64_t b, int64_t c) {
|
||||
if (dq.size() != 3) return false;
|
||||
@@ -100,6 +99,17 @@ void IdGlobalPool::deserialize(StreamBuffer *sb) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string IdGlobalPool::debug_string() const {
|
||||
std::ostringstream oss;
|
||||
oss << "next_batch:" << util::hex64() << next_batch_ << " ";
|
||||
oss << "next_id:" << util::hex64() << next_id_ << " ";
|
||||
oss << "salvaged:";
|
||||
for (const int64_t val : salvaged_) {
|
||||
oss << " " << util::hex64() << val;
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
IdPlayerPool::IdPlayerPool(IdGlobalPool *g) {
|
||||
global_ = g;
|
||||
fifo_capacity_ = 0;
|
||||
@@ -252,6 +262,20 @@ void IdPlayerPool::apply_patch(StreamBuffer *sb) {
|
||||
}
|
||||
}
|
||||
|
||||
std::string IdPlayerPool::debug_string() const {
|
||||
std::ostringstream oss;
|
||||
oss << "cap:" << fifo_capacity_ << " ids:";
|
||||
for (int i = 0; i < int(ranges_.size()); i++) {
|
||||
if (i > 0) oss << ",";
|
||||
oss << util::hex64() << ranges_[i];
|
||||
}
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
static int64_t nthbatch(int64_t n) {
|
||||
return int64_t(0x0001000000000000) + n*256;
|
||||
}
|
||||
|
||||
LuaDefine(unittests_idalloc, "c") {
|
||||
IdGlobalPool gp;
|
||||
IdPlayerPool pp(&gp);
|
||||
@@ -425,12 +449,10 @@ LuaDefine(unittests_idalloc, "c") {
|
||||
pp.test_push_back(123);
|
||||
pp.test_push_back(456);
|
||||
|
||||
// transmit and compare. Add extra bytes
|
||||
// transmit and compare.
|
||||
sb.clear();
|
||||
LuaAssert(L, ppds.make_patch(pp, &sb));
|
||||
sb.write_uint32(0);
|
||||
ppds.apply_patch(&sb);
|
||||
LuaAssert(L, sb.total_writes() - sb.total_reads() == 4);
|
||||
LuaAssert(L, ppds.exactly_equal(pp));
|
||||
|
||||
// Pop a value from master pool
|
||||
|
||||
@@ -72,12 +72,6 @@
|
||||
#include "streambuffer.hpp"
|
||||
|
||||
class IdGlobalPool {
|
||||
private:
|
||||
std::vector<int64_t> salvaged_;
|
||||
int64_t next_batch_;
|
||||
int64_t next_id_;
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
|
||||
public:
|
||||
// Construct and destroy global pools. Note that after constructing
|
||||
// a global pool, it is generally also necessary to initialize it
|
||||
@@ -118,15 +112,18 @@ public:
|
||||
// Serialize to or deserialize from a streambuffer.
|
||||
void serialize(StreamBuffer *sb);
|
||||
void deserialize(StreamBuffer *sb);
|
||||
|
||||
// Generate a debug string.
|
||||
std::string debug_string() const;
|
||||
|
||||
private:
|
||||
std::vector<int64_t> salvaged_;
|
||||
int64_t next_batch_;
|
||||
int64_t next_id_;
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
};
|
||||
|
||||
class IdPlayerPool {
|
||||
private:
|
||||
IdGlobalPool *global_;
|
||||
int fifo_capacity_;
|
||||
std::deque<int64_t> ranges_;
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
|
||||
public:
|
||||
// Construct a player pool.
|
||||
//
|
||||
@@ -189,6 +186,15 @@ public:
|
||||
//
|
||||
bool make_patch(const IdPlayerPool &auth, StreamBuffer *sb) const;
|
||||
void apply_patch(StreamBuffer *sb);
|
||||
|
||||
// Debug string.
|
||||
std::string debug_string() const;
|
||||
|
||||
private:
|
||||
IdGlobalPool *global_;
|
||||
int fifo_capacity_;
|
||||
std::deque<int64_t> ranges_;
|
||||
friend int unittests_idalloc(lua_State *L);
|
||||
};
|
||||
|
||||
#endif // IDALLOC_HPP
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#define stat _stat
|
||||
@@ -130,3 +133,23 @@ std::string XYZ::debug_string() const {
|
||||
}
|
||||
|
||||
} // namespace util
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex64 &v) {
|
||||
oss << "0x" << std::setw(16) << std::setfill('0') << std::hex;
|
||||
return oss;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex32 &v) {
|
||||
oss << "0x" << std::setw(8) << std::setfill('0') << std::hex;
|
||||
return oss;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex16 &v) {
|
||||
oss << "0x" << std::setw(4) << std::setfill('0') << std::hex;
|
||||
return oss;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex8 &v) {
|
||||
oss << "0x" << std::setw(2) << std::setfill('0') << std::hex;
|
||||
return oss;
|
||||
}
|
||||
|
||||
@@ -66,6 +66,17 @@ struct XYZ {
|
||||
std::string debug_string() const;
|
||||
};
|
||||
|
||||
// These are formatting directives that can be sent to a std::ostream.
|
||||
class hex64 {};
|
||||
class hex32 {};
|
||||
class hex16 {};
|
||||
class hex8 {};
|
||||
|
||||
} // namespace util
|
||||
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex64 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex32 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex16 &v);
|
||||
std::ostream &operator<<(std::ostream &oss, const util::hex8 &v);
|
||||
|
||||
#endif // UTIL_HPP
|
||||
|
||||
Reference in New Issue
Block a user