From 49484cf2f043ea624102a25e02853fcf3083b45e Mon Sep 17 00:00:00 2001 From: Josh Yelon Date: Mon, 26 Jul 2021 13:12:44 -0400 Subject: [PATCH] Fix constness in certain operations --- luprex/core/cpp/animqueue.cpp | 16 ++++-- luprex/core/cpp/animqueue.hpp | 4 +- luprex/core/cpp/idalloc.cpp | 4 +- luprex/core/cpp/idalloc.hpp | 4 +- luprex/core/cpp/util.hpp | 1 + luprex/core/cpp/world.cpp | 99 ++++++++++++++++++++++------------- luprex/core/cpp/world.hpp | 21 ++++---- 7 files changed, 95 insertions(+), 54 deletions(-) diff --git a/luprex/core/cpp/animqueue.cpp b/luprex/core/cpp/animqueue.cpp index bf6e0f93..f6d8979e 100644 --- a/luprex/core/cpp/animqueue.cpp +++ b/luprex/core/cpp/animqueue.cpp @@ -425,9 +425,8 @@ std::string AnimQueue::debug_string() const { return oss.str(); } -void AnimQueue::serialize(StreamBuffer *sb) { +void AnimQueue::serialize_size_and_steps(StreamBuffer *sb) const { assert(valid()); // can't serialize an invalid animqueue. - sb->write_int64(version_number_); sb->write_uint8(size_limit_); sb->write_uint8(steps_.size()); for (const AnimStep &step : steps_) { @@ -435,8 +434,12 @@ void AnimQueue::serialize(StreamBuffer *sb) { } } -void AnimQueue::deserialize(StreamBuffer *sb) { - version_number_ = sb->read_int64(); +void AnimQueue::serialize(StreamBuffer *sb) const { + serialize_size_and_steps(sb); + sb->write_int64(version_number_); +} + +void AnimQueue::deserialize_size_and_steps(StreamBuffer *sb) { size_limit_ = sb->read_uint8(); size_t nsteps = sb->read_uint8(); steps_.resize(nsteps); @@ -447,6 +450,11 @@ void AnimQueue::deserialize(StreamBuffer *sb) { } } +void AnimQueue::deserialize(StreamBuffer *sb) { + deserialize_size_and_steps(sb); + version_number_ = sb->read_int64(); +} + bool AnimQueue::need_patch(const AnimQueue &auth) const { // Sanity check. assert(valid()); diff --git a/luprex/core/cpp/animqueue.hpp b/luprex/core/cpp/animqueue.hpp index 6ad65c51..ab7edc4e 100644 --- a/luprex/core/cpp/animqueue.hpp +++ b/luprex/core/cpp/animqueue.hpp @@ -182,7 +182,9 @@ public: void add(int64_t id, const AnimStep &step); // Serialize or deserialize to a StreamBuffer - void serialize(StreamBuffer *sb); + void serialize_size_and_steps(StreamBuffer *sb) const; + void deserialize_size_and_steps(StreamBuffer *sb); + void serialize(StreamBuffer *sb) const; void deserialize(StreamBuffer *sb); // Difference transmission diff --git a/luprex/core/cpp/idalloc.cpp b/luprex/core/cpp/idalloc.cpp index e1408800..698e5de5 100644 --- a/luprex/core/cpp/idalloc.cpp +++ b/luprex/core/cpp/idalloc.cpp @@ -80,7 +80,7 @@ int64_t IdGlobalPool::alloc_id_for_thread(lua_State *L) { } } -void IdGlobalPool::serialize(StreamBuffer *sb) { +void IdGlobalPool::serialize(StreamBuffer *sb) const { sb->write_int64(next_batch_); sb->write_int64(next_id_); sb->write_uint32(salvaged_.size()); @@ -171,7 +171,7 @@ void IdPlayerPool::prepare_thread(lua_State *L) { lua_setnextid(L, get_batch()); } -void IdPlayerPool::serialize(StreamBuffer *sb) { +void IdPlayerPool::serialize(StreamBuffer *sb) const { sb->write_uint8(fifo_capacity_); sb->write_uint8(ranges_.size()); for (int64_t batch : ranges_) { diff --git a/luprex/core/cpp/idalloc.hpp b/luprex/core/cpp/idalloc.hpp index 004f4098..a570e528 100644 --- a/luprex/core/cpp/idalloc.hpp +++ b/luprex/core/cpp/idalloc.hpp @@ -110,7 +110,7 @@ public: int64_t alloc_id_for_thread(lua_State *L); // Serialize to or deserialize from a streambuffer. - void serialize(StreamBuffer *sb); + void serialize(StreamBuffer *sb) const; void deserialize(StreamBuffer *sb); // Generate a debug string. @@ -176,7 +176,7 @@ public: // Serialize to or deserialize from a streambuffer. // Caution: the pointer to the global pool is not serialized or deserialized. - void serialize(StreamBuffer *sb); + void serialize(StreamBuffer *sb) const; void deserialize(StreamBuffer *sb); // Difference transmission diff --git a/luprex/core/cpp/util.hpp b/luprex/core/cpp/util.hpp index 39e7808c..74003825 100644 --- a/luprex/core/cpp/util.hpp +++ b/luprex/core/cpp/util.hpp @@ -8,6 +8,7 @@ #include #include #include +#include "luastack.hpp" namespace util { diff --git a/luprex/core/cpp/world.cpp b/luprex/core/cpp/world.cpp index eec88a4a..51e81cbb 100644 --- a/luprex/core/cpp/world.cpp +++ b/luprex/core/cpp/world.cpp @@ -98,8 +98,17 @@ Tangible *World::tangible_get(int64_t id) { } } -std::vector World::tangible_get_all(const std::vector &ids) { - std::vector result(ids.size()); +const Tangible *World::tangible_get(int64_t id) const { + auto iter = tangibles_.find(id); + if (iter == tangibles_.end()) { + return nullptr; + } else { + return iter->second.get(); + } +} + +World::TanVector World::tangible_get_all(const IdVector &ids) const { + TanVector result(ids.size()); for (int i = 0; i < int(ids.size()); i++) { result[i] = tangible_get(ids[i]); } @@ -152,8 +161,8 @@ void World::tangible_delete(lua_State *L, int64_t id) { LS.result(); } -util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) { - Tangible *player = tangible_get(player_id); +util::IdVector World::get_near(int64_t player_id, float radius, bool exclude_nowhere) const { + const Tangible *player = tangible_get(player_id); if (player == nullptr) { return IdVector(); } @@ -494,24 +503,54 @@ void World::rollback() { deserialize(&snapshot_); } -void World::difference_transmit(int64_t actor_id, World *master, StreamBuffer *sb) { +void World::difference_transmit(int64_t actor_id, const World *master, StreamBuffer *sb) { StreamBuffer tsb; - diff_actor_essentials(actor_id, master, &tsb); + // Get the actor in both models. + const Tangible *s_actor = tangible_get(actor_id); + const Tangible *m_actor = master->tangible_get(actor_id); + assert(s_actor != nullptr); + assert(m_actor != nullptr); + + // Pass one: update the actor essentials. + assert(tsb.at_eof()); + diff_actor_essentials(m_actor, s_actor, &tsb); tsb.copy_into(sb); patch_actor_essentials(&tsb); - diff_visible_animations(actor_id, master, &tsb); + // Get the list of tangibles visible in either model. + // Some tangibles may be missing in the master, some may be missing in the sync. + util::IdVector visible = PlaneMap::sort_union_id_vectors( + master->get_near(actor_id, 100.0, true), + this->get_near(actor_id, 100.0, true)); + TanVector m_visible = tangible_get_all(visible); + TanVector s_visible = tangible_get_all(visible); + assert(m_visible.size() == s_visible.size()); + + // Pass two: update visible animations. + assert(tsb.at_eof()); + diff_visible_animations(m_visible, s_visible, &tsb); tsb.copy_into(sb); patch_visible_animations(&tsb); + + // Copy the version number from master animqueue to synch animqueue. + for (int i = 0; i < int(m_visible.size()); i++) { + const Tangible *m_tan = m_visible[i]; + if (m_tan != nullptr) { + Tangible *s_tan = const_cast(s_visible[i]); + if (s_tan == nullptr) { + s_tan = tangible_get(m_tan->id()); + assert(s_tan != nullptr); + } + s_tan->anim_queue_.update_version(m_tan->anim_queue_); + } + } + + assert(tsb.at_eof()); } -void World::diff_actor_essentials(int64_t actor_id, World *master, StreamBuffer *sb) { - Tangible *s_actor = tangible_get(actor_id); - Tangible *m_actor = master->tangible_get(actor_id); - assert(s_actor != nullptr); - assert(m_actor != nullptr); - sb->write_int64(actor_id); +void World::diff_actor_essentials(const Tangible *m_actor, const Tangible *s_actor, StreamBuffer *sb) { + sb->write_int64(m_actor->id()); s_actor->id_player_pool_.diff(m_actor->id_player_pool_, sb); s_actor->anim_queue_.diff(m_actor->anim_queue_, sb); } @@ -524,29 +563,19 @@ void World::patch_actor_essentials(StreamBuffer *sb) { s_actor->update_plane_item(); } -void World::diff_visible_animations(int64_t actor_id, World *master, StreamBuffer *sb) { - // Get the list of tangibles visible in either model. - util::IdVector visible = PlaneMap::sort_union_id_vectors( - master->get_near(actor_id, 100.0, true), - this->get_near(actor_id, 100.0, true)); - - // Some tangibles may be missing in the master, some may be missing in the sync. - std::vector m_visible = tangible_get_all(visible); - std::vector s_visible = tangible_get_all(visible); - assert(m_visible.size() == s_visible.size()); - +void World::diff_visible_animations(const TanVector &mvis, const TanVector &svis, StreamBuffer *sb) { // For each tangible missing in the synchronous model, send the // necessary information to create the tangible. sb->write_int32(0); int count_pos = sb->total_writes(); int count = 0; - for (int i = 0; i < int(s_visible.size()); i++) { - Tangible *mt = m_visible[i]; - Tangible *st = s_visible[i]; + for (int i = 0; i < int(svis.size()); i++) { + const Tangible *mt = mvis[i]; + const Tangible *st = svis[i]; if (st == nullptr) { count += 1; sb->write_int64(mt->id()); - mt->anim_queue_.serialize(sb); + mt->anim_queue_.serialize_size_and_steps(sb); } } sb->overwrite_int32(count_pos, count); @@ -556,9 +585,9 @@ void World::diff_visible_animations(int64_t actor_id, World *master, StreamBuffe sb->write_int32(0); count_pos = sb->total_writes(); count = 0; - for (int i = 0; i < int(s_visible.size()); i++) { - Tangible *mt = m_visible[i]; - Tangible *st = s_visible[i]; + for (int i = 0; i < int(svis.size()); i++) { + const Tangible *mt = mvis[i]; + const Tangible *st = svis[i]; if (mt == nullptr) { count += 1; sb->write_int64(st->id()); @@ -571,9 +600,9 @@ void World::diff_visible_animations(int64_t actor_id, World *master, StreamBuffe sb->write_int32(0); count_pos = sb->total_writes(); count = 0; - for (int i = 0; i < int(s_visible.size()); i++) { - Tangible *mt = m_visible[i]; - Tangible *st = s_visible[i]; + for (int i = 0; i < int(svis.size()); i++) { + const Tangible *mt = mvis[i]; + const Tangible *st = svis[i]; if ((mt != nullptr) && (st != nullptr)) { if (st->anim_queue_.need_patch(mt->anim_queue_)) { count++; @@ -591,7 +620,7 @@ void World::patch_visible_animations(StreamBuffer *sb) { for (int i = 0; i < count; i++) { int64_t id = sb->read_int64(); Tangible *t = tangible_make(state(), id, false); - t->anim_queue_.deserialize(sb); + t->anim_queue_.deserialize_size_and_steps(sb); t->update_plane_item(); } diff --git a/luprex/core/cpp/world.hpp b/luprex/core/cpp/world.hpp index a511da3d..4e51df90 100644 --- a/luprex/core/cpp/world.hpp +++ b/luprex/core/cpp/world.hpp @@ -68,7 +68,7 @@ public: // Get the ID // - int64_t id() { return plane_item_.id(); } + int64_t id() const { return plane_item_.id(); } void update_plane_item(); bool is_an_actor() { return (id_player_pool_.get_fifo_capacity() > 0); } @@ -78,7 +78,7 @@ public: class World { public: using IdVector = util::IdVector; - using TangibleVector = std::vector; + using TanVector = std::vector; using Redirects = std::map; // Constructor. @@ -107,7 +107,7 @@ public: // Get a list of the tangibles that are near the player. If 'exclude_nowhere' is // true, exclude any tangibles on the nowhere plane. // - IdVector get_near(int64_t player_id, float radius, bool exclude_nowhere); + IdVector get_near(int64_t player_id, float radius, bool exclude_nowhere) const; // Make a tangible. // @@ -120,10 +120,7 @@ public: // Get a pointer to the specified tangible. // Tangible *tangible_get(int64_t id); - - // Get pointers to many tangibles. - // - TangibleVector tangible_get_all(const IdVector &ids); + const Tangible *tangible_get(int64_t id) const; // Get a pointer to the specified tangible. // @@ -131,6 +128,10 @@ public: // a lua error is generated. // Tangible *tangible_get(lua_State *L, int idx); + + // Get pointers to many tangibles. + // + TanVector tangible_get_all(const IdVector &ids) const; // Delete the specified tangible. // @@ -182,7 +183,7 @@ public: // so that they can be sent to the client. It also applies the diffs // to this model. // - void difference_transmit(int64_t actor, World *master, StreamBuffer *sb); + void difference_transmit(int64_t actor, const World *master, StreamBuffer *sb); // Apply differences. // @@ -213,7 +214,7 @@ private: // Before we do anything else, we need to get the actor in the right place. // We also update the actor's ID allocation pipeline. // - void diff_actor_essentials(int64_t actor_id, World *master, StreamBuffer *sb); + static void diff_actor_essentials(const Tangible *mactor, const Tangible *sactor, StreamBuffer *sb); void patch_actor_essentials(StreamBuffer *sb); // Pass 2 of difference transmission: visible animations. @@ -221,7 +222,7 @@ private: // Synchronizes the animation status of every tangible inside the visibility // radius of either model. Creates missing tangibles and deletes excess tangibles. // - void diff_visible_animations(int64_t actor_id, World *master, StreamBuffer *sb); + static void diff_visible_animations(const TanVector &mvis, const TanVector &svis, StreamBuffer *sb); void patch_visible_animations(StreamBuffer *sb); private: