From 57392cdfddac82aac08df888c56762226518e7e2 Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Wed, 27 Aug 2025 11:38:36 +0300 Subject: [PATCH] IDs are no longer generated on server, fixes error caused by spamming undo and redo --- CMakeLists.txt | 1 - src/CollabList.hpp | 70 ++++++++++--------- src/DrawComponents/DrawBrushStroke.cpp | 2 +- src/DrawComponents/DrawComponent.cpp | 16 ++--- src/DrawComponents/DrawComponent.hpp | 5 +- src/DrawingProgram/DrawingProgram.cpp | 30 ++++---- .../DrawingProgramSelection.cpp | 6 +- src/ResourceManager.cpp | 2 +- src/Server/ClientData.cpp | 9 --- src/Server/ClientData.hpp | 2 - src/Server/MainServer.cpp | 55 +++++++-------- src/Server/ServerData.hpp | 2 +- 12 files changed, 92 insertions(+), 108 deletions(-) delete mode 100644 src/Server/ClientData.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index fc1a611..59dfe79 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,6 @@ set(sources "src/main.cpp" "src/ResourceDisplay/ImageResourceDisplay.cpp" "src/ResourceDisplay/FileResourceDisplay.cpp" "src/Server/MainServer.cpp" - "src/Server/ClientData.cpp" "src/CollabTextBox/CollabTextBox.cpp" "src/CollabTextBox/CollabTextBoxShaper.cpp" "src/DrawingProgram/DrawingProgramCache.cpp" diff --git a/src/CollabList.hpp b/src/CollabList.hpp index 2732092..63800fb 100644 --- a/src/CollabList.hpp +++ b/src/CollabList.hpp @@ -10,7 +10,6 @@ template class CollabList { struct ObjectInfo { bool syncIgnore; - IDType id; T obj; uint64_t pos; }; @@ -45,7 +44,7 @@ template class CollabList { if(clientEraseCallback) clientEraseCallback(clientSideList[i]); clientSideList[i]->obj->collabListInfo.reset(); - idToObjectMap.erase(clientSideList[i]->id); + idToObjectMap.erase(clientSideList[i]->obj->id); clientSideList.erase(clientSideList.begin() + i); i--; if(updateCallback) @@ -57,16 +56,17 @@ template class CollabList { complete_client_pos_refresh(false); } - ObjectInfoPtr client_insert(uint64_t pos, const T& item) { + ObjectInfoPtr client_insert(uint64_t pos, const T& item, bool createNewIDs = true) { auto newObj(std::make_shared()); newObj->syncIgnore = true; - newObj->id = getNewIDFunc(); newObj->obj = item; + if(createNewIDs) + newObj->obj->id = getNewIDFunc(); newObj->pos = std::min(static_cast(clientSideList.size()), pos); item->collabListInfo = newObj; clientSideList.insert(clientSideList.begin() + newObj->pos, newObj); - idToObjectMap.emplace(newObj->id, newObj); + idToObjectMap.emplace(newObj->obj->id, newObj); client_pos_refresh_after_insert(newObj->pos); @@ -78,15 +78,16 @@ template class CollabList { return newObj; } - std::vector client_insert_ordered_vector_items(uint64_t pos, const std::vector& items) { + std::vector client_insert_ordered_vector_items(uint64_t pos, const std::vector& items, bool createNewIDs = true) { std::vector itemsToPushIn; for(auto& item : items) { auto& newObj = itemsToPushIn.emplace_back(std::make_shared()); newObj->syncIgnore = true; - newObj->id = getNewIDFunc(); newObj->obj = item; + if(createNewIDs) + newObj->obj->id = getNewIDFunc(); item->collabListInfo = newObj; - idToObjectMap.emplace(newObj->id, newObj); + idToObjectMap.emplace(newObj->obj->id, newObj); } clientSideList.insert(clientSideList.begin() + pos, itemsToPushIn.begin(), itemsToPushIn.end()); @@ -101,14 +102,15 @@ template class CollabList { return itemsToPushIn; } - IDType client_insert(const ObjectInfoPtr& objInfoToInsert) { + IDType client_insert(const ObjectInfoPtr& objInfoToInsert, bool createNewIDs = true) { objInfoToInsert->syncIgnore = true; - objInfoToInsert->id = getNewIDFunc(); + if(createNewIDs) + objInfoToInsert->obj->id = getNewIDFunc(); objInfoToInsert->pos = std::min(static_cast(clientSideList.size()), objInfoToInsert->pos); objInfoToInsert->obj->collabListInfo = objInfoToInsert; clientSideList.insert(clientSideList.begin() + objInfoToInsert->pos, objInfoToInsert); - idToObjectMap.emplace(objInfoToInsert->id, objInfoToInsert); + idToObjectMap.emplace(objInfoToInsert->obj->id, objInfoToInsert); client_pos_refresh_after_insert(objInfoToInsert->pos); @@ -117,7 +119,7 @@ template class CollabList { if(updateCallback) updateCallback(); - return objInfoToInsert->id; + return objInfoToInsert->obj->id; } void client_erase(const ObjectInfoPtr& objToErase) { @@ -126,7 +128,7 @@ template class CollabList { if(obj->obj == objToErase->obj) { if(clientEraseCallback) clientEraseCallback(obj); - idToObjectMap.erase(objToErase->id); + idToObjectMap.erase(objToErase->obj->id); obj->syncIgnore = true; obj->obj->collabListInfo.reset(); erasedSomething = true; @@ -147,7 +149,7 @@ template class CollabList { if(objSet.contains(obj)) { if(clientEraseCallback) clientEraseCallback(obj); - idToObjectMap.erase(obj->id); + idToObjectMap.erase(obj->obj->id); obj->syncIgnore = true; obj->obj->collabListInfo.reset(); erasedSomething = true; @@ -165,22 +167,24 @@ template class CollabList { } // NOTE: Dont use this function unless you're certain every object in the vector isn't already in the client list - void client_insert_ordered_vector(const std::vector& objOrderedVector) { + void client_insert_ordered_vector(const std::vector& objOrderedVector, bool createNewIDs = true) { if(objOrderedVector.empty()) return; uint64_t startPoint = 0; objOrderedVector.front()->syncIgnore = true; - objOrderedVector.front()->id = getNewIDFunc(); + if(createNewIDs) + objOrderedVector.front()->obj->id = getNewIDFunc(); objOrderedVector.front()->obj->collabListInfo = objOrderedVector.front(); - idToObjectMap.emplace(objOrderedVector.front()->id, objOrderedVector.front()); + idToObjectMap.emplace(objOrderedVector.front()->obj->id, objOrderedVector.front()); for(uint64_t i = 1; i < static_cast(objOrderedVector.size()); i++) { auto& obj = objOrderedVector[i]; obj->syncIgnore = true; - obj->id = getNewIDFunc(); + if(createNewIDs) + obj->obj->id = getNewIDFunc(); obj->obj->collabListInfo = obj; - idToObjectMap.emplace(obj->id, obj); + idToObjectMap.emplace(obj->obj->id, obj); if(obj->pos - objOrderedVector[startPoint]->pos != (i - startPoint)) { uint64_t insertPosition = std::min(clientSideList.size(), objOrderedVector[startPoint]->pos); clientSideList.insert(clientSideList.begin() + insertPosition, objOrderedVector.begin() + startPoint, objOrderedVector.begin() + i); @@ -203,7 +207,7 @@ template class CollabList { std::vector didntExistPreviously(objOrderedVector.size(), true); uint64_t startPoint = 0; - auto foundInClient1 = idToObjectMap.emplace(objOrderedVector.front()->id, objOrderedVector.front()); + auto foundInClient1 = idToObjectMap.emplace(objOrderedVector.front()->obj->id, objOrderedVector.front()); if(!foundInClient1.second) { // object already existed objOrderedVector.front() = foundInClient1.first->second; didntExistPreviously[0] = false; @@ -214,7 +218,7 @@ template class CollabList { for(uint64_t i = 1; i < static_cast(objOrderedVector.size()); i++) { auto& obj = objOrderedVector[i]; - auto foundInClient = idToObjectMap.emplace(obj->id, obj); + auto foundInClient = idToObjectMap.emplace(obj->obj->id, obj); if(!foundInClient.second) { // object already existed obj = foundInClient.first->second; didntExistPreviously[i] = false; @@ -241,8 +245,8 @@ template class CollabList { return didntExistPreviously; } - bool server_insert(uint64_t pos, IDType id, const T& item) { - auto foundInClient = idToObjectMap.find(id); + bool server_insert(uint64_t pos, const T& item) { + auto foundInClient = idToObjectMap.find(item->id); if(foundInClient != idToObjectMap.end()) { ObjectInfoPtr& o = foundInClient->second; serverSideList.insert(serverSideList.begin() + pos, o); @@ -252,10 +256,9 @@ template class CollabList { } auto newObj(std::make_shared()); newObj->syncIgnore = false; - newObj->id = id; newObj->obj = item; newObj->pos = std::min(pos, clientSideList.size()); - idToObjectMap.emplace(newObj->id, newObj); + idToObjectMap.emplace(newObj->obj->id, newObj); item->collabListInfo = newObj; serverSideList.insert(serverSideList.begin() + pos, newObj); @@ -272,16 +275,16 @@ template class CollabList { } void server_erase(IDType id) { std::erase_if(serverSideList, [&](const auto& obj) { - if(obj->id == id) { + if(obj->obj->id == id) { obj->syncIgnore = false; return true; } return false; }); std::erase_if(clientSideList, [&](const auto& obj) { - if(obj->id == id) { + if(obj->obj->id == id) { obj->syncIgnore = false; - idToObjectMap.erase(obj->id); + idToObjectMap.erase(obj->obj->id); if(clientEraseCallback) clientEraseCallback(obj); obj->obj->collabListInfo.reset(); @@ -294,18 +297,18 @@ template class CollabList { void server_erase_set(const std::unordered_set& idsToErase) { std::erase_if(serverSideList, [&](const auto& obj) { - if(idsToErase.contains(obj->id)) { + if(idsToErase.contains(obj->obj->id)) { obj->syncIgnore = false; return true; } return false; }); std::erase_if(clientSideList, [&](const auto& obj) { - if(idsToErase.contains(obj->id)) { + if(idsToErase.contains(obj->obj->id)) { obj->syncIgnore = false; if(clientEraseCallback) clientEraseCallback(obj); - idToObjectMap.erase(obj->id); + idToObjectMap.erase(obj->obj->id); obj->obj->collabListInfo.reset(); return true; } @@ -314,13 +317,12 @@ template class CollabList { sync(); } - void init_emplace_back(IDType id, const T& item) { + void init_emplace_back(const T& item) { auto newObj(std::make_shared()); newObj->syncIgnore = false; - newObj->id = id; newObj->obj = item; item->collabListInfo = newObj; - idToObjectMap.emplace(newObj->id, newObj); + idToObjectMap.emplace(newObj->obj->id, newObj); serverSideList.emplace_back(newObj); clientSideList.emplace_back(newObj); diff --git a/src/DrawComponents/DrawBrushStroke.cpp b/src/DrawComponents/DrawBrushStroke.cpp index e2bbf67..76b6d66 100644 --- a/src/DrawComponents/DrawBrushStroke.cpp +++ b/src/DrawComponents/DrawBrushStroke.cpp @@ -81,7 +81,7 @@ void DrawBrushStroke::draw(SkCanvas* canvas, const DrawData& drawData) { canvas->save(); paint.setColor4f(SkColor4f{d->color.x(), d->color.y(), d->color.z(), d->color.w()}); canvas_do_calculated_transform(canvas); - if(drawSetupData.mipmapLevel == 0) + if(drawSetupData.mipmapLevel == 0 || drawData.dontUseDrawProgCache) // check dontUseDrawProgCache, to make sure that SVG screenshots dont use LOD canvas->drawPath(*brushPath, paint); else canvas->drawPath(*brushPathLOD[drawSetupData.mipmapLevel - 1], paint); diff --git a/src/DrawComponents/DrawComponent.cpp b/src/DrawComponents/DrawComponent.cpp index ce7e01a..3a15e85 100644 --- a/src/DrawComponents/DrawComponent.cpp +++ b/src/DrawComponents/DrawComponent.cpp @@ -16,14 +16,14 @@ void save(cereal::PortableBinaryOutputArchive& a, const CollabListType::ObjectInfo& o) { // Client will send ID, but server should ignore ID and generate its own - a(o.pos, o.obj->get_type(), o.id, o.obj->coords, *o.obj); + a(o.pos, o.obj->get_type(), o.obj->id, o.obj->coords, *o.obj); } void load(cereal::PortableBinaryInputArchive& a, CollabListType::ObjectInfo& o) { DrawComponentType t; - a(o.pos, t, o.id); + a(o.pos, t); o.obj = DrawComponent::allocate_comp_type(t); - a(o.obj->coords, *o.obj); + a(o.obj->id, o.obj->coords, *o.obj); } void SendOrderedComponentVectorOp::save(cereal::PortableBinaryOutputArchive& a) const { @@ -60,7 +60,7 @@ void DrawComponent::server_send_place_many(MainServer& server, std::vectorsend_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_PLACE_MANY_COMPONENTS, SendOrderedComponentVectorOp{&comps}); } -void DrawComponent::server_send_place(MainServer& server, ServerClientID id, uint64_t placement) { +void DrawComponent::server_send_place(MainServer& server, uint64_t placement) { server.netServer->send_items_to_all_clients(RELIABLE_COMMAND_CHANNEL, CLIENT_PLACE_SINGLE_COMPONENT, placement, get_type(), id, this->coords, *this); } @@ -72,7 +72,7 @@ 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, ServerClientID id) { +void DrawComponent::server_send_update(MainServer& server) { server.netServer->send_items_to_all_clients(UNRELIABLE_COMMAND_CHANNEL, CLIENT_UPDATE_COMPONENT, id, *this); } @@ -130,12 +130,12 @@ void DrawComponent::client_send_place_many(DrawingProgram& drawP, std::vectorpos, get_type(), this->coords, *this); + 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, collabListInfo.lock()->id, *this); + drawP.world.con.client_send_items_to_server(UNRELIABLE_COMMAND_CHANNEL, SERVER_UPDATE_COMPONENT, id, *this); } void DrawComponent::client_send_transform_many(DrawingProgram& drawP, const std::vector>& transforms) { @@ -144,7 +144,7 @@ void DrawComponent::client_send_transform_many(DrawingProgram& drawP, const std: void DrawComponent::client_send_erase(DrawingProgram& drawP) { if(collabListInfo.lock()) - drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_ERASE_SINGLE_COMPONENT, collabListInfo.lock()->id); + drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_ERASE_SINGLE_COMPONENT, id); } void DrawComponent::client_send_erase_set(DrawingProgram& drawP, const std::unordered_set& ids) { diff --git a/src/DrawComponents/DrawComponent.hpp b/src/DrawComponents/DrawComponent.hpp index 94efdf2..d93354c 100644 --- a/src/DrawComponents/DrawComponent.hpp +++ b/src/DrawComponents/DrawComponent.hpp @@ -63,15 +63,16 @@ class DrawComponent { void canvas_do_calculated_transform(SkCanvas* canvas); void calculate_draw_transform(const DrawData& drawData); - void server_send_place(MainServer& server, ServerClientID id, uint64_t placement); + void server_send_place(MainServer& server, uint64_t placement); 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, ServerClientID id); + void server_send_update(MainServer& server); static void server_send_transform_many(MainServer& server, const std::vector>& transforms); std::weak_ptr collabListInfo; std::weak_ptr parentBvhNode; + ServerClientID id; #ifndef IS_SERVER std::chrono::time_point lastUpdateTime; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index f90b612..7231e9d 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -114,10 +114,9 @@ void DrawingProgram::init_client_callbacks() { uint64_t insertPosition; DrawComponentType type; message(insertPosition, type); - ServerClientID newObjectID; auto newObj = DrawComponent::allocate_comp_type(type); - message(newObjectID, newObj->coords, *newObj); - bool didntExistPreviously = components.server_insert(insertPosition, newObjectID, newObj); + message(newObj->id, newObj->coords, *newObj); + bool didntExistPreviously = components.server_insert(insertPosition, newObj); if(didntExistPreviously) newObj->commit_update(*this); }); @@ -439,11 +438,10 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a) a(compCount); for(uint64_t i = 0; i < compCount; i++) { DrawComponentType t; - ServerClientID id; - a(t, id); + a(t); auto newComp = DrawComponent::allocate_comp_type(t); - a(newComp->coords, *newComp); - components.init_emplace_back(id, newComp); + a(newComp->id, newComp->coords, *newComp); + components.init_emplace_back(newComp); } parallel_loop_all_components([&](const auto& c){ c->obj->commit_update(*this, false); @@ -454,7 +452,7 @@ void DrawingProgram::initialize_draw_data(cereal::PortableBinaryInputArchive& a) void DrawingProgram::client_erase_set(std::unordered_set erasedComponents) { std::unordered_set idsToErase; for(auto& c : erasedComponents) - idsToErase.emplace(c->id); + idsToErase.emplace(c->obj->id); DrawComponent::client_send_erase_set(*this, idsToErase); components.client_erase_set(erasedComponents); add_undo_erase_components(erasedComponents); @@ -470,7 +468,7 @@ void DrawingProgram::add_undo_place_component(const CollabListType::ObjectInfoPt [&, objToUndo]() { if(objToUndo->obj->collabListInfo.lock()) return false; - components.client_insert(objToUndo); + components.client_insert(objToUndo, false); objToUndo->obj->client_send_place(*this); return true; } @@ -500,7 +498,7 @@ void DrawingProgram::add_undo_place_components(const std::unordered_set idsToErase; for(auto& c : objSetToUndo) - idsToErase.emplace(c->id); + idsToErase.emplace(c->obj->id); DrawComponent::client_send_erase_set(*this, idsToErase); components.client_erase_set(objSetToUndo); @@ -517,7 +515,7 @@ void DrawingProgram::add_undo_place_components(const std::unordered_setobj->collabListInfo.lock()) return false; - components.client_insert_ordered_vector(sortedObjects); + components.client_insert_ordered_vector(sortedObjects, false); DrawComponent::client_send_place_many(*this, sortedObjects); return true; @@ -537,7 +535,7 @@ void DrawingProgram::add_undo_erase_components(const std::unordered_setobj->collabListInfo.lock()) return false; - components.client_insert_ordered_vector(sortedObjects); + components.client_insert_ordered_vector(sortedObjects, false); DrawComponent::client_send_place_many(*this, sortedObjects); return true; @@ -549,7 +547,7 @@ void DrawingProgram::add_undo_erase_components(const std::unordered_set idsToErase; for(auto& c : objSetToUndo) - idsToErase.emplace(c->id); + idsToErase.emplace(c->obj->id); DrawComponent::client_send_erase_set(*this, idsToErase); components.client_erase_set(objSetToUndo); @@ -563,8 +561,8 @@ ClientPortionID DrawingProgram::get_max_id(ServerPortionID serverID) { ClientPortionID maxClientID = 0; auto& cList = components.client_list(); for(auto& comp : cList) { - if(comp->id.first == serverID) - maxClientID = std::max(maxClientID, comp->id.second); + if(comp->obj->id.first == serverID) + maxClientID = std::max(maxClientID, comp->obj->id.second); } return maxClientID; } @@ -583,7 +581,7 @@ void DrawingProgram::write_to_file(cereal::PortableBinaryOutputArchive& a) { auto& cList = components.client_list(); a((uint64_t)cList.size()); for(size_t i = 0; i < cList.size(); i++) { - a(cList[i]->obj->get_type(), cList[i]->id, cList[i]->obj->coords, *cList[i]->obj); + a(cList[i]->obj->get_type(), cList[i]->obj->id, cList[i]->obj->coords, *cList[i]->obj); } } diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index b8d8381..f8057ed 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -152,7 +152,7 @@ void DrawingProgramSelection::commit_transform_selection() { std::vector> transformsTo; std::vector> transformsToSend; for(auto& transformedObj : a) { - transformsToSend.emplace_back(transformedObj->id, transformedObj->obj->coords); + transformsToSend.emplace_back(transformedObj->obj->id, transformedObj->obj->coords); transformsTo.emplace_back(transformedObj, transformedObj->obj->coords); } DrawComponent::client_send_transform_many(drawP, transformsToSend); @@ -162,7 +162,7 @@ void DrawingProgramSelection::commit_transform_selection() { for(auto& [comp, coords] : transformsFrom) { auto lockObjInfo = comp->obj->collabListInfo.lock(); if(lockObjInfo) - transformsToSend.emplace_back(lockObjInfo->id, coords); + transformsToSend.emplace_back(lockObjInfo->obj->id, coords); else return false; } @@ -186,7 +186,7 @@ void DrawingProgramSelection::commit_transform_selection() { for(auto& [comp, coords] : transformsTo) { auto lockObjInfo = comp->obj->collabListInfo.lock(); if(lockObjInfo) - transformsToSend.emplace_back(lockObjInfo->id, coords); + transformsToSend.emplace_back(lockObjInfo->obj->id, coords); else return false; } diff --git a/src/ResourceManager.cpp b/src/ResourceManager.cpp index 67c5165..c0ce588 100644 --- a/src/ResourceManager.cpp +++ b/src/ResourceManager.cpp @@ -78,7 +78,7 @@ ServerClientID ResourceManager::add_resource(const ResourceData& resource) { } ServerClientID newID = world.get_new_id(); resources[newID] = resource; - world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_RESOURCE_INIT); + world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_RESOURCE_INIT, newID); world.con.client_send_items_to_server(RESOURCE_COMMAND_CHANNEL, SERVER_RESOURCE_DATA, resource); return newID; } diff --git a/src/Server/ClientData.cpp b/src/Server/ClientData.cpp deleted file mode 100644 index 68cad36..0000000 --- a/src/Server/ClientData.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include "ClientData.hpp" -#include "MainServer.hpp" -#include "CommandList.hpp" - - -ServerClientID ClientData::get_next_id() { - id.second++; - return id; -} diff --git a/src/Server/ClientData.hpp b/src/Server/ClientData.hpp index 8f69085..b2b867c 100644 --- a/src/Server/ClientData.hpp +++ b/src/Server/ClientData.hpp @@ -24,7 +24,5 @@ class ClientData { template void serialize(Archive& a) { a(camCoords, windowSize, cursorPos, cursorColor, displayName); } - - ServerClientID get_next_id(); }; diff --git a/src/Server/MainServer.cpp b/src/Server/MainServer.cpp index bfe5e82..64a2eff 100644 --- a/src/Server/MainServer.cpp +++ b/src/Server/MainServer.cpp @@ -28,7 +28,7 @@ void ServerData::save(cereal::PortableBinaryOutputArchive& a) const { a(canvasBackColor); a((uint64_t)components.size()); for(uint64_t i = 0; i < components.size(); i++) - a(components[i].second->get_type(), components[i].first, components[i].second->coords, *(components[i].second)); + a(components[i]->get_type(), components[i]->id, components[i]->coords, *components[i]); a(bookmarks); } @@ -38,12 +38,11 @@ void ServerData::load(cereal::PortableBinaryInputArchive& a) { a(compCount); for(uint64_t i = 0; i < compCount; i++) { DrawComponentType t; - ServerClientID id; - a(t, id); + a(t); auto newComp = DrawComponent::allocate_comp_type(t); - a(newComp->coords, *newComp); - components.emplace_back(id, newComp); - idToComponentMap.emplace(id, newComp); + a(newComp->id, newComp->coords, *newComp); + components.emplace_back(newComp); + idToComponentMap.emplace(newComp->id, newComp); } a(bookmarks); } @@ -55,8 +54,8 @@ ClientPortionID ServerData::get_max_id(ServerPortionID serverID) const { maxClientID = std::max(maxClientID, p.first.second); } for(auto& p : components) { - if(p.first.first == serverID) - maxClientID = std::max(maxClientID, p.first.second); + if(p->id.first == serverID) + maxClientID = std::max(maxClientID, p->id.second); } return maxClientID; } @@ -65,8 +64,9 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): world(initWorld) { for(auto& c : world.drawProg.components.client_list()) { - data.components.emplace_back(c->id, c->obj->copy()); - data.idToComponentMap.emplace(data.components.back().first, data.components.back().second); + data.components.emplace_back(c->obj->copy()); + data.components.back()->id = c->obj->id; + data.idToComponentMap.emplace(data.components.back()->id, data.components.back()); } data.bookmarks = world.bMan.bookmark_list(); data.resources = world.rMan.resource_list(); @@ -114,36 +114,31 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): DrawComponentType type; message(placement, type); auto newComp = DrawComponent::allocate_comp_type(type); - message(newComp->coords, *newComp); - ServerClientID id = clients[client->customID].get_next_id(); + message(newComp->id, newComp->coords, *newComp); placement = std::min(placement, data.components.size()); - data.components.insert(data.components.begin() + placement, {id, newComp}); - data.idToComponentMap.emplace(id, newComp); - newComp->server_send_place(*this, id, placement); + data.components.insert(data.components.begin() + placement, newComp); + data.idToComponentMap.emplace(newComp->id, newComp); + newComp->server_send_place(*this, placement); }); netServer->add_recv_callback(SERVER_PLACE_MANY_COMPONENTS, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { - auto& cli = clients[client->customID]; - std::vector objOrderedVector; SendOrderedComponentVectorOp a{&objOrderedVector}; message(a); - std::vector>> objOrderedComponentPairs; - for(auto& o : objOrderedVector) { - o->id = cli.get_next_id(); - objOrderedComponentPairs.emplace_back(o->id, o->obj); - } + std::vector> objOrderedComponentPairs; + for(auto& o : objOrderedVector) + objOrderedComponentPairs.emplace_back(o->obj); uint64_t startPoint = 0; if(objOrderedVector.empty()) return; - data.idToComponentMap.emplace(objOrderedVector.front()->id, objOrderedVector.front()->obj); + data.idToComponentMap.emplace(objOrderedVector.front()->obj->id, objOrderedVector.front()->obj); for(uint64_t i = 1; i < static_cast(objOrderedVector.size()); i++) { auto& obj = objOrderedVector[i]; - data.idToComponentMap.emplace(obj->id, obj->obj); + data.idToComponentMap.emplace(obj->obj->id, obj->obj); if(obj->pos - objOrderedVector[startPoint]->pos != (i - startPoint)) { uint64_t insertPosition = std::min(data.components.size(), objOrderedVector[startPoint]->pos); data.components.insert(data.components.begin() + insertPosition, objOrderedComponentPairs.begin() + startPoint, objOrderedComponentPairs.begin() + i); @@ -158,10 +153,9 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): for(uint64_t i = 0; i < data.components.size(); i++) { if(startPoint >= objOrderedVector.size()) break; - auto& [id, c] = data.components[i]; + auto& c = data.components[i]; auto& o = objOrderedVector[startPoint]; if(c == o->obj) { - o->id = id; o->pos = i; startPoint++; } @@ -175,7 +169,7 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): DrawComponent::server_send_erase(*this, compToRemove); data.idToComponentMap.erase(compToRemove); std::erase_if(data.components, [&](auto& p) { - return p.first == compToRemove; + return p->id == compToRemove; }); }); netServer->add_recv_callback(SERVER_ERASE_MANY_COMPONENTS, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { @@ -185,7 +179,7 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): for(auto& id : idsToRemove) data.idToComponentMap.erase(id); std::erase_if(data.components, [&](auto& p) { - return idsToRemove.contains(p.first); + return idsToRemove.contains(p->id); }); }); netServer->add_recv_callback(SERVER_TRANSFORM_MANY_COMPONENTS, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { @@ -205,12 +199,13 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID): if(it != data.idToComponentMap.end()) { std::shared_ptr& comp = it->second; message(*comp); - comp->server_send_update(*this, idToUpdate); + comp->server_send_update(*this); } }); netServer->add_recv_callback(SERVER_RESOURCE_INIT, [&](std::shared_ptr client, cereal::PortableBinaryInputArchive& message) { auto& c = clients[client->customID]; - ServerClientID newID = c.get_next_id(); + ServerClientID newID; + message(newID); if(c.pendingResourceData.empty()) c.pendingResourceID.emplace(newID); else { diff --git a/src/Server/ServerData.hpp b/src/Server/ServerData.hpp index 371307e..2bf3a2f 100644 --- a/src/Server/ServerData.hpp +++ b/src/Server/ServerData.hpp @@ -8,7 +8,7 @@ class DrawComponent; class ServerData { public: - std::vector>> components; + std::vector> components; std::unordered_map> idToComponentMap; std::unordered_map resources; std::unordered_map bookmarks;