IDs are no longer generated on server, fixes error caused by spamming undo and redo
This commit is contained in:
parent
a9af3a9b17
commit
57392cdfdd
12 changed files with 92 additions and 108 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ template <typename T, typename IDType> class CollabList {
|
|||
|
||||
struct ObjectInfo {
|
||||
bool syncIgnore;
|
||||
IDType id;
|
||||
T obj;
|
||||
uint64_t pos;
|
||||
};
|
||||
|
|
@ -45,7 +44,7 @@ template <typename T, typename IDType> 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 <typename T, typename IDType> 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<ObjectInfo>());
|
||||
newObj->syncIgnore = true;
|
||||
newObj->id = getNewIDFunc();
|
||||
newObj->obj = item;
|
||||
if(createNewIDs)
|
||||
newObj->obj->id = getNewIDFunc();
|
||||
newObj->pos = std::min<uint64_t>(static_cast<uint64_t>(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 <typename T, typename IDType> class CollabList {
|
|||
return newObj;
|
||||
}
|
||||
|
||||
std::vector<ObjectInfoPtr> client_insert_ordered_vector_items(uint64_t pos, const std::vector<T>& items) {
|
||||
std::vector<ObjectInfoPtr> client_insert_ordered_vector_items(uint64_t pos, const std::vector<T>& items, bool createNewIDs = true) {
|
||||
std::vector<ObjectInfoPtr> itemsToPushIn;
|
||||
for(auto& item : items) {
|
||||
auto& newObj = itemsToPushIn.emplace_back(std::make_shared<ObjectInfo>());
|
||||
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 <typename T, typename IDType> 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<uint64_t>(static_cast<uint64_t>(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 <typename T, typename IDType> class CollabList {
|
|||
if(updateCallback)
|
||||
updateCallback();
|
||||
|
||||
return objInfoToInsert->id;
|
||||
return objInfoToInsert->obj->id;
|
||||
}
|
||||
|
||||
void client_erase(const ObjectInfoPtr& objToErase) {
|
||||
|
|
@ -126,7 +128,7 @@ template <typename T, typename IDType> 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 <typename T, typename IDType> 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 <typename T, typename IDType> 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<ObjectInfoPtr>& objOrderedVector) {
|
||||
void client_insert_ordered_vector(const std::vector<ObjectInfoPtr>& 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<uint64_t>(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<uint64_t>(clientSideList.size(), objOrderedVector[startPoint]->pos);
|
||||
clientSideList.insert(clientSideList.begin() + insertPosition, objOrderedVector.begin() + startPoint, objOrderedVector.begin() + i);
|
||||
|
|
@ -203,7 +207,7 @@ template <typename T, typename IDType> class CollabList {
|
|||
std::vector<bool> 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 <typename T, typename IDType> class CollabList {
|
|||
for(uint64_t i = 1; i < static_cast<uint64_t>(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 <typename T, typename IDType> 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 <typename T, typename IDType> class CollabList {
|
|||
}
|
||||
auto newObj(std::make_shared<ObjectInfo>());
|
||||
newObj->syncIgnore = false;
|
||||
newObj->id = id;
|
||||
newObj->obj = item;
|
||||
newObj->pos = std::min<uint64_t>(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 <typename T, typename IDType> 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 <typename T, typename IDType> class CollabList {
|
|||
|
||||
void server_erase_set(const std::unordered_set<ServerClientID>& 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 <typename T, typename IDType> class CollabList {
|
|||
sync();
|
||||
}
|
||||
|
||||
void init_emplace_back(IDType id, const T& item) {
|
||||
void init_emplace_back(const T& item) {
|
||||
auto newObj(std::make_shared<ObjectInfo>());
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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::vector<Colla
|
|||
server.netServer->send_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::vector<Co
|
|||
|
||||
void DrawComponent::client_send_place(DrawingProgram& drawP) {
|
||||
//if(collabListInfo.lock()) If this fails, then there's a real issue
|
||||
drawP.world.con.client_send_items_to_server(RELIABLE_COMMAND_CHANNEL, SERVER_PLACE_SINGLE_COMPONENT, collabListInfo.lock()->pos, 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<std::pair<ServerClientID, CoordSpaceHelper>>& 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<ServerClientID>& ids) {
|
||||
|
|
|
|||
|
|
@ -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<CollabListType::ObjectInfoPtr>& comps);
|
||||
static void server_send_erase(MainServer& server, ServerClientID id);
|
||||
static void server_send_erase_set(MainServer& server, const std::unordered_set<ServerClientID>& 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<std::pair<ServerClientID, CoordSpaceHelper>>& transforms);
|
||||
|
||||
std::weak_ptr<CollabListType::ObjectInfo> collabListInfo;
|
||||
std::weak_ptr<DrawingProgramCacheBVHNode> parentBvhNode;
|
||||
ServerClientID id;
|
||||
|
||||
#ifndef IS_SERVER
|
||||
std::chrono::time_point<std::chrono::steady_clock> lastUpdateTime;
|
||||
|
|
|
|||
|
|
@ -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<CollabListType::ObjectInfoPtr> erasedComponents) {
|
||||
std::unordered_set<ServerClientID> 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<CollabLi
|
|||
|
||||
std::unordered_set<ServerClientID> 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_set<CollabLi
|
|||
if(comp->obj->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_set<CollabLi
|
|||
if(comp->obj->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<CollabLi
|
|||
|
||||
std::unordered_set<ServerClientID> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ void DrawingProgramSelection::commit_transform_selection() {
|
|||
std::vector<std::pair<CollabListType::ObjectInfoPtr, CoordSpaceHelper>> transformsTo;
|
||||
std::vector<std::pair<ServerClientID, CoordSpaceHelper>> 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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
#include "ClientData.hpp"
|
||||
#include "MainServer.hpp"
|
||||
#include "CommandList.hpp"
|
||||
|
||||
|
||||
ServerClientID ClientData::get_next_id() {
|
||||
id.second++;
|
||||
return id;
|
||||
}
|
||||
|
|
@ -24,7 +24,5 @@ class ClientData {
|
|||
template <typename Archive> void serialize(Archive& a) {
|
||||
a(camCoords, windowSize, cursorPos, cursorColor, displayName);
|
||||
}
|
||||
|
||||
ServerClientID get_next_id();
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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<uint64_t>(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<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
auto& cli = clients[client->customID];
|
||||
|
||||
std::vector<CollabListType::ObjectInfoPtr> objOrderedVector;
|
||||
SendOrderedComponentVectorOp a{&objOrderedVector};
|
||||
message(a);
|
||||
|
||||
std::vector<std::pair<ServerClientID, std::shared_ptr<DrawComponent>>> objOrderedComponentPairs;
|
||||
for(auto& o : objOrderedVector) {
|
||||
o->id = cli.get_next_id();
|
||||
objOrderedComponentPairs.emplace_back(o->id, o->obj);
|
||||
}
|
||||
std::vector<std::shared_ptr<DrawComponent>> 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<uint64_t>(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<uint64_t>(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<NetServer::ClientData> 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<NetServer::ClientData> client, cereal::PortableBinaryInputArchive& message) {
|
||||
|
|
@ -205,12 +199,13 @@ MainServer::MainServer(World& initWorld, const std::string& serverLocalID):
|
|||
if(it != data.idToComponentMap.end()) {
|
||||
std::shared_ptr<DrawComponent>& 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<NetServer::ClientData> 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 {
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ class DrawComponent;
|
|||
|
||||
class ServerData {
|
||||
public:
|
||||
std::vector<std::pair<ServerClientID, std::shared_ptr<DrawComponent>>> components;
|
||||
std::vector<std::shared_ptr<DrawComponent>> components;
|
||||
std::unordered_map<ServerClientID, std::shared_ptr<DrawComponent>> idToComponentMap;
|
||||
std::unordered_map<ServerClientID, ResourceData> resources;
|
||||
std::unordered_map<std::string, Bookmark> bookmarks;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue