Overhaul animation queues so the queue is stored as a single encoded string.
This commit is contained in:
@@ -18,14 +18,63 @@
|
||||
// Persistent values are retained from one animation step to the next,
|
||||
// nonpersistent values exist for one animation step only.
|
||||
//
|
||||
// Animation steps are stored encoded as strings, which is convenient for
|
||||
// passing the data to unreal, but it means that the animation step has to be
|
||||
// decoded whenever you want access to the key-value pairs.
|
||||
//
|
||||
// Each animation step has a hash value. The hash value is generated
|
||||
// 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.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// So first, you need to know how to serialize a single animation
|
||||
// step. Remember, an animation step consists of a list of key-value
|
||||
// pairs (see above). The key-value pairs are serialized as follows:
|
||||
//
|
||||
// for all key-value pairs do:
|
||||
// write_string(key)
|
||||
// write_bool(persistent)
|
||||
// write_uint8(type) // T_STRING, T_NUMBER, T_BOOL, or T_XYZ
|
||||
// switch type:
|
||||
// T_STRING: write_string(value)
|
||||
// T_NUMBER: write_double(value)
|
||||
// T_BOOL: write_bool(value)
|
||||
// T_XYZ: write_xyz(value)
|
||||
//
|
||||
// The encoded string produced by the loop above is called an "encstep".
|
||||
// That's short for "encoded animation step". The encstep has a hash
|
||||
// value, which is a function that accepts the encstep and also the hash
|
||||
// of the previous encstep. Note that the hash is not part of the encstep.
|
||||
//
|
||||
// An animation queue consists of a list of steps. Each step has a hash
|
||||
// and an encstep. An animation queue is serialized as follows:
|
||||
//
|
||||
// for all animation steps, starting with the most recent, do:
|
||||
// write_uint64(hash)
|
||||
// write_string(encstep)
|
||||
//
|
||||
// The encoded string produced by the loop above is called an "encqueue",
|
||||
// because it encodes everything in the animation queue (except for the
|
||||
// size limit, which is separate).
|
||||
//
|
||||
// Since the steps in an encqueue are stored most-recent first, if you
|
||||
// want some information about the most recent animation entry, you
|
||||
// don't need to decode the entire encqueue. You only need to
|
||||
// decode the first step.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ANIMQUEUE_HPP
|
||||
@@ -40,7 +89,6 @@
|
||||
#include "streambuffer.hpp"
|
||||
#include "debugcollector.hpp"
|
||||
#include "util.hpp"
|
||||
#include "enginewrapper.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <ostream>
|
||||
@@ -190,14 +238,6 @@ struct AnimCoreState
|
||||
};
|
||||
|
||||
class AnimQueue : public eng::nevernew {
|
||||
private:
|
||||
struct Step {
|
||||
Step() { hash=0; }
|
||||
Step(const eng::string &e, uint64_t h) : encoding(e), hash(h) {}
|
||||
eng::string encoding;
|
||||
uint64_t hash;
|
||||
};
|
||||
|
||||
public:
|
||||
// Construct an empty animation queue.
|
||||
// clears the state to a valid state.
|
||||
@@ -250,10 +290,6 @@ public:
|
||||
eng::string steps_debug_string() const;
|
||||
eng::string full_debug_string() const;
|
||||
|
||||
// Get the final hash value.
|
||||
//
|
||||
uint64_t get_final_hash() const { return steps_.back().hash; }
|
||||
|
||||
// Get the final entry, xyz and plane only.
|
||||
//
|
||||
AnimCoreState get_final_core_state() const;
|
||||
@@ -266,17 +302,22 @@ public:
|
||||
//
|
||||
AnimState get_final_everything() const;
|
||||
|
||||
// Get the contents of the animation queue for export to the engine wrapper.
|
||||
// Get a serialized representation of the animation queue.
|
||||
//
|
||||
// Caution: this exports pointers into existing allocated strings.
|
||||
// The pointers in this array are only valid until you modify the
|
||||
// animation queue.
|
||||
// Get the entire animation queue in a serialized format (encqueue).
|
||||
// The string returned is a shared string. No string copy
|
||||
// is made during this process.
|
||||
//
|
||||
void get_for_engine_wrapper(std::vector<EngineWrapper::AnimEntry> *into) const;
|
||||
util::SharedStdString get_encoded_queue() const { return encqueue_; }
|
||||
|
||||
private:
|
||||
int size_limit_;
|
||||
eng::deque<Step> steps_;
|
||||
|
||||
// Note: this is stored as a std::string, not an eng::string, because the
|
||||
// ownership ends up being shared between us and the graphics engine. We
|
||||
// can't have the graphics engine affecting the behavior of the engine heap.
|
||||
//
|
||||
util::SharedStdString encqueue_;
|
||||
};
|
||||
|
||||
#endif // ANIMQUEUE_HPP
|
||||
|
||||
Reference in New Issue
Block a user