From b7b215f79c3a188d79796f88b23f30e99b0b4bf2 Mon Sep 17 00:00:00 2001 From: jyelon Date: Wed, 16 Aug 2023 15:40:30 -0400 Subject: [PATCH] A little code cleanup in AnimQueue --- luprex/cpp/core/animqueue.cpp | 84 +++++++++++++---------------------- luprex/cpp/core/animqueue.hpp | 26 ++++++----- 2 files changed, 46 insertions(+), 64 deletions(-) diff --git a/luprex/cpp/core/animqueue.cpp b/luprex/cpp/core/animqueue.cpp index 65693017..719bfb9a 100644 --- a/luprex/cpp/core/animqueue.cpp +++ b/luprex/cpp/core/animqueue.cpp @@ -9,10 +9,6 @@ #include #include -util::SharedStdString make_shared_string(const StreamBuffer &sb) { - return std::make_shared(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; - -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(result.view()); } void AnimQueue::set_limit(int nkeep) { assert((nkeep >= 2) && (nkeep <= 250)); size_limit_ = nkeep; - encqueue_ = std::make_shared(encqueue_firstn(*encqueue_, nkeep)); + encqueue_ = std::make_shared(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(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 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; diff --git a/luprex/cpp/core/animqueue.hpp b/luprex/cpp/core/animqueue.hpp index c8cd95cc..fb952ba5 100644 --- a/luprex/cpp/core/animqueue.hpp +++ b/luprex/cpp/core/animqueue.hpp @@ -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;