diff options
author | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-07-26 15:46:45 (GMT) |
---|---|---|
committer | Mateusz Piekos <mateuszpiekos@gmail.com> | 2012-07-26 15:46:45 (GMT) |
commit | 2e9ba0fb5a68abd8fa44d9996ea321a77876af14 (patch) | |
tree | 23a1bdf024045ad619af906bf2438dd05fa3c8fe /Swiften | |
parent | 833e544490a0e3ff5eeebe44fae2b9a8f98d4a78 (diff) | |
download | swift-contrib-2e9ba0fb5a68abd8fa44d9996ea321a77876af14.zip swift-contrib-2e9ba0fb5a68abd8fa44d9996ea321a77876af14.tar.bz2 |
Improved handling of operations IDs and transformations
Diffstat (limited to 'Swiften')
-rw-r--r-- | Swiften/Parser/PayloadParsers/WhiteboardParser.cpp | 1 | ||||
-rw-r--r-- | Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp | 1 | ||||
-rw-r--r-- | Swiften/Whiteboard/IncomingWhiteboardSession.cpp | 43 | ||||
-rw-r--r-- | Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h | 11 | ||||
-rw-r--r-- | Swiften/Whiteboard/OutgoingWhiteboardSession.cpp | 37 | ||||
-rw-r--r-- | Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp | 2 | ||||
-rw-r--r-- | Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp | 47 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardClient.cpp | 79 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardServer.cpp | 9 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardServer.h | 1 | ||||
-rw-r--r-- | Swiften/Whiteboard/WhiteboardTransformer.cpp | 35 |
11 files changed, 195 insertions, 71 deletions
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<WhiteboardDeleteOperation>(); + 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<std::string>(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 <Swiften/Whiteboard/IncomingWhiteboardSession.h> #include <Swiften/Elements/WhiteboardPayload.h> +#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h> + 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<WhiteboardInsertOperation>(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<WhiteboardInsertOperation>(op); + if (insertOp) { + std::cout << "iin2: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(op); + if (updateOp) { + std::cout << "uin2: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(op); + if (deleteOp) { + std::cout << "din2: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + }*/ + onOperationReceived(op); + WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); 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<WhiteboardInsertOperation>(operation); + if (insertOp) { + std::cout << "iout: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); + if (updateOp) { + std::cout << "uout: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); + if (deleteOp) { + std::cout << "dout: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + } +*/ server.handleLocalOperationReceived(operation); WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); 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 <boost/bind.hpp> #include <Swiften/Elements/WhiteboardPayload.h> +#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h> + 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<WhiteboardInsertOperation>(operation); + if (insertOp) { + std::cout << "iin1: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); + if (updateOp) { + std::cout << "uin1: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); + if (deleteOp) { + std::cout << "din1: " << deleteOp->getID() << " " << deleteOp->getPos() << " " << deleteOp->getParentID() << std::endl; + } + + insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client); + if (insertOp) { + std::cout << "iin1: " << insertOp->getID() << " " << insertOp->getPos() << " " << insertOp->getParentID() << std::endl; + } + + updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(pairResult.client); + if (updateOp) { + std::cout << "uin1: " << updateOp->getID() << " " << updateOp->getPos() << " " << updateOp->getParentID() << std::endl; + } + + deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(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 <boost/smart_ptr/make_shared.hpp> #include <Swiften/Whiteboard/WhiteboardServer.h> #include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardDeleteOperation.h> +#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h> #include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h> 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<WhiteboardEllipseElement>(op->getElement())); } + void testSimpleOp1() { + WhiteboardServer server; + WhiteboardInsertOperation::ref firstOp = boost::make_shared<WhiteboardInsertOperation>(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardDeleteOperation::ref serverOp = boost::make_shared<WhiteboardDeleteOperation>(); + serverOp->setID("b"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + WhiteboardUpdateOperation::ref clientOp = boost::make_shared<WhiteboardUpdateOperation>(); + WhiteboardEllipseElement::ref clientElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setID("a"); + clientOp->setParentID("0"); + clientOp->setPos(1); + clientOp->setElement(clientElement); + WhiteboardDeleteOperation::ref op = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(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<WhiteboardInsertOperation>(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardUpdateOperation::ref serverOp = boost::make_shared<WhiteboardUpdateOperation>(); + serverOp->setID("b"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + WhiteboardDeleteOperation::ref clientOp = boost::make_shared<WhiteboardDeleteOperation>(); + clientOp->setID("a"); + clientOp->setParentID("0"); + clientOp->setPos(1); + WhiteboardDeleteOperation::ref op = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(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<WhiteboardInsertOperation>(); 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<WhiteboardInsertOperation>(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<WhiteboardInsertOperation>(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<WhiteboardOperation::ref>::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<WhiteboardOperation::ref>::iterator it = bridge_.begin(); - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> opPair; - WhiteboardOperation::ref temp; - opPair = WhiteboardTransformer::transform(*it, operation); - temp = opPair.first; + std::list<WhiteboardOperation::ref>::iterator it = bridge_.begin(); + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> 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<WhiteboardOperation::ref>::reverse_iterator it; - std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair; - WhiteboardInsertOperation::ref temp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); - bool end = false; - for (it = localOperations_.rbegin(); it != localOperations_.rend(); ++it) { - while ((*it)->getParentID() == temp->getParentID()) { - opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*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<WhiteboardOperation::ref>::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<WhiteboardOperation::ref> 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<WhiteboardDeleteOperation>(*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<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { - std::pair<WhiteboardDeleteOperation::ref, WhiteboardUpdateOperation::ref> result; + std::pair<WhiteboardDeleteOperation::ref, WhiteboardOperation::ref> result; result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); result.first->setParentID(clientOp->getID()); result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() > serverOp->getPos()) { + if (clientOp->getPos() == serverOp->getPos()) { + WhiteboardDeleteOperation::ref deleteOp = boost::make_shared<WhiteboardDeleteOperation>(); + 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<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { - std::pair<WhiteboardUpdateOperation::ref, WhiteboardDeleteOperation::ref> result; + std::pair<WhiteboardOperation::ref, WhiteboardDeleteOperation::ref> result; result.first = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); result.first->setParentID(clientOp->getID()); result.second = boost::make_shared<WhiteboardDeleteOperation>(*clientOp); result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() < serverOp->getPos()) { + if (clientOp->getPos() == serverOp->getPos()) { + WhiteboardDeleteOperation::ref deleteOp = boost::make_shared<WhiteboardDeleteOperation>(); + 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; |