From 2e9ba0fb5a68abd8fa44d9996ea321a77876af14 Mon Sep 17 00:00:00 2001 From: Mateusz Piekos Date: Thu, 26 Jul 2012 17:46:45 +0200 Subject: Improved handling of operations IDs and transformations diff --git a/Swift/QtUI/Whiteboard/GView.cpp b/Swift/QtUI/Whiteboard/GView.cpp index 5f10329..163cab0 100644 --- a/Swift/QtUI/Whiteboard/GView.cpp +++ b/Swift/QtUI/Whiteboard/GView.cpp @@ -75,11 +75,11 @@ namespace Swift { item->stackBefore(temp); items_.insert(pos-1, item); } - std::cout << "items in:" << std::endl; + /*std::cout << "items in:" << std::endl; for (QList::const_iterator it = items_.begin(); it != items_.end(); ++it) { std::cout << (*it)->data(100).toString().toStdString() << std::endl; } - std::cout << std::endl; + std::cout << std::endl;*/ } void GView::setIDPrefix(QString prefix) { @@ -90,6 +90,8 @@ namespace Swift { scene()->clear(); items_.clear(); itemsMap_.clear(); + lastItem = 0; + selectionRect = 0; } QGraphicsItem* GView::getItem(QString id) { @@ -249,8 +251,9 @@ namespace Swift { { QGraphicsItem* item = scene()->items(rect).first(); QString id = item->data(100).toString(); + int pos = items_.indexOf(item)+1; + itemDeleted(id, pos); deleteItem(id); - itemDeleted(id, items_.indexOf(item)+1); } } else if (mode == Circle) { @@ -354,11 +357,11 @@ namespace Swift { lastItem->setZValue(zValue++); items_.append(lastItem); itemsMap_.insert(lastItem->data(100).toString(), lastItem); - std::cout << "items out:" << std::endl; + /*std::cout << "items out:" << std::endl; for (QList::const_iterator it = items_.begin(); it != items_.end(); ++it) { std::cout << (*it)->data(100).toString().toStdString() << std::endl; } - std::cout << std::endl; + std::cout << std::endl;*/ lastItemChanged(lastItem, items_.size(), New); } else if (selectionRect){ diff --git a/Swift/QtUI/Whiteboard/GView.h b/Swift/QtUI/Whiteboard/GView.h index 443b7ab..dc6a3c2 100644 --- a/Swift/QtUI/Whiteboard/GView.h +++ b/Swift/QtUI/Whiteboard/GView.h @@ -37,6 +37,7 @@ namespace Swift { void clear(); QGraphicsItem* getItem(QString id); void deleteItem(QString id); + QString getNewID(); public slots: void moveUpSelectedItem(); @@ -45,7 +46,6 @@ namespace Swift { private slots: void handleTextItemModified(QGraphicsTextItem*); private: - QString getNewID(); void changePenAndBrush(QGraphicsItem* item, QPen pen, QBrush brush); void setActualPenAndBrushFromItem(QGraphicsItem* item); diff --git a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp index a2440ba..960254c 100644 --- a/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp +++ b/Swift/QtUI/Whiteboard/QtWhiteboardWindow.cpp @@ -141,21 +141,21 @@ namespace Swift { if (insertOp) { WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::New); insertOp->getElement()->accept(visitor); - lastOpID = insertOp->getID(); } WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast(operation); if (updateOp) { WhiteboardElementDrawingVisitor visitor(graphicsView, operation->getPos(), GView::Update); updateOp->getElement()->accept(visitor); - lastOpID = updateOp->getID(); } WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast(operation); if (deleteOp) { - graphicsView->deleteItem(P2QSTRING(deleteOp->getID())); - lastOpID = deleteOp->getID(); + if (deleteOp->getPos() != -1) { + graphicsView->deleteItem(P2QSTRING(deleteOp->getElementID())); + } } + lastOpID = operation->getID(); } void QtWhiteboardWindow::changeLineWidth(int i) @@ -343,29 +343,32 @@ namespace Swift { if (type == GView::New) { WhiteboardInsertOperation::ref insertOp = boost::make_shared(); - insertOp->setID(el->getID()); +// insertOp->setID(el->getID()); + insertOp->setID(Q2PSTRING(graphicsView->getNewID())); insertOp->setPos(pos); insertOp->setElement(el); insertOp->setParentID(lastOpID); - lastOpID = el->getID(); + lastOpID = insertOp->getID(); whiteboardSession_->sendOperation(insertOp); } else { WhiteboardUpdateOperation::ref updateOp = boost::make_shared(); - updateOp->setID(el->getID()); +// updateOp->setID(el->getID()); + updateOp->setID(Q2PSTRING(graphicsView->getNewID())); updateOp->setPos(pos); updateOp->setElement(el); updateOp->setParentID(lastOpID); - lastOpID = el->getID(); + lastOpID = updateOp->getID(); whiteboardSession_->sendOperation(updateOp); } } void QtWhiteboardWindow::handleItemDeleted(QString id, int pos) { WhiteboardDeleteOperation::ref deleteOp = boost::make_shared(); - deleteOp->setID(Q2PSTRING(id)); + deleteOp->setID(Q2PSTRING(graphicsView->getNewID())); + deleteOp->setElementID(Q2PSTRING(id)); deleteOp->setPos(pos); deleteOp->setParentID(lastOpID); - lastOpID = Q2PSTRING(id); + lastOpID = deleteOp->getID(); whiteboardSession_->sendOperation(deleteOp); } diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp index 0381abb..12bed17 100644 --- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp +++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp @@ -36,6 +36,7 @@ namespace Swift { operation = updateOp; } else if (type == "delete") { WhiteboardDeleteOperation::ref deleteOp = boost::make_shared(); + deleteOp->setElementID(attributes.getAttributeValue("elementid").get_value_or("")); operation = deleteOp; } if (operation) { diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp index 7248c0e..f0ab7c1 100644 --- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp +++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp @@ -174,6 +174,7 @@ namespace Swift { operationNode->setAttribute("pos", boost::lexical_cast(deleteOp->getPos())); operationNode->setAttribute("id", deleteOp->getID()); operationNode->setAttribute("parentid", deleteOp->getParentID()); + operationNode->setAttribute("elementid", deleteOp->getElementID()); } catch (boost::bad_lexical_cast&) { } } diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp index 568bed8..39eb435 100644 --- a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp +++ b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp @@ -7,6 +7,10 @@ #include #include +#include +#include +#include + namespace Swift { IncomingWhiteboardSession::IncomingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { } @@ -28,16 +32,51 @@ namespace Swift { // std::cout << "incoming pos: " << operation->getPos() << std::endl; // WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(operation); WhiteboardOperation::ref op = server.handleClientOperationReceived(operation); +/* server.print(); + std::cout << "in1: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID() << std::endl; +// std::cout << "sin2: " << op->getID() << " " << op->getPos() << " " << op->getParentID() << std::endl; //std::cout << "in1: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID() << std::endl; - //std::cout << "in2: " << op->getID() << " " << op->getPos() << " " << op->getParentID() << std::endl; + + WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(op); + if (insertOp) { + std::cout << "iin2: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast(op); + if (updateOp) { + std::cout << "uin2: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast(op); + if (deleteOp) { + std::cout << "din2: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + }*/ + onOperationReceived(op); + WhiteboardPayload::ref payload = boost::make_shared(); payload->setOperation(op); sendPayload(payload); } void IncomingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) { - //std::cout << "out: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID()<< std::endl; +// std::cout << "out: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID()<< std::endl; + +/* WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(operation); + if (insertOp) { + std::cout << "iout: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast(operation); + if (updateOp) { + std::cout << "uout: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast(operation); + if (deleteOp) { + std::cout << "dout: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + } +*/ server.handleLocalOperationReceived(operation); WhiteboardPayload::ref payload = boost::make_shared(); payload->setOperation(operation); diff --git a/Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h b/Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h index 139ef0c..d739e57 100644 --- a/Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h +++ b/Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h @@ -17,5 +17,16 @@ namespace Swift { public: ~WhiteboardDeleteOperation() { } + + std::string getElementID() const { + return elementID_; + } + + void setElementID(const std::string& elementID) { + elementID_ = elementID; + } + + private: + std::string elementID_; }; } diff --git a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp index 0c7bc42..ae07822 100644 --- a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp +++ b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp @@ -10,6 +10,10 @@ #include #include +#include +#include +#include + namespace Swift { OutgoingWhiteboardSession::OutgoingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { } @@ -36,11 +40,40 @@ namespace Swift { void OutgoingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) { // std::cout << "incoming pos: " << operation->getPos() << std::endl; +// client.print(); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(operation); if (pairResult.client) { +/* WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(operation); + if (insertOp) { + std::cout << "iin1: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast(operation); + if (updateOp) { + std::cout << "uin1: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast(operation); + if (deleteOp) { + std::cout << "din1: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + } + + insertOp = boost::dynamic_pointer_cast(pairResult.client); + if (insertOp) { + std::cout << "iin1: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + updateOp = boost::dynamic_pointer_cast(pairResult.client); + if (updateOp) { + std::cout << "uin1: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + deleteOp = boost::dynamic_pointer_cast(pairResult.client); + if (deleteOp) { + std::cout << "din1: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + }*/ onOperationReceived(pairResult.client); - //std::cout << "in1: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID() << std::endl; - //std::cout << "in2: " << pairResult.client->getID() << " " << pairResult.client->getPos() << " " << pairResult.client->getParentID() << std::endl; } if (pairResult.server) { diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp index 9fef701..7d767d3 100644 --- a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp +++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp @@ -515,7 +515,7 @@ public: //Client receives confirmation about processing "b", there aren't any operations //waiting so it should return nothing. serverUpdateOp = createUpdateOperation("b", "a", 0); - pairResult = client.handleServerOperationReceived(serverOp); + pairResult = client.handleServerOperationReceived(serverUpdateOp); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp index c61f9d1..563be54 100644 --- a/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp +++ b/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include using namespace Swift; @@ -18,6 +20,8 @@ using namespace Swift; class WhiteboardServerTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(WhiteboardServerTest); CPPUNIT_TEST(testSimpleOp); + CPPUNIT_TEST(testSimpleOp1); + CPPUNIT_TEST(testSimpleOp2); CPPUNIT_TEST(testFewSimpleOps); CPPUNIT_TEST_SUITE_END(); public: @@ -44,6 +48,49 @@ public: CPPUNIT_ASSERT_EQUAL(clientElement, boost::dynamic_pointer_cast(op->getElement())); } + void testSimpleOp1() { + WhiteboardServer server; + WhiteboardInsertOperation::ref firstOp = boost::make_shared(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardDeleteOperation::ref serverOp = boost::make_shared(); + serverOp->setID("b"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + WhiteboardUpdateOperation::ref clientOp = boost::make_shared(); + WhiteboardEllipseElement::ref clientElement = boost::make_shared(0,0,0,0); + clientOp->setID("a"); + clientOp->setParentID("0"); + clientOp->setPos(1); + clientOp->setElement(clientElement); + WhiteboardDeleteOperation::ref op = boost::dynamic_pointer_cast(server.handleClientOperationReceived(clientOp)); + CPPUNIT_ASSERT_EQUAL(std::string("b"), op->getParentID()); + CPPUNIT_ASSERT_EQUAL(std::string("a"), op->getID()); + CPPUNIT_ASSERT_EQUAL(-1, op->getPos()); + } + + void testSimpleOp2() { + WhiteboardServer server; + WhiteboardInsertOperation::ref firstOp = boost::make_shared(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardUpdateOperation::ref serverOp = boost::make_shared(); + serverOp->setID("b"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + WhiteboardDeleteOperation::ref clientOp = boost::make_shared(); + clientOp->setID("a"); + clientOp->setParentID("0"); + clientOp->setPos(1); + WhiteboardDeleteOperation::ref op = boost::dynamic_pointer_cast(server.handleClientOperationReceived(clientOp)); + CPPUNIT_ASSERT_EQUAL(std::string("b"), op->getParentID()); + CPPUNIT_ASSERT_EQUAL(std::string("a"), op->getID()); + CPPUNIT_ASSERT_EQUAL(1, op->getPos()); + } + + void testFewSimpleOps() { WhiteboardServer server; WhiteboardInsertOperation::ref firstOp = boost::make_shared(); diff --git a/Swiften/Whiteboard/WhiteboardClient.cpp b/Swiften/Whiteboard/WhiteboardClient.cpp index ce47fe5..4dacc90 100644 --- a/Swiften/Whiteboard/WhiteboardClient.cpp +++ b/Swiften/Whiteboard/WhiteboardClient.cpp @@ -11,7 +11,7 @@ namespace Swift { WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) { localOperations_.push_back(operation); -// if (bridge_.size() > 0) { + WhiteboardOperation::ref op; WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(operation); if (insertOp) { @@ -30,7 +30,7 @@ namespace Swift { op->setParentID(bridge_.back()->getID()); } bridge_.push_back(op); -// } + if (lastSentOperationID_.empty()) { WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast(operation); @@ -59,8 +59,6 @@ namespace Swift { WhiteboardClient::Result WhiteboardClient::handleServerOperationReceived(WhiteboardOperation::ref operation) { serverOperations_.push_back(operation); -// WhiteboardOperation::ref clientOp; -// WhiteboardOperation::ref serverOp; Result result; // if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) { //Situation where client and server are in sync @@ -73,15 +71,6 @@ namespace Swift { if (bridge_.size() > 0 && lastSentOperationID_ == bridge_.front()->getID()) { bridge_.erase(bridge_.begin()); } - /*std::list::iterator it; - for (it = bridge_.begin(); it != bridge_.end(); ++it) { - if ((*it)->getParentID() == lastSentOperationID_) { - lastSentOperationID_ = (*it)->getID(); - serverOp = *it; - serverOp->setOrigin(WhiteboardOperation::Other); - break; - } - }*/ if (bridge_.size() > 0 && (bridge_.front())->getParentID() == lastSentOperationID_) { lastSentOperationID_ = (bridge_.front())->getID(); @@ -91,56 +80,26 @@ namespace Swift { lastSentOperationID_.clear(); } } else { - if (bridge_.size() > 0 && bridge_.front()->getParentID() == operation->getParentID()) { - std::list::iterator it = bridge_.begin(); - std::pair opPair; - WhiteboardOperation::ref temp; - opPair = WhiteboardTransformer::transform(*it, operation); - temp = opPair.first; + std::list::iterator it = bridge_.begin(); + std::pair opPair; + WhiteboardOperation::ref temp; + opPair = WhiteboardTransformer::transform(*it, operation); + temp = opPair.first; + *it = opPair.second; + std::string previousID = (*it)->getID(); + ++it; + for (; it != bridge_.end(); ++it) { + opPair = WhiteboardTransformer::transform(*it, temp); + temp = opPair.first; *it = opPair.second; - std::string previousID = (*it)->getID(); - ++it; - for (; it != bridge_.end(); ++it) { - opPair = WhiteboardTransformer::transform(*it, temp); - temp = opPair.first; - *it = opPair.second; - (*it)->setParentID(previousID); - previousID = (*it)->getID(); - } - - temp->setParentID(localOperations_.back()->getID()); - localOperations_.push_back(temp); - result.client = temp; - } else { -//doesn't get executed -/* std::list::reverse_iterator it; - std::pair opPair; - WhiteboardInsertOperation::ref temp = boost::dynamic_pointer_cast(operation); - bool end = false; - for (it = localOperations_.rbegin(); it != localOperations_.rend(); ++it) { - while ((*it)->getParentID() == temp->getParentID()) { - opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast(*it), temp); - if (bridge_.size() > 0) { - opPair.second->setParentID(bridge_.back()->getID()); - } - temp = opPair.first; - bridge_.push_back(opPair.second); - if (it == localOperations_.rbegin()) { - localOperations_.push_back(temp); - result.client = temp; - end = true; - break; - } else { - --it; - } - } - if (end) { - break; - }*/ - - + (*it)->setParentID(previousID); + previousID = (*it)->getID(); } + + temp->setParentID(localOperations_.back()->getID()); + localOperations_.push_back(temp); + result.client = temp; } return result; diff --git a/Swiften/Whiteboard/WhiteboardServer.cpp b/Swiften/Whiteboard/WhiteboardServer.cpp index 53a131f..384372b 100644 --- a/Swiften/Whiteboard/WhiteboardServer.cpp +++ b/Swiften/Whiteboard/WhiteboardServer.cpp @@ -36,4 +36,13 @@ namespace Swift { } return WhiteboardOperation::ref(); } + + void WhiteboardServer::print() { + std::list::iterator it; + std::cout << "Server:" << std::endl; + for(it = operations_.begin(); it != operations_.end(); ++it) { + std::cout << (*it)->getID() << " " << (*it)->getPos() << std::endl; + } + } + } diff --git a/Swiften/Whiteboard/WhiteboardServer.h b/Swiften/Whiteboard/WhiteboardServer.h index 6ee4ac6..7c06d75 100644 --- a/Swiften/Whiteboard/WhiteboardServer.h +++ b/Swiften/Whiteboard/WhiteboardServer.h @@ -15,6 +15,7 @@ namespace Swift { public: void handleLocalOperationReceived(WhiteboardOperation::ref operation); WhiteboardOperation::ref handleClientOperationReceived(WhiteboardOperation::ref operation); + void print(); private: std::list operations_; diff --git a/Swiften/Whiteboard/WhiteboardTransformer.cpp b/Swiften/Whiteboard/WhiteboardTransformer.cpp index 8ee206b..c9dbbbd 100644 --- a/Swiften/Whiteboard/WhiteboardTransformer.cpp +++ b/Swiften/Whiteboard/WhiteboardTransformer.cpp @@ -94,10 +94,19 @@ namespace Swift { result.first->setParentID(clientOp->getID()); result.second = boost::make_shared(*clientOp); result.second->setParentID(serverOp->getID()); + if (clientOp->getPos() == -1) { + result.second->setPos(-1); + } + if (serverOp->getPos() == -1) { + result.first->setPos(-1); + } if (clientOp->getPos() < serverOp->getPos()) { result.first->setPos(result.first->getPos()-1); } else if (clientOp->getPos() > serverOp->getPos()) { result.second->setPos(result.second->getPos()-1); + } else { + result.first->setPos(-1); + result.second->setPos(-1); } //TODO: situation with deletion of the same item return result; @@ -111,7 +120,7 @@ namespace Swift { result.second->setParentID(serverOp->getID()); if (clientOp->getPos() <= serverOp->getPos()) { result.first->setPos(result.first->getPos()+1); - } else { + } else if (serverOp->getPos() != -1) { result.second->setPos(result.second->getPos()-1); } return result; @@ -125,19 +134,26 @@ namespace Swift { result.second->setParentID(serverOp->getID()); if (serverOp->getPos() <= clientOp->getPos()) { result.second->setPos(result.second->getPos()+1); - } else { + } else if (clientOp->getPos() != -1) { result.first->setPos(result.first->getPos()-1); } return result; } std::pair WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { - std::pair result; + std::pair result; result.first = boost::make_shared(*serverOp); result.first->setParentID(clientOp->getID()); result.second = boost::make_shared(*clientOp); result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() > serverOp->getPos()) { + if (clientOp->getPos() == serverOp->getPos()) { + WhiteboardDeleteOperation::ref deleteOp = boost::make_shared(); + result.second = deleteOp; + result.second->setPos(-1); + result.second->setID(clientOp->getID()); + result.second->setParentID(serverOp->getID()); + deleteOp->setElementID(serverOp->getElementID()); + } else if (clientOp->getPos() > serverOp->getPos()) { result.second->setPos(result.second->getPos()-1); } return result; @@ -145,12 +161,19 @@ namespace Swift { } std::pair WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { - std::pair result; + std::pair result; result.first = boost::make_shared(*serverOp); result.first->setParentID(clientOp->getID()); result.second = boost::make_shared(*clientOp); result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() < serverOp->getPos()) { + if (clientOp->getPos() == serverOp->getPos()) { + WhiteboardDeleteOperation::ref deleteOp = boost::make_shared(); + result.first = deleteOp; + result.first->setPos(-1); + result.first->setID(serverOp->getID()); + result.first->setParentID(clientOp->getID()); + deleteOp->setElementID(clientOp->getElementID()); + } else if (clientOp->getPos() < serverOp->getPos()) { result.first->setPos(result.first->getPos()-1); } return result; -- cgit v0.10.2-6-g49f6