A little code cleanup in AnimQueue
This commit is contained in:
@@ -9,10 +9,6 @@
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
|
||||
util::SharedStdString make_shared_string(const StreamBuffer &sb) {
|
||||
return std::make_shared<std::string>(sb.view());
|
||||
}
|
||||
|
||||
static const char *vtname(AnimValueType vt) {
|
||||
switch (vt) {
|
||||
case T_UNINITIALIZED: return "uninitialized";
|
||||
@@ -423,26 +419,6 @@ void AnimCoreState::decode(std::string_view s) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct StepBreakout {
|
||||
uint64_t hash;
|
||||
std::string_view encstep;
|
||||
StepBreakout(uint64_t h, std::string_view e) : hash(h), encstep(e) {}
|
||||
};
|
||||
|
||||
using StepBreakoutVec = eng::vector<StepBreakout>;
|
||||
|
||||
StepBreakoutVec encqueue_breakout(std::string_view encqueue) {
|
||||
StepBreakoutVec result;
|
||||
StreamBuffer sb(encqueue);
|
||||
while (!sb.empty()) {
|
||||
uint64_t hash = sb.read_uint64();
|
||||
std::string_view encstep = sb.read_string_view();
|
||||
result.emplace_back(hash, encstep);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Just return the hash of the very last step. (Steps are stored last to first).
|
||||
static uint64_t encqueue_final_hash(std::string_view encqueue) {
|
||||
StreamBuffer sb(encqueue);
|
||||
@@ -450,6 +426,7 @@ static uint64_t encqueue_final_hash(std::string_view encqueue) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
// Return the encstep for the final step of the animation queue.
|
||||
static std::string_view encqueue_final_encstep(std::string_view encqueue) {
|
||||
StreamBuffer sb(encqueue);
|
||||
sb.read_uint64();
|
||||
@@ -457,9 +434,9 @@ static std::string_view encqueue_final_encstep(std::string_view encqueue) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return the encqueue for the first N steps. If there aren't that
|
||||
// many steps, then just return them all.
|
||||
std::string_view encqueue_firstn(std::string_view encqueue, int n) {
|
||||
// Return the encqueue for the first N steps.
|
||||
// If there aren't that many steps, then just return them all.
|
||||
std::string_view encqueue_finaln(std::string_view encqueue, int n) {
|
||||
StreamBuffer sb(encqueue);
|
||||
while ((n > 0) && (!sb.empty())) {
|
||||
sb.read_uint64();
|
||||
@@ -487,13 +464,13 @@ void AnimQueue::clear(const AnimState &state) {
|
||||
uint64_t hash = hash_encstep(0, encstep);
|
||||
result.write_uint64(hash);
|
||||
result.write_string(encstep);
|
||||
encqueue_ = make_shared_string(result);
|
||||
encqueue_ = std::make_shared<std::string>(result.view());
|
||||
}
|
||||
|
||||
void AnimQueue::set_limit(int nkeep) {
|
||||
assert((nkeep >= 2) && (nkeep <= 250));
|
||||
size_limit_ = nkeep;
|
||||
encqueue_ = std::make_shared<std::string>(encqueue_firstn(*encqueue_, nkeep));
|
||||
encqueue_ = std::make_shared<std::string>(encqueue_finaln(*encqueue_, nkeep));
|
||||
}
|
||||
|
||||
void AnimQueue::add(const AnimState &state) {
|
||||
@@ -503,8 +480,8 @@ void AnimQueue::add(const AnimState &state) {
|
||||
StreamBuffer result;
|
||||
result.write_uint64(hash);
|
||||
result.write_string(encstep);
|
||||
result.write_bytes(encqueue_firstn(*encqueue_, size_limit_ - 1));
|
||||
encqueue_ = make_shared_string(result);
|
||||
result.write_bytes(encqueue_finaln(*encqueue_, size_limit_ - 1));
|
||||
encqueue_ = std::make_shared<std::string>(result.view());
|
||||
}
|
||||
|
||||
void AnimQueue::serialize(StreamBuffer *sb) const {
|
||||
@@ -557,35 +534,39 @@ bool AnimQueue::exactly_equal_fast(const AnimQueue &other) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
eng::string AnimQueue::steps_debug_string() const {
|
||||
StepBreakoutVec breakout = encqueue_breakout(*encqueue_);
|
||||
eng::ostringstream oss;
|
||||
void AnimQueue::print_debug_string(eng::ostringstream &oss, bool full) const {
|
||||
bool first = true;
|
||||
for (int i = breakout.size() - 1; i >= 0; i--) {
|
||||
const StepBreakout &step = breakout[i];
|
||||
if (!first) oss << "; ";
|
||||
if (full) {
|
||||
oss << "limit=" << size_limit();
|
||||
first = false;
|
||||
AnimState state(step.encstep);
|
||||
state.print_debug_string(oss);
|
||||
}
|
||||
// Break out the steps.
|
||||
eng::vector<std::string_view> encsteps;
|
||||
StreamBuffer sb(*encqueue_);
|
||||
while (!sb.empty()) {
|
||||
sb.read_uint64();
|
||||
encsteps.push_back(sb.read_string_view());
|
||||
}
|
||||
for (int i = encsteps.size() - 1; i >= 0; i --) {
|
||||
if (!first) oss << "; ";
|
||||
AnimState state(encsteps[i]);
|
||||
state.print_debug_string(oss);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
eng::string AnimQueue::steps_debug_string() const {
|
||||
eng::ostringstream oss;
|
||||
print_debug_string(oss, false);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
eng::string AnimQueue::full_debug_string() const {
|
||||
StepBreakoutVec breakout = encqueue_breakout(*encqueue_);
|
||||
eng::ostringstream oss;
|
||||
oss << "limit=" << size_limit();
|
||||
for (int i = breakout.size() - 1; i >= 0; i--) {
|
||||
const StepBreakout &step = breakout[i];
|
||||
oss << "; ";
|
||||
AnimState state(step.encstep);
|
||||
state.print_debug_string(oss);
|
||||
}
|
||||
print_debug_string(oss, true);
|
||||
return oss.str();
|
||||
}
|
||||
|
||||
// Get the final entry, xyz and plane only.
|
||||
//
|
||||
AnimCoreState AnimQueue::get_final_core_state() const {
|
||||
std::string_view encstep = encqueue_final_encstep(*encqueue_);
|
||||
AnimCoreState result;
|
||||
@@ -593,8 +574,6 @@ AnimCoreState AnimQueue::get_final_core_state() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the final entry, all persistent variables.
|
||||
//
|
||||
AnimState AnimQueue::get_final_persistent() const {
|
||||
std::string_view encstep = encqueue_final_encstep(*encqueue_);
|
||||
AnimState result;
|
||||
@@ -602,8 +581,6 @@ AnimState AnimQueue::get_final_persistent() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Get the final entry, everything persistent and non-persistent.
|
||||
//
|
||||
AnimState AnimQueue::get_final_everything() const {
|
||||
std::string_view encstep = encqueue_final_encstep(*encqueue_);
|
||||
AnimState result;
|
||||
@@ -611,7 +588,6 @@ AnimState AnimQueue::get_final_everything() const {
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
LuaDefine(unittests_animqueue, "", "some unit tests") {
|
||||
// Useful objects.
|
||||
AnimQueue aq, aqs;
|
||||
|
||||
@@ -22,23 +22,28 @@
|
||||
// by mixing the hash value of the previous step with the hash value
|
||||
// of the encoded string of key-value pairs.
|
||||
//
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// SERIALIZED STORAGE
|
||||
//
|
||||
// The entired animation queue is stored in a serialized format,
|
||||
// as a shared string. This means that the animation queue can be
|
||||
// passed to the graphics engine as a single string. This vastly
|
||||
// simplifies the API for passing the animation queue to the
|
||||
// graphics engine. It also vastly reduces the amount of computation
|
||||
// done during the graphics engine probe: all we have to do is get
|
||||
// the already existing string and pass a reference to it.
|
||||
// passed to the graphics engine as a single string. This can be
|
||||
// accomplished by the function EngineWrapper.get_animation_queues.
|
||||
//
|
||||
// However, that means that when manipulating the animation queue,
|
||||
// we have to decode it, manipulate it, and then reencode it. This
|
||||
// is a good tradeoff: we update animation queues rarely, compared
|
||||
// to how often we pass them to the graphics engine.
|
||||
// The fact that the queue is stored in a serialized format means
|
||||
// that when manipulating the animation queue, we have to decode it,
|
||||
// manipulate it, and then reencode it.
|
||||
//
|
||||
// From an efficiency perspective, this means that manipulation is
|
||||
// slower, but passing the strings to the graphics engine is faster
|
||||
// and simpler. This is a good tradeoff: we manipulate animation
|
||||
// queues rarely, compared to how often we pass them to the graphics
|
||||
// engine.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// THE SERIALIZED REPRESENTATION
|
||||
//
|
||||
// So first, you need to know how to serialize a single animation
|
||||
// step. Remember, an animation step consists of a list of key-value
|
||||
@@ -287,6 +292,7 @@ public:
|
||||
|
||||
// Debug strings.
|
||||
//
|
||||
void print_debug_string(eng::ostringstream &oss, bool full) const;
|
||||
eng::string steps_debug_string() const;
|
||||
eng::string full_debug_string() const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user