From 66d372d810358424bf692518404820d3ebe0e152 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Thu, 18 Dec 2025 23:37:37 +0300 Subject: [PATCH] Automatically finalize any delayed update objects --- .../DelayUpdateSerializedClassManager.cpp | 12 ++++++-- .../DelayUpdateSerializedClassManager.hpp | 29 +++++++++++++++++-- src/CanvasTheme.cpp | 2 +- src/World.cpp | 2 +- 4 files changed, 38 insertions(+), 7 deletions(-) diff --git a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.cpp b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.cpp index 84c42eb..c55a3f8 100644 --- a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.cpp +++ b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.cpp @@ -1,9 +1,17 @@ #include "DelayUpdateSerializedClassManager.hpp" +#include namespace NetworkingObjects { - void DelayUpdateSerializedClassManager::update() { + void DelayUpdateSerializedClassManager::update(NetworkingObjects::NetObjManager& netObjMan) { + for(auto& [objID, updatingObj] : updatingObjs) { + if(updatingObj.lastTemporaryUpdateTimePoint.has_value() && (std::chrono::steady_clock::now() - updatingObj.lastTemporaryUpdateTimePoint.value()) >= std::chrono::milliseconds(300)) { + updatingObj.sendFinalUpdate(); + std::cout << "yay!" << std::endl; + updatingObj.lastTemporaryUpdateTimePoint = std::nullopt; + } + } std::erase_if(updatingObjs, [](auto& updatingPair) { - if((std::chrono::steady_clock::now() - updatingPair.second.lastUpdateTimePoint) >= std::chrono::seconds(3)) { + if((std::chrono::steady_clock::now() - updatingPair.second.lastUpdateTimePoint) >= std::chrono::seconds(3) && !updatingPair.second.lastTemporaryUpdateTimePoint.has_value()) { updatingPair.second.setDataAfterTimeout(); return true; } diff --git a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp index 91432a2..22f9e60 100644 --- a/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp +++ b/include/Helpers/NetworkingObjects/DelayUpdateSerializedClassManager.hpp @@ -60,12 +60,12 @@ namespace NetworkingObjects { // TODO: When finalUpdate = false, maybe add a small delay between updates instead of sending them every frame? o.send_update_to_all(finalUpdate ? RELIABLE_COMMAND_CHANNEL : UNRELIABLE_COMMAND_CHANNEL, [&](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { if(o.get_obj_man()->is_server()) - server_write_func(o, a); + server_write_func(o, a, finalUpdate); else client_write_update_func(o, a, finalUpdate); }); } - void update(); + void update(NetworkingObjects::NetObjManager& netObjMan); private: template void client_write_update_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a, bool finalUpdate) { a(finalUpdate); @@ -84,11 +84,22 @@ namespace NetworkingObjects { typeIndexFuncs[std::type_index(typeid(T))].postUpdateFunc(static_cast(oLock.get())); } }; + toAdd.sendFinalUpdate = [&typeIndexFuncs = typeIndexFuncs, oWeak = NetObjWeakPtr(o)]() { + NetObjTemporaryPtr oLock = oWeak.lock(); + if(oLock) { + oLock.send_update_to_all(RELIABLE_COMMAND_CHANNEL, [&typeIndexFuncs = typeIndexFuncs](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { + a(true); // It's the final update (sent over reliable channel) + typeIndexFuncs[std::type_index(typeid(T))].writeUpdateFunc(static_cast(o.get()), a); + }); + } + }; + toAdd.lastTemporaryUpdateTimePoint = finalUpdate ? std::nullopt : std::optional(std::chrono::steady_clock::now()); updatingObjs.emplace(o.get_net_id(), toAdd); } else { auto& [netID, updatingObjData] = *it; updatingObjData.lastUpdateTimePoint = std::chrono::steady_clock::now(); + updatingObjData.lastTemporaryUpdateTimePoint = finalUpdate ? std::nullopt : std::optional(std::chrono::steady_clock::now()); } } @@ -105,7 +116,7 @@ namespace NetworkingObjects { } } - template void server_write_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { + template void server_write_func(const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a, bool finalUpdate) { typeIndexFuncs[std::type_index(typeid(T))].writeUpdateFunc(static_cast(o.get()), a); auto it = updatingObjs.find(o.get_net_id()); @@ -124,11 +135,21 @@ namespace NetworkingObjects { }); } }; + toAdd.sendFinalUpdate = [&typeIndexFuncs = typeIndexFuncs, oWeak = NetObjWeakPtr(o)]() { + NetObjTemporaryPtr oLock = oWeak.lock(); + if(oLock) { + oLock.send_update_to_all(RELIABLE_COMMAND_CHANNEL, [&typeIndexFuncs = typeIndexFuncs](const NetObjTemporaryPtr& o, cereal::PortableBinaryOutputArchive& a) { + typeIndexFuncs[std::type_index(typeid(T))].writeUpdateFunc(static_cast(o.get()), a); + }); + } + }; + toAdd.lastTemporaryUpdateTimePoint = finalUpdate ? std::nullopt : std::optional(std::chrono::steady_clock::now()); updatingObjs.emplace(o.get_net_id(), toAdd); } else { auto& [netID, updatingObjData] = *it; updatingObjData.lastUpdateTimePoint = std::chrono::steady_clock::now(); + updatingObjData.lastTemporaryUpdateTimePoint = finalUpdate ? std::nullopt : std::optional(std::chrono::steady_clock::now()); typeIndexFuncs[std::type_index(typeid(T))].assignmentFunc(static_cast(updatingObjs[o.get_net_id()].objToUpdateCurrentData.get()), static_cast(o.get())); *updatingObjData.doLastAssignment = false; } @@ -158,6 +179,8 @@ namespace NetworkingObjects { std::shared_ptr doLastAssignment; std::chrono::steady_clock::time_point lastUpdateTimePoint; std::function setDataAfterTimeout; + std::optional lastTemporaryUpdateTimePoint; + std::function sendFinalUpdate; }; std::unordered_map updatingObjs; diff --git a/src/CanvasTheme.cpp b/src/CanvasTheme.cpp index 44ceaec..eb304c1 100644 --- a/src/CanvasTheme.cpp +++ b/src/CanvasTheme.cpp @@ -32,7 +32,7 @@ const SkColor4f& CanvasTheme::get_tool_front_color() const { void CanvasTheme::set_back_color(const Vector3f& newBackColor) { if(backColor && newBackColor != backColor->c) { backColor->c = newBackColor; - world.delayedUpdateObjectManager.send_update_to_all(backColor, true); + world.delayedUpdateObjectManager.send_update_to_all(backColor, false); set_tool_front_color(world.drawProg); } } diff --git a/src/World.cpp b/src/World.cpp index d4170d2..51f60d3 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -217,7 +217,7 @@ void World::focus_update() { } if(!clientStillConnecting) { - delayedUpdateObjectManager.update(); + delayedUpdateObjectManager.update(netObjMan); constexpr float SECONDS_TO_SEND_CAMERA_DATA = 0.5f; timeToSendCameraData.update_time_since(); if(timeToSendCameraData.get_time_since() > SECONDS_TO_SEND_CAMERA_DATA) {