From 278792a0ff46984d9bc948a9b944bc7c2c3f377c Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Wed, 1 Oct 2025 08:59:44 +0300 Subject: [PATCH] Reliable channel used to finalize component updates --- src/DrawComponents/DrawComponent.cpp | 17 ++++++++++++----- src/DrawComponents/DrawComponent.hpp | 4 ++-- src/DrawingProgram/BrushTool.cpp | 4 ++-- src/DrawingProgram/EditTool.cpp | 6 +++--- src/DrawingProgram/EllipseDrawEditTool.cpp | 4 ++-- src/DrawingProgram/EllipseDrawTool.cpp | 4 ++-- src/DrawingProgram/RectDrawEditTool.cpp | 4 ++-- src/DrawingProgram/RectDrawTool.cpp | 4 ++-- src/DrawingProgram/TextBoxEditTool.cpp | 8 ++++---- src/DrawingProgram/TextBoxTool.cpp | 4 ++-- src/Server/MainServer.cpp | 5 +++-- 11 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/DrawComponents/DrawComponent.cpp b/src/DrawComponents/DrawComponent.cpp index 7f2f30f..d7fd42d 100644 --- a/src/DrawComponents/DrawComponent.cpp +++ b/src/DrawComponents/DrawComponent.cpp @@ -72,8 +72,11 @@ void DrawComponent::server_send_erase_set(MainServer& server, const std::unorder server.netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_ERASE_MANY_COMPONENTS, ids); } -void DrawComponent::server_send_update(MainServer& server) { - server.netServer->send_items_to_all_clients(UNRELIABLE_COMMAND_CHANNEL, CLIENT_UPDATE_COMPONENT, id, *this); +void DrawComponent::server_send_update(MainServer& server, bool final) { + if(final) + server.netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_UPDATE_COMPONENT, id, *this); + else + server.netServer->send_items_to_all_clients(UNRELIABLE_COMMAND_CHANNEL, CLIENT_UPDATE_COMPONENT, id, *this); } void DrawComponent::server_send_transform_many(MainServer& server, const std::vector>& transforms) { @@ -138,9 +141,13 @@ void DrawComponent::client_send_place(DrawingProgram& drawP) { drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_PLACE_SINGLE_COMPONENT, collabListInfo.lock()->pos, get_type(), id, this->coords, *this); } -void DrawComponent::client_send_update(DrawingProgram& drawP) { - if(collabListInfo.lock()) - drawP.world.con.client_send_items_to_server(UNRELIABLE_COMMAND_CHANNEL, SERVER_UPDATE_COMPONENT, id, *this); +void DrawComponent::client_send_update(DrawingProgram& drawP, bool final) { + if(collabListInfo.lock()) { + if(final) + drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_UPDATE_COMPONENT, final, id, *this); + else + drawP.world.con.client_send_items_to_server(UNRELIABLE_COMMAND_CHANNEL, SERVER_UPDATE_COMPONENT, final, id, *this); + } } void DrawComponent::client_send_transform_many(DrawingProgram& drawP, const std::vector>& transforms) { diff --git a/src/DrawComponents/DrawComponent.hpp b/src/DrawComponents/DrawComponent.hpp index 0e0d169..5741c6a 100644 --- a/src/DrawComponents/DrawComponent.hpp +++ b/src/DrawComponents/DrawComponent.hpp @@ -71,7 +71,7 @@ class DrawComponent { static void server_send_place_many(MainServer& server, std::vector& comps); static void server_send_erase(MainServer& server, ServerClientID id); static void server_send_erase_set(MainServer& server, const std::unordered_set& ids); - void server_send_update(MainServer& server); + void server_send_update(MainServer& server, bool final); static void server_send_transform_many(MainServer& server, const std::vector>& transforms); std::weak_ptr collabListInfo; @@ -88,7 +88,7 @@ class DrawComponent { void client_send_place(DrawingProgram& drawP); void client_send_erase(DrawingProgram& drawP); static void client_send_erase_set(DrawingProgram& drawP, const std::unordered_set& ids); - void client_send_update(DrawingProgram& drawP); + void client_send_update(DrawingProgram& drawP, bool final); static void client_send_transform_many(DrawingProgram& drawP, const std::vector>& transforms); std::optional> worldAABB; diff --git a/src/DrawingProgram/BrushTool.cpp b/src/DrawingProgram/BrushTool.cpp index 8dd7aeb..5199901 100644 --- a/src/DrawingProgram/BrushTool.cpp +++ b/src/DrawingProgram/BrushTool.cpp @@ -141,7 +141,7 @@ void BrushTool::tool_update() { if((!controls.drawingMinimumRelativeToSize && distToPrev >= 10.0) || (controls.drawingMinimumRelativeToSize && distToPrev >= drawP.controls.relativeWidth * DRAW_MINIMUM_LIMIT)) { controls.intermediateItem->d->points.back() = p; controls.addedTemporaryPoint = false; - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, false); if(controls.midwayInterpolation) { if(controls.intermediateItem->d->points.size() != 2) // Don't interpolate the first point @@ -175,7 +175,7 @@ bool BrushTool::prevent_undo_or_redo() { void BrushTool::commit_stroke() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { if(!controls.intermediateItem->d->points.empty()) { - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, true); controls.intermediateItem->commit_update(drawP); } } diff --git a/src/DrawingProgram/EditTool.cpp b/src/DrawingProgram/EditTool.cpp index 2f26170..ed29447 100644 --- a/src/DrawingProgram/EditTool.cpp +++ b/src/DrawingProgram/EditTool.cpp @@ -30,7 +30,7 @@ void EditTool::gui_toolbox() { bool editHappened = controls.compEditTool->edit_gui(a); if(editHappened) { a->commit_update(drawP); - a->client_send_update(drawP); + a->client_send_update(drawP, true); } } } @@ -50,7 +50,7 @@ void EditTool::switch_tool(DrawingProgramToolType newTool) { if(a && a->collabListInfo.lock()) { controls.compEditTool->commit_edit_updates(a, controls.prevData); a->commit_update(drawP); - a->client_send_update(drawP); + a->client_send_update(drawP, true); } controls.compToEdit.reset(); controls.pointHandles.clear(); @@ -162,7 +162,7 @@ void EditTool::tool_update() { newPos = cwise_vec_min((*controls.pointDragging->max - Vector2f{controls.pointDragging->minimumDistanceBetweenBoundsAndPoint, controls.pointDragging->minimumDistanceBetweenBoundsAndPoint}).eval(), newPos); *controls.pointDragging->p = newPos; a->commit_update(drawP); - a->client_send_update(drawP); + a->client_send_update(drawP, false); } isMovingPoint = true; } diff --git a/src/DrawingProgram/EllipseDrawEditTool.cpp b/src/DrawingProgram/EllipseDrawEditTool.cpp index 5290610..b6e01c1 100644 --- a/src/DrawingProgram/EllipseDrawEditTool.cpp +++ b/src/DrawingProgram/EllipseDrawEditTool.cpp @@ -62,13 +62,13 @@ void EllipseDrawEditTool::commit_edit_updates(const std::shared_ptrd = pData; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; }, [&, a, cData]() { a->d = cData; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; } diff --git a/src/DrawingProgram/EllipseDrawTool.cpp b/src/DrawingProgram/EllipseDrawTool.cpp index 2634635..289f8e7 100644 --- a/src/DrawingProgram/EllipseDrawTool.cpp +++ b/src/DrawingProgram/EllipseDrawTool.cpp @@ -71,7 +71,7 @@ void EllipseDrawTool::tool_update() { controls.intermediateItem->d.p1 = cwise_vec_min(controls.startAt, newPos); controls.intermediateItem->d.p2 = cwise_vec_max(controls.startAt, newPos); controls.intermediateItem->d.p2 = ensure_points_have_distance(controls.intermediateItem->d.p1, controls.intermediateItem->d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, false); controls.intermediateItem->commit_update(drawP); } else { @@ -89,7 +89,7 @@ bool EllipseDrawTool::prevent_undo_or_redo() { void EllipseDrawTool::commit() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, true); controls.intermediateItem->commit_update(drawP); } controls.intermediateItem = nullptr; diff --git a/src/DrawingProgram/RectDrawEditTool.cpp b/src/DrawingProgram/RectDrawEditTool.cpp index d8c87a9..be27c53 100644 --- a/src/DrawingProgram/RectDrawEditTool.cpp +++ b/src/DrawingProgram/RectDrawEditTool.cpp @@ -59,13 +59,13 @@ void RectDrawEditTool::commit_edit_updates(const std::shared_ptr& drawP.world.undo.push(UndoManager::UndoRedoPair{ [&, a, pData]() { a->d = pData; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; }, [&, a, cData]() { a->d = cData; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; } diff --git a/src/DrawingProgram/RectDrawTool.cpp b/src/DrawingProgram/RectDrawTool.cpp index d14d6c0..be043e9 100644 --- a/src/DrawingProgram/RectDrawTool.cpp +++ b/src/DrawingProgram/RectDrawTool.cpp @@ -67,7 +67,7 @@ void RectDrawTool::tool_update() { controls.intermediateItem->d.p1 = cwise_vec_min(controls.startAt, newPos); controls.intermediateItem->d.p2 = cwise_vec_max(controls.startAt, newPos); controls.intermediateItem->d.p2 = ensure_points_have_distance(controls.intermediateItem->d.p1, controls.intermediateItem->d.p2, MINIMUM_DISTANCE_BETWEEN_BOUNDS); - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, false); controls.intermediateItem->commit_update(drawP); } else { @@ -85,7 +85,7 @@ bool RectDrawTool::prevent_undo_or_redo() { void RectDrawTool::commit_rectangle() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, true); controls.intermediateItem->commit_update(drawP); } controls.intermediateItem = nullptr; diff --git a/src/DrawingProgram/TextBoxEditTool.cpp b/src/DrawingProgram/TextBoxEditTool.cpp index c72a24c..ece45ab 100644 --- a/src/DrawingProgram/TextBoxEditTool.cpp +++ b/src/DrawingProgram/TextBoxEditTool.cpp @@ -42,7 +42,7 @@ void TextBoxEditTool::commit_edit_updates(const std::shared_ptr& a->d = pData; a->set_textbox_string(pData.currentText); a->d.editing = false; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; }, @@ -50,7 +50,7 @@ void TextBoxEditTool::commit_edit_updates(const std::shared_ptr& a->d = cData; a->set_textbox_string(cData.currentText); a->d.editing = false; - a->client_send_update(drawP); + a->client_send_update(drawP, true); a->commit_update(drawP); return true; } @@ -66,7 +66,7 @@ void TextBoxEditTool::edit_start(EditTool& editTool, const std::shared_ptrd; a->d.editing = true; - a->client_send_update(drawP); + a->client_send_update(drawP, false); editTool.add_point_handle({&a->d.p1, nullptr, &a->d.p2}); editTool.add_point_handle({&a->d.p2, &a->d.p1, nullptr}); } @@ -202,6 +202,6 @@ void TextBoxEditTool::edit_text(std::function toRun, const std::shared_p } void TextBoxEditTool::update_textbox_network(const std::shared_ptr& textBox) { - textBox->client_send_update(drawP); + textBox->client_send_update(drawP, false); textBox->commit_update(drawP); } diff --git a/src/DrawingProgram/TextBoxTool.cpp b/src/DrawingProgram/TextBoxTool.cpp index 78e5247..6b113bd 100644 --- a/src/DrawingProgram/TextBoxTool.cpp +++ b/src/DrawingProgram/TextBoxTool.cpp @@ -71,7 +71,7 @@ void TextBoxTool::tool_update() { return; } else { - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, false); controls.intermediateItem->commit_update(drawP); } break; @@ -85,7 +85,7 @@ bool TextBoxTool::prevent_undo_or_redo() { void TextBoxTool::commit() { if(controls.intermediateItem && controls.intermediateItem->collabListInfo.lock()) { - controls.intermediateItem->client_send_update(drawP); + controls.intermediateItem->client_send_update(drawP, true); controls.intermediateItem->commit_update(drawP); } controls.intermediateItem = nullptr; diff --git a/src/Server/MainServer.cpp b/src/Server/MainServer.cpp index 6d5129f..7a78b5a 100644 --- a/src/Server/MainServer.cpp +++ b/src/Server/MainServer.cpp @@ -172,13 +172,14 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): DrawComponent::server_send_transform_many(*this, transformsToSend); }); netServer->add_recv_callback(SERVER_UPDATE_COMPONENT, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { + bool isFinalUpdate; ServerClientID idToUpdate; - message(idToUpdate); + message(isFinalUpdate, idToUpdate); auto it = data.idToComponentMap.find(idToUpdate); if(it != data.idToComponentMap.end()) { std::shared_ptr& comp = it->second; message(*comp); - comp->server_send_update(*this); + comp->server_send_update(*this, isFinalUpdate); } }); netServer->add_recv_callback(SERVER_RESOURCE_INIT, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) {