From ab005fc968a1d3395d21873afa46837746172e79 Mon Sep 17 00:00:00 2001 From: jyelon Date: Mon, 24 Jul 2023 17:21:44 -0400 Subject: [PATCH] Added get_animation_queue to DrivenEngine --- luprex/cpp/core/animqueue.cpp | 11 +++++++++++ luprex/cpp/core/animqueue.hpp | 9 +++++++++ luprex/cpp/core/drivenengine.cpp | 21 +++++++++++++++++++++ luprex/cpp/core/drivenengine.hpp | 4 ++++ luprex/cpp/core/enginewrapper.hpp | 30 ++++++++++++++++++++++++++++++ luprex/cpp/core/world-core.cpp | 7 +++++++ luprex/cpp/core/world.hpp | 7 +++++++ 7 files changed, 89 insertions(+) diff --git a/luprex/cpp/core/animqueue.cpp b/luprex/cpp/core/animqueue.cpp index 0b16469d..fd05f1e7 100644 --- a/luprex/cpp/core/animqueue.cpp +++ b/luprex/cpp/core/animqueue.cpp @@ -611,6 +611,17 @@ AnimState AnimQueue::get_final_everything() const { return result; } +void AnimQueue::get_for_engine_wrapper(std::vector *into) const { + into->resize(steps_.size()); + for (int i = 0; i < int(steps_.size()); i++) { + const AnimQueue::Step &step = steps_[i]; + EngineWrapper::AnimEntry &entry = (*into)[i]; + entry.hash = step.hash; + entry.data = step.encoding.c_str(); + entry.size = step.encoding.size(); + } +} + LuaDefine(unittests_animqueue, "", "some unit tests") { // Useful objects. diff --git a/luprex/cpp/core/animqueue.hpp b/luprex/cpp/core/animqueue.hpp index 9a20959e..931d8edf 100644 --- a/luprex/cpp/core/animqueue.hpp +++ b/luprex/cpp/core/animqueue.hpp @@ -40,6 +40,7 @@ #include "streambuffer.hpp" #include "debugcollector.hpp" #include "util.hpp" +#include "enginewrapper.hpp" #include #include @@ -265,6 +266,14 @@ public: // AnimState get_final_everything() const; + // Get the contents of the animation queue for export to the engine wrapper. + // + // Caution: this exports pointers into existing allocated strings. + // The pointers in this array are only valid until you modify the + // animation queue. + // + void get_for_engine_wrapper(std::vector *into) const; + private: int size_limit_; eng::deque steps_; diff --git a/luprex/cpp/core/drivenengine.cpp b/luprex/cpp/core/drivenengine.cpp index 844f7b8f..3dacc31f 100644 --- a/luprex/cpp/core/drivenengine.cpp +++ b/luprex/cpp/core/drivenengine.cpp @@ -445,6 +445,22 @@ void DrivenEngine::drv_get_animation_queue_hashes(uint32_t count, const int64_t } } +void DrivenEngine::drv_get_animation_queue(uint64_t tanid, uint32_t *count, AnimEntry **entries) { + uint32_t hash1 = eng::memhash(); + anim_queue_result_.clear(); + if ((visible_world_ != 0) && (tanid != 0)) { + visible_world_->get_animation_queue(tanid, &anim_queue_result_); + } + *count = anim_queue_result_.size(); + if (count > 0) { + *entries = &(anim_queue_result_[0]); + } else { + *entries = nullptr; + } + uint32_t hash2 = eng::memhash(); + assert(hash1 == hash2); +} + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // @@ -578,6 +594,10 @@ static void drv_get_animation_queue_hashes(EngineWrapper *w, uint32_t count, con return w->engine->drv_get_animation_queue_hashes(count, ids, hashes); } +static void drv_get_animation_queue(EngineWrapper *w, int64_t tanid, uint32_t *count, EngineWrapper::AnimEntry **entries) { + return w->engine->drv_get_animation_queue(tanid, count, entries); +} + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // @@ -975,6 +995,7 @@ static void init_engine_wrapper_helper(EngineWrapper *w) { w->get_actor_id = drv_get_actor_id; w->get_tangibles_near = drv_get_tangibles_near; w->get_animation_queue_hashes = drv_get_animation_queue_hashes; + w->get_animation_queue = drv_get_animation_queue; w->play_initialize = play_initialize; w->play_clear_new_outgoing = play_clear_new_outgoing; diff --git a/luprex/cpp/core/drivenengine.hpp b/luprex/cpp/core/drivenengine.hpp index 476e2537..c47c3ddf 100644 --- a/luprex/cpp/core/drivenengine.hpp +++ b/luprex/cpp/core/drivenengine.hpp @@ -125,6 +125,8 @@ using SharedChannel = std::shared_ptr; class DrivenEngine : public eng::opnew { public: + using AnimEntry = EngineWrapper::AnimEntry; + ////////////////////////////////////////////////////////////// // // Build the named engine @@ -283,6 +285,7 @@ public: uint64_t drv_get_actor_id() const; void drv_get_tangibles_near(uint64_t tanid, double rx, double ry, double rz, uint32_t *count, int64_t **ids); void drv_get_animation_queue_hashes(uint32_t count, const int64_t *ids, uint64_t *hashes); + void drv_get_animation_queue(uint64_t tanid, uint32_t *count, AnimEntry **entries); void drv_initialize(uint32_t srcpklen, const char *srcpk, int argc, char **argv); void drv_clear_new_outgoing(); @@ -312,6 +315,7 @@ private: World *visible_world_; int64_t visible_actor_id_; util::IdVector scan_result_; + std::vector anim_queue_result_; bool rescan_lua_source_; double clock_; bool stop_driver_; diff --git a/luprex/cpp/core/enginewrapper.hpp b/luprex/cpp/core/enginewrapper.hpp index 4569636d..6be138ef 100644 --- a/luprex/cpp/core/enginewrapper.hpp +++ b/luprex/cpp/core/enginewrapper.hpp @@ -31,6 +31,22 @@ struct EngineWrapper { PlayLogfile *wlog; ReplayLogfile *rlog; + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + // + // STRUCTURES + // + // These structures are used to return complicated values. + // + ////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////// + + struct AnimEntry { + uint64_t hash; + uint32_t size; + const char *data; + }; + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // @@ -116,12 +132,26 @@ struct EngineWrapper { // Do a scan to find tangibles near the specified player. // + // Returns a count and a pointer to an array of tangible IDs. The returned + // pointer is valid until the next call into the engine. + // void (*get_tangibles_near)(EngineWrapper *w, uint64_t tanid, double rx, double ry, double rz, uint32_t *count, int64_t **ids); // Get the hash value of the final animation step for each tangible. // + // You must supply an array of tangible IDs. The animation queue hash for + // each such tangible will be looked up. You must supply a buffer to + // hold the returned hashes. + // void (*get_animation_queue_hashes)(EngineWrapper *w, uint32_t count, const int64_t *ids, uint64_t *hashes); + // Get the entire contents of an animation queue. + // + // Returns a count and a pointer to an array of AnimEntry. The returned + // pointer is valid until the next call into the engine. + // + void (*get_animation_queue)(EngineWrapper *w, int64_t tanid, uint32_t *count, AnimEntry **buffer); + ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // diff --git a/luprex/cpp/core/world-core.cpp b/luprex/cpp/core/world-core.cpp index 90b89959..c39bf6ad 100644 --- a/luprex/cpp/core/world-core.cpp +++ b/luprex/cpp/core/world-core.cpp @@ -238,6 +238,13 @@ void World::get_animation_queue_hashes(uint32_t count, const int64_t *ids, uint6 } } +void World::get_animation_queue(int64_t tanid, std::vector *into) { + Tangible *tan = tangible_get(tanid); + if (tan != nullptr) { + tan->anim_queue_.get_for_engine_wrapper(into); + } +} + World::Redirects World::fetch_redirects() { World::Redirects result = std::move(redirects_); redirects_.clear(); diff --git a/luprex/cpp/core/world.hpp b/luprex/cpp/core/world.hpp index 8eab8edb..4714cf17 100644 --- a/luprex/cpp/core/world.hpp +++ b/luprex/cpp/core/world.hpp @@ -142,6 +142,13 @@ public: // void get_animation_queue_hashes(uint32_t count, const int64_t *ids, uint64_t *hashes); + // Get the animation queue for the graphics engine. + // + // Gets the animation queue of a tangible in a form that can be + // passed to the graphics engine. + // + void get_animation_queue(int64_t tanid, std::vector *into); + // Make a tangible. // // You must provide a valid previously-unused ID. Otherwise, leaves the lua