diff options
author | Tobias Markmann <tm@ayena.de> | 2016-03-31 14:57:35 (GMT) |
---|---|---|
committer | Tobias Markmann <tm@ayena.de> | 2016-03-31 14:57:35 (GMT) |
commit | cfbdb43d2cadd40aa87338d41548e4bf89e146e6 (patch) | |
tree | 18d94153a302445196fc0c18586abf44a1ce4a38 /Swiften/Whiteboard | |
parent | 1d545a4a7fb877f021508094b88c1f17b30d8b4e (diff) | |
download | swift-cfbdb43d2cadd40aa87338d41548e4bf89e146e6.zip swift-cfbdb43d2cadd40aa87338d41548e4bf89e146e6.tar.bz2 |
Convert tabs to 4 spaces for all source files
Removed trailing spaces and whitespace on empty lines
in the process.
Changed CheckTabs.py tool to disallow hard tabs in source
files.
Test-Information:
Manually checked 30 random files that the conversion worked
as expected.
Change-Id: I874f99d617bd3d2bb55f02d58f22f58f9b094480
Diffstat (limited to 'Swiften/Whiteboard')
18 files changed, 1468 insertions, 1468 deletions
diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp index 4708bfa..206e10b 100644 --- a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp +++ b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp @@ -20,46 +20,46 @@ #include <Swiften/Elements/WhiteboardPayload.h> namespace Swift { - IncomingWhiteboardSession::IncomingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { - } + IncomingWhiteboardSession::IncomingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { + } - IncomingWhiteboardSession::~IncomingWhiteboardSession() { - } + IncomingWhiteboardSession::~IncomingWhiteboardSession() { + } - void IncomingWhiteboardSession::accept() { - boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionAccept); - boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); - request->send(); - onRequestAccepted(toJID_); - } + void IncomingWhiteboardSession::accept() { + boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionAccept); + boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); + request->send(); + onRequestAccepted(toJID_); + } - void IncomingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) { - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(operation); - if (pairResult.client) { - if (pairResult.client->getPos() != -1) { - onOperationReceived(pairResult.client); - } - lastOpID = pairResult.client->getID(); - } + void IncomingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) { + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(operation); + if (pairResult.client) { + if (pairResult.client->getPos() != -1) { + onOperationReceived(pairResult.client); + } + lastOpID = pairResult.client->getID(); + } - if (pairResult.server) { - WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); - payload->setOperation(pairResult.server); - sendPayload(payload); - } - } + if (pairResult.server) { + WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); + payload->setOperation(pairResult.server); + sendPayload(payload); + } + } - void IncomingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) { - operation->setID(idGenerator.generateID()); - operation->setParentID(lastOpID); - lastOpID = operation->getID(); + void IncomingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) { + operation->setID(idGenerator.generateID()); + operation->setParentID(lastOpID); + lastOpID = operation->getID(); - WhiteboardOperation::ref result = client.handleLocalOperationReceived(operation); + WhiteboardOperation::ref result = client.handleLocalOperationReceived(operation); - if (result) { - WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); - payload->setOperation(result); - sendPayload(payload); - } - } + if (result) { + WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); + payload->setOperation(result); + sendPayload(payload); + } + } } diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.h b/Swiften/Whiteboard/IncomingWhiteboardSession.h index c79e320..f6c1f49 100644 --- a/Swiften/Whiteboard/IncomingWhiteboardSession.h +++ b/Swiften/Whiteboard/IncomingWhiteboardSession.h @@ -19,20 +19,20 @@ #include <Swiften/Whiteboard/WhiteboardSession.h> namespace Swift { - class SWIFTEN_API IncomingWhiteboardSession : public WhiteboardSession { - public: - typedef boost::shared_ptr<IncomingWhiteboardSession> ref; + class SWIFTEN_API IncomingWhiteboardSession : public WhiteboardSession { + public: + typedef boost::shared_ptr<IncomingWhiteboardSession> ref; - public: - IncomingWhiteboardSession(const JID& jid, IQRouter* router); - ~IncomingWhiteboardSession(); + public: + IncomingWhiteboardSession(const JID& jid, IQRouter* router); + ~IncomingWhiteboardSession(); - void accept(); + void accept(); - private: - void handleIncomingOperation(WhiteboardOperation::ref operation); - void sendOperation(WhiteboardOperation::ref operation); + private: + void handleIncomingOperation(WhiteboardOperation::ref operation); + void sendOperation(WhiteboardOperation::ref operation); - WhiteboardClient client; - }; + WhiteboardClient client; + }; } diff --git a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp index 7d706d5..2bfc434 100644 --- a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp +++ b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp @@ -21,45 +21,45 @@ #include <Swiften/Elements/WhiteboardPayload.h> namespace Swift { - OutgoingWhiteboardSession::OutgoingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { - } + OutgoingWhiteboardSession::OutgoingWhiteboardSession(const JID& jid, IQRouter* router) : WhiteboardSession(jid, router) { + } - OutgoingWhiteboardSession::~OutgoingWhiteboardSession() { - } + OutgoingWhiteboardSession::~OutgoingWhiteboardSession() { + } - void OutgoingWhiteboardSession::startSession() { - boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionRequest); - boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); - request->onResponse.connect(boost::bind(&OutgoingWhiteboardSession::handleRequestResponse, this, _1, _2)); - request->send(); - } + void OutgoingWhiteboardSession::startSession() { + boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionRequest); + boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); + request->onResponse.connect(boost::bind(&OutgoingWhiteboardSession::handleRequestResponse, this, _1, _2)); + request->send(); + } - void OutgoingWhiteboardSession::handleRequestResponse(boost::shared_ptr<WhiteboardPayload> /*payload*/, ErrorPayload::ref error) { - if (error) { - onRequestRejected(toJID_); - } - } + void OutgoingWhiteboardSession::handleRequestResponse(boost::shared_ptr<WhiteboardPayload> /*payload*/, ErrorPayload::ref error) { + if (error) { + onRequestRejected(toJID_); + } + } - void OutgoingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) { - WhiteboardOperation::ref op = server.handleClientOperationReceived(operation); - if (op->getPos() != -1) { - onOperationReceived(op); - } - lastOpID = op->getID(); + void OutgoingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) { + WhiteboardOperation::ref op = server.handleClientOperationReceived(operation); + if (op->getPos() != -1) { + onOperationReceived(op); + } + lastOpID = op->getID(); - WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); - payload->setOperation(op); - sendPayload(payload); - } + WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); + payload->setOperation(op); + sendPayload(payload); + } - void OutgoingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) { - operation->setID(idGenerator.generateID()); - operation->setParentID(lastOpID); - lastOpID = operation->getID(); + void OutgoingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) { + operation->setID(idGenerator.generateID()); + operation->setParentID(lastOpID); + lastOpID = operation->getID(); - server.handleLocalOperationReceived(operation); - WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); - payload->setOperation(operation); - sendPayload(payload); - } + server.handleLocalOperationReceived(operation); + WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>(); + payload->setOperation(operation); + sendPayload(payload); + } } diff --git a/Swiften/Whiteboard/OutgoingWhiteboardSession.h b/Swiften/Whiteboard/OutgoingWhiteboardSession.h index c8098d3..dd8623a 100644 --- a/Swiften/Whiteboard/OutgoingWhiteboardSession.h +++ b/Swiften/Whiteboard/OutgoingWhiteboardSession.h @@ -20,20 +20,20 @@ #include <Swiften/Whiteboard/WhiteboardSession.h> namespace Swift { - class SWIFTEN_API OutgoingWhiteboardSession : public WhiteboardSession { - public: - typedef boost::shared_ptr<OutgoingWhiteboardSession> ref; - - public: - OutgoingWhiteboardSession(const JID& jid, IQRouter* router); - virtual ~OutgoingWhiteboardSession(); - void startSession(); - - private: - void handleRequestResponse(boost::shared_ptr<WhiteboardPayload> /*payload*/, ErrorPayload::ref error); - void handleIncomingOperation(WhiteboardOperation::ref operation); - void sendOperation(WhiteboardOperation::ref operation); - - WhiteboardServer server; - }; + class SWIFTEN_API OutgoingWhiteboardSession : public WhiteboardSession { + public: + typedef boost::shared_ptr<OutgoingWhiteboardSession> ref; + + public: + OutgoingWhiteboardSession(const JID& jid, IQRouter* router); + virtual ~OutgoingWhiteboardSession(); + void startSession(); + + private: + void handleRequestResponse(boost::shared_ptr<WhiteboardPayload> /*payload*/, ErrorPayload::ref error); + void handleIncomingOperation(WhiteboardOperation::ref operation); + void sendOperation(WhiteboardOperation::ref operation); + + WhiteboardServer server; + }; } diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp index 999ccb7..9534c60 100644 --- a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp +++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp @@ -25,659 +25,659 @@ using namespace Swift; class WhiteboardClientTest : public CppUnit::TestFixture { - CPPUNIT_TEST_SUITE(WhiteboardClientTest); - CPPUNIT_TEST(testSynchronize_simplestSync); - CPPUNIT_TEST(testSynchronize_withoutTranslation); - CPPUNIT_TEST(testSynchronize_nonInterrupted); - CPPUNIT_TEST(testSynchronize_clientInterruption); - CPPUNIT_TEST(testSynchronize_serverInterruption); - CPPUNIT_TEST(testSynchronize_nonInterruptedMixOperations); - CPPUNIT_TEST(testSynchronize_nonInterruptedMixOperations2); - CPPUNIT_TEST_SUITE_END(); + CPPUNIT_TEST_SUITE(WhiteboardClientTest); + CPPUNIT_TEST(testSynchronize_simplestSync); + CPPUNIT_TEST(testSynchronize_withoutTranslation); + CPPUNIT_TEST(testSynchronize_nonInterrupted); + CPPUNIT_TEST(testSynchronize_clientInterruption); + CPPUNIT_TEST(testSynchronize_serverInterruption); + CPPUNIT_TEST(testSynchronize_nonInterruptedMixOperations); + CPPUNIT_TEST(testSynchronize_nonInterruptedMixOperations2); + CPPUNIT_TEST_SUITE_END(); public: - /*! - * /\ - * \/ - * \ - */ - void testSynchronize_simplestSync() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - clientOp = createInsertOperation("a", "0", 1); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(aElement); - WhiteboardInsertOperation::ref result; - checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); - - //Client receives server operation parented off "0", which isn't last client operation - //so it have to be transformed against local operations and then transformed value can - //be returned to draw - serverOp = createInsertOperation("b", "0", 1); - WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(bElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "b", "a", 2, bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation from the server about processed "a" operation, it had to - //be transformed against "b" on the server side to receive operation parented off "b". - //There aren't any waiting operations to send to server, this operation should return - //nothing - serverOp = createInsertOperation("a", "b", 1); - pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives local operation, it doesn't have to be transformed against anything - //but operation returned to send to the server should be parented off last server - //operation, which is "b" - clientOp = createInsertOperation("c", "b", 3); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(cElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "c", "a", 3, cElement); - - //Client receives confirmation from the server about processed "a" operation, it - //should be the same operation as it was sent because server didn't have to - //transform it - clientOp = createInsertOperation("c", "a", 3); - clientOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(clientOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Results: - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - // - //Server operations: - //ID pos - //0 0 - //b 1 - //a 1 - //c 3 - // - //what gives 0abc on both sides - } - - /*! - * / - * / - * \ - */ - void testSynchronize_withoutTranslation() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp = createInsertOperation("c", "0", 1); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(cElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "c", "0", 1, cElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - clientOp = createInsertOperation("d", "c", 2); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); - - //Client receives confirmation about processing "c" operation, it should be the - //same as sent operation because it wasn't transformed, client could send now - //operation "d" - clientOp = createInsertOperation("c", "0", 1); - clientOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(clientOp); - checkOperation(pairResult.server, "d", "c", 2, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - //Client receives confirmation about processing "d", it should be the same as - //sent operation. There aren't any operations in queue to send. - clientOp = createInsertOperation("d", "c", 2); - clientOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(clientOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives new operation from server, it's parented off "d" which is at - //the end of local history so it doesn't have to be transformed, so operation - //to pass to window should be the same - serverOp = createInsertOperation("e", "d", 3); - WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(eElement); - pairResult = client.handleServerOperationReceived(serverOp); - WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - - //Client operations: - //ID pos - //0 0 - //c 1 - //d 2 - //e 3 - // - //Server operations: - //ID pos - //0 0 - //c 1 - //d 2 - //e 3 - } - - /*! - * /\ - * / \ - * \ / - * \/ - */ - void testSynchronize_nonInterrupted() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - clientOp = createInsertOperation("a", "0", 1); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(aElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - clientOp = createInsertOperation("b", "a", 2); - WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); - - //Client receives new operation from server, it should be transformed against - //"a" and "b" before adding to local operations history because it's parented off "0". - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("c", "0", 1); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "c", "b", 3, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives new operation from server, it should be transformed against - //results of previous transformations, returned operation should be parented off - //"c" existing in local history. - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("d", "c", 2); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "d", "c", 4, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "a", it should send next operation - //to server which is "b", but it should be version parented of transformed "a" - serverOp = createInsertOperation("a", "d", 1); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.server, "b", "a", 2, bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - - //Client receives confirmation about processing "b", there aren't any operations - //waiting so it should return nothing. - serverOp = createInsertOperation("b", "a", 2); - pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - //d 4 - // - //Server operations: - //ID pos - //0 0 - //c 1 - //d 2 - //a 1 - //b 2 - // - //what gives 0abcd on both sides. - } - - /*! - * /\ - * / \ - * \ / - * / / - * \/ - */ - void testSynchronize_clientInterruption() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - clientOp = createInsertOperation("a", "0", 1); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(aElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - clientOp = createInsertOperation("b", "a", 2); - WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); - - //Client receives new operation from server, it should be transformed against - //"a" and "b" before adding to local operations history because it's parented off "0". - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("c", "0", 1); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "c", "b", 3, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives new local operation, client is still waiting for ack so, it - //should return nothing - clientOp = createInsertOperation("e", "a", 4); - WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(eElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); - - //Client receives new server operation, to add it to local history it should be transformed - //against result of previous transformations and operation "e", returned operation should - //be parented off "e", which was last local operation - serverOp = createInsertOperation("d", "c", 2); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "d", "e", 5, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "a", it had to be transformed against - //"c" and "d" and it is now parented off "d", returned value should be next operation - //which have to be send to server("b" parented off server version of "a"). - serverOp = createInsertOperation("a", "d", 1); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.server, "b", "a", 2, bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - //Client receives confirmation about processing "b", it is the same operation as sent because - //it didn't have to be transformed, returned value should be next operation - //which have to be send to server("e" parented off server version of "b"). - serverOp = createInsertOperation("b", "a", 2); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.server, "e", "b", 4, eElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - //Client receives confirmation about processing "b", it is the same operation as sent because - //it didn't have to be transformed, there aren't any operations to send so this function returns - //nothing - serverOp = createInsertOperation("e", "b", 4); - pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Result: - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - //e 4 - //d 5 - // - //Server operations: - //0 0 - //c 1 - //d 2 - //a 1 - //b 2 - //e 4 - //what gives 0abced on both sides - } - - /*! - * /\ - * / / - * \ \ - * \/ - */ - void testSynchronize_serverInterruption() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - clientOp = createInsertOperation("a", "0", 1); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(aElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - clientOp = createInsertOperation("b", "a", 2); - WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); - - //Client receives new operation from server, it should be transformed against - //"a" and "b" before adding to local operations history because it's parented off "0". - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("c", "0", 1); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "c", "b", 3, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "a", it had to be transformed against - //"c" and it is now parented off "c", returned value should be next operation - //which have to be send to server("b" parented off server version of "a"). - serverOp = createInsertOperation("a", "c", 1); - serverOp->setElement(aElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.server, "b", "a", 2, bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - //Client receives new server operation, to add it to local history it should be transformed - //against result of previous transformation(but only with transformation of "b"), returned - //operation should be parented off "c", which was last local operation - serverOp = createInsertOperation("d", "a", 3); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "d", "c", 4, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "b", it had to be transformed against - //"d" because both operations was parented off server version of "a". - //there aren't any operations to send so this function returns nothing. - serverOp = createInsertOperation("b", "d", 2); - serverOp->setElement(bElement); - pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - //d 4 - // - //Server operations: - //ID pos - //0 0 - //c 1 - //a 1 - //d 3 - //b 2 - // - //what gives 0abcd on both sides - - } - - /*! - * /\ - * / \ - * \ / - * \/ - */ - void testSynchronize_nonInterruptedMixOperations() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - clientOp = createInsertOperation("a", "0", 1); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setElement(aElement); - checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - WhiteboardUpdateOperation::ref clientUpdateOp = createUpdateOperation("b", "a", 0); - WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientUpdateOp->setElement(bElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientUpdateOp)); - - //Client receives new operation from server, it should be transformed against - //"a" and "b" before adding to local operations history because it's parented off "0". - //Because client is waiting for ack of "a", there is no operation to send to server - WhiteboardUpdateOperation::ref serverUpdateOp = createUpdateOperation("c", "0", 0); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverUpdateOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(serverUpdateOp); - checkOperation(pairResult.client, "c", "b", 0, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives new operation from server, it should be transformed against - //results of previous transformations, returned operation should be parented off - //"c" existing in local history. - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("d", "c", 1); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "d", "c", 2, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "a", it should send next operation - //to server which is "b", but it should be version parented of transformed "a" - serverOp = createInsertOperation("a", "d", 1); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.server, "b", "a", 0, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - - //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(serverUpdateOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - //d 4 - // - //Server operations: - //ID pos - //0 0 - //c 1 - //d 2 - //a 1 - //b 2 - // - //what gives 0abcd on both sides. - } - - /*! - * /\ - * / \ - * \ / - * \/ - */ - void testSynchronize_nonInterruptedMixOperations2() { - WhiteboardClient client; - WhiteboardInsertOperation::ref serverOp; - serverOp = createInsertOperation("0", "", 0); - WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - serverOp = createInsertOperation("1", "0", 1); - pairResult = client.handleServerOperationReceived(serverOp); - CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - //Client receives first local operation, because it's parented off "0" which exists - //in server history and client doesn't wait for any operation ack from server, - //so this operation could be send - WhiteboardInsertOperation::ref clientOp; - WhiteboardUpdateOperation::ref clientUpdateOp; - WhiteboardDeleteOperation::ref clientDeleteOp; - clientUpdateOp = createUpdateOperation("a", "1", 0); - WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientUpdateOp->setElement(aElement); - checkOperation(client.handleLocalOperationReceived(clientUpdateOp), "a", "1", 0, aElement); - - //Client receives second local operation, client didn't receive ack about previous - //operation from the server so it can't be send. - clientDeleteOp = createDeleteOperation("b", "a", 1); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientDeleteOp)); - - //Client receives new operation from server, it should be transformed against - //"a" and "b" before adding to local operations history because it's parented off "0". - //Because client is waiting for ack of "a", there is no operation to send to server - serverOp = createInsertOperation("c", "1", 2); - WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverOp->setElement(cElement); - pairResult = client.handleServerOperationReceived(serverOp); - checkOperation(pairResult.client, "c", "b", 1, cElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives new operation from server, it should be transformed against - //results of previous transformations, returned operation should be parented off - //"c" existing in local history. - //Because client is waiting for ack of "a", there is no operation to send to server - WhiteboardUpdateOperation::ref serverUpdateOp = createUpdateOperation("d", "c", 0); - WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - serverUpdateOp->setElement(dElement); - pairResult = client.handleServerOperationReceived(serverUpdateOp); - checkOperation(pairResult.client, "d", "c", 0, dElement); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client receives confirmation about processing "a", it should send next operation - //to server which is "b", but it should be version parented of transformed "a" - serverUpdateOp = createUpdateOperation("a", "d", 0); - pairResult = client.handleServerOperationReceived(serverUpdateOp); - checkOperation(pairResult.server, "b", "a", 1); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - - - //Client receives confirmation about processing "b", there aren't any operations - //waiting so it should return nothing. - WhiteboardDeleteOperation::ref serverDeleteOp = createDeleteOperation("b", "a", 0); - pairResult = client.handleServerOperationReceived(serverDeleteOp); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); - CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); - - //Client operations: - //ID pos - //0 0 - //a 1 - //b 2 - //c 3 - //d 4 - // - //Server operations: - //ID pos - //0 0 - //c 1 - //d 2 - //a 1 - //b 2 - // - //what gives 0abcd on both sides. - } - - - WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent, int pos) { - WhiteboardInsertOperation::ref operation = boost::make_shared<WhiteboardInsertOperation>(); - operation->setParentID(parent); - operation->setID(id); - operation->setPos(pos); - return operation; - } - - WhiteboardUpdateOperation::ref createUpdateOperation(std::string id, std::string parent, int pos) { - WhiteboardUpdateOperation::ref operation = boost::make_shared<WhiteboardUpdateOperation>(); - operation->setParentID(parent); - operation->setID(id); - operation->setPos(pos); - return operation; - } - - WhiteboardDeleteOperation::ref createDeleteOperation(std::string id, std::string parent, int pos) { - WhiteboardDeleteOperation::ref operation = boost::make_shared<WhiteboardDeleteOperation>(); - operation->setParentID(parent); - operation->setID(id); - operation->setPos(pos); - return operation; - } - - void checkOperation(WhiteboardOperation::ref operation, std::string id, std::string parent, int pos = -1, WhiteboardElement::ref element = WhiteboardElement::ref()) { - CPPUNIT_ASSERT_EQUAL(id, operation->getID()); - CPPUNIT_ASSERT_EQUAL(parent, operation->getParentID()); - if (pos != -1) { - CPPUNIT_ASSERT_EQUAL(pos, operation->getPos()); - } - - if (element) { - WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); - if (insertOp) { - CPPUNIT_ASSERT_EQUAL(element, insertOp->getElement()); - } - - WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); - if (updateOp) { - CPPUNIT_ASSERT_EQUAL(element, updateOp->getElement()); - } - } - } + /*! + * /\ + * \/ + * \ + */ + void testSynchronize_simplestSync() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0", 1); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + WhiteboardInsertOperation::ref result; + checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + + //Client receives server operation parented off "0", which isn't last client operation + //so it have to be transformed against local operations and then transformed value can + //be returned to draw + serverOp = createInsertOperation("b", "0", 1); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(bElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "b", "a", 2, bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation from the server about processed "a" operation, it had to + //be transformed against "b" on the server side to receive operation parented off "b". + //There aren't any waiting operations to send to server, this operation should return + //nothing + serverOp = createInsertOperation("a", "b", 1); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives local operation, it doesn't have to be transformed against anything + //but operation returned to send to the server should be parented off last server + //operation, which is "b" + clientOp = createInsertOperation("c", "b", 3); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(cElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "c", "a", 3, cElement); + + //Client receives confirmation from the server about processed "a" operation, it + //should be the same operation as it was sent because server didn't have to + //transform it + clientOp = createInsertOperation("c", "a", 3); + clientOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(clientOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Results: + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + // + //Server operations: + //ID pos + //0 0 + //b 1 + //a 1 + //c 3 + // + //what gives 0abc on both sides + } + + /*! + * / + * / + * \ + */ + void testSynchronize_withoutTranslation() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp = createInsertOperation("c", "0", 1); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(cElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "c", "0", 1, cElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + clientOp = createInsertOperation("d", "c", 2); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + //Client receives confirmation about processing "c" operation, it should be the + //same as sent operation because it wasn't transformed, client could send now + //operation "d" + clientOp = createInsertOperation("c", "0", 1); + clientOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(clientOp); + checkOperation(pairResult.server, "d", "c", 2, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + //Client receives confirmation about processing "d", it should be the same as + //sent operation. There aren't any operations in queue to send. + clientOp = createInsertOperation("d", "c", 2); + clientOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(clientOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives new operation from server, it's parented off "d" which is at + //the end of local history so it doesn't have to be transformed, so operation + //to pass to window should be the same + serverOp = createInsertOperation("e", "d", 3); + WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(eElement); + pairResult = client.handleServerOperationReceived(serverOp); + WhiteboardInsertOperation::ref result = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + + //Client operations: + //ID pos + //0 0 + //c 1 + //d 2 + //e 3 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //e 3 + } + + /*! + * /\ + * / \ + * \ / + * \/ + */ + void testSynchronize_nonInterrupted() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0", 1); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + clientOp = createInsertOperation("b", "a", 2); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("c", "0", 1); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "c", "b", 3, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives new operation from server, it should be transformed against + //results of previous transformations, returned operation should be parented off + //"c" existing in local history. + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("d", "c", 2); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "d", "c", 4, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "a", it should send next operation + //to server which is "b", but it should be version parented of transformed "a" + serverOp = createInsertOperation("a", "d", 1); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.server, "b", "a", 2, bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + + //Client receives confirmation about processing "b", there aren't any operations + //waiting so it should return nothing. + serverOp = createInsertOperation("b", "a", 2); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + // + //what gives 0abcd on both sides. + } + + /*! + * /\ + * / \ + * \ / + * / / + * \/ + */ + void testSynchronize_clientInterruption() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0", 1); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + clientOp = createInsertOperation("b", "a", 2); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("c", "0", 1); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "c", "b", 3, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives new local operation, client is still waiting for ack so, it + //should return nothing + clientOp = createInsertOperation("e", "a", 4); + WhiteboardEllipseElement::ref eElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(eElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + //Client receives new server operation, to add it to local history it should be transformed + //against result of previous transformations and operation "e", returned operation should + //be parented off "e", which was last local operation + serverOp = createInsertOperation("d", "c", 2); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "d", "e", 5, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "a", it had to be transformed against + //"c" and "d" and it is now parented off "d", returned value should be next operation + //which have to be send to server("b" parented off server version of "a"). + serverOp = createInsertOperation("a", "d", 1); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.server, "b", "a", 2, bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + //Client receives confirmation about processing "b", it is the same operation as sent because + //it didn't have to be transformed, returned value should be next operation + //which have to be send to server("e" parented off server version of "b"). + serverOp = createInsertOperation("b", "a", 2); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.server, "e", "b", 4, eElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + //Client receives confirmation about processing "b", it is the same operation as sent because + //it didn't have to be transformed, there aren't any operations to send so this function returns + //nothing + serverOp = createInsertOperation("e", "b", 4); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Result: + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //e 4 + //d 5 + // + //Server operations: + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + //e 4 + //what gives 0abced on both sides + } + + /*! + * /\ + * / / + * \ \ + * \/ + */ + void testSynchronize_serverInterruption() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0", 1); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + clientOp = createInsertOperation("b", "a", 2); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientOp)); + + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("c", "0", 1); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "c", "b", 3, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "a", it had to be transformed against + //"c" and it is now parented off "c", returned value should be next operation + //which have to be send to server("b" parented off server version of "a"). + serverOp = createInsertOperation("a", "c", 1); + serverOp->setElement(aElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.server, "b", "a", 2, bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + //Client receives new server operation, to add it to local history it should be transformed + //against result of previous transformation(but only with transformation of "b"), returned + //operation should be parented off "c", which was last local operation + serverOp = createInsertOperation("d", "a", 3); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "d", "c", 4, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "b", it had to be transformed against + //"d" because both operations was parented off server version of "a". + //there aren't any operations to send so this function returns nothing. + serverOp = createInsertOperation("b", "d", 2); + serverOp->setElement(bElement); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //a 1 + //d 3 + //b 2 + // + //what gives 0abcd on both sides + + } + + /*! + * /\ + * / \ + * \ / + * \/ + */ + void testSynchronize_nonInterruptedMixOperations() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + clientOp = createInsertOperation("a", "0", 1); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setElement(aElement); + checkOperation(client.handleLocalOperationReceived(clientOp), "a", "0", 1, aElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + WhiteboardUpdateOperation::ref clientUpdateOp = createUpdateOperation("b", "a", 0); + WhiteboardEllipseElement::ref bElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientUpdateOp->setElement(bElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientUpdateOp)); + + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server + WhiteboardUpdateOperation::ref serverUpdateOp = createUpdateOperation("c", "0", 0); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverUpdateOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverUpdateOp); + checkOperation(pairResult.client, "c", "b", 0, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives new operation from server, it should be transformed against + //results of previous transformations, returned operation should be parented off + //"c" existing in local history. + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("d", "c", 1); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "d", "c", 2, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "a", it should send next operation + //to server which is "b", but it should be version parented of transformed "a" + serverOp = createInsertOperation("a", "d", 1); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.server, "b", "a", 0, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + + //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(serverUpdateOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + // + //what gives 0abcd on both sides. + } + + /*! + * /\ + * / \ + * \ / + * \/ + */ + void testSynchronize_nonInterruptedMixOperations2() { + WhiteboardClient client; + WhiteboardInsertOperation::ref serverOp; + serverOp = createInsertOperation("0", "", 0); + WhiteboardClient::Result pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + serverOp = createInsertOperation("1", "0", 1); + pairResult = client.handleServerOperationReceived(serverOp); + CPPUNIT_ASSERT_EQUAL(serverOp, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(pairResult.client)); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + //Client receives first local operation, because it's parented off "0" which exists + //in server history and client doesn't wait for any operation ack from server, + //so this operation could be send + WhiteboardInsertOperation::ref clientOp; + WhiteboardUpdateOperation::ref clientUpdateOp; + WhiteboardDeleteOperation::ref clientDeleteOp; + clientUpdateOp = createUpdateOperation("a", "1", 0); + WhiteboardEllipseElement::ref aElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientUpdateOp->setElement(aElement); + checkOperation(client.handleLocalOperationReceived(clientUpdateOp), "a", "1", 0, aElement); + + //Client receives second local operation, client didn't receive ack about previous + //operation from the server so it can't be send. + clientDeleteOp = createDeleteOperation("b", "a", 1); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), client.handleLocalOperationReceived(clientDeleteOp)); + + //Client receives new operation from server, it should be transformed against + //"a" and "b" before adding to local operations history because it's parented off "0". + //Because client is waiting for ack of "a", there is no operation to send to server + serverOp = createInsertOperation("c", "1", 2); + WhiteboardEllipseElement::ref cElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverOp->setElement(cElement); + pairResult = client.handleServerOperationReceived(serverOp); + checkOperation(pairResult.client, "c", "b", 1, cElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives new operation from server, it should be transformed against + //results of previous transformations, returned operation should be parented off + //"c" existing in local history. + //Because client is waiting for ack of "a", there is no operation to send to server + WhiteboardUpdateOperation::ref serverUpdateOp = createUpdateOperation("d", "c", 0); + WhiteboardEllipseElement::ref dElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + serverUpdateOp->setElement(dElement); + pairResult = client.handleServerOperationReceived(serverUpdateOp); + checkOperation(pairResult.client, "d", "c", 0, dElement); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client receives confirmation about processing "a", it should send next operation + //to server which is "b", but it should be version parented of transformed "a" + serverUpdateOp = createUpdateOperation("a", "d", 0); + pairResult = client.handleServerOperationReceived(serverUpdateOp); + checkOperation(pairResult.server, "b", "a", 1); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + + + //Client receives confirmation about processing "b", there aren't any operations + //waiting so it should return nothing. + WhiteboardDeleteOperation::ref serverDeleteOp = createDeleteOperation("b", "a", 0); + pairResult = client.handleServerOperationReceived(serverDeleteOp); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.client); + CPPUNIT_ASSERT_EQUAL(WhiteboardOperation::ref(), pairResult.server); + + //Client operations: + //ID pos + //0 0 + //a 1 + //b 2 + //c 3 + //d 4 + // + //Server operations: + //ID pos + //0 0 + //c 1 + //d 2 + //a 1 + //b 2 + // + //what gives 0abcd on both sides. + } + + + WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent, int pos) { + WhiteboardInsertOperation::ref operation = boost::make_shared<WhiteboardInsertOperation>(); + operation->setParentID(parent); + operation->setID(id); + operation->setPos(pos); + return operation; + } + + WhiteboardUpdateOperation::ref createUpdateOperation(std::string id, std::string parent, int pos) { + WhiteboardUpdateOperation::ref operation = boost::make_shared<WhiteboardUpdateOperation>(); + operation->setParentID(parent); + operation->setID(id); + operation->setPos(pos); + return operation; + } + + WhiteboardDeleteOperation::ref createDeleteOperation(std::string id, std::string parent, int pos) { + WhiteboardDeleteOperation::ref operation = boost::make_shared<WhiteboardDeleteOperation>(); + operation->setParentID(parent); + operation->setID(id); + operation->setPos(pos); + return operation; + } + + void checkOperation(WhiteboardOperation::ref operation, std::string id, std::string parent, int pos = -1, WhiteboardElement::ref element = WhiteboardElement::ref()) { + CPPUNIT_ASSERT_EQUAL(id, operation->getID()); + CPPUNIT_ASSERT_EQUAL(parent, operation->getParentID()); + if (pos != -1) { + CPPUNIT_ASSERT_EQUAL(pos, operation->getPos()); + } + + if (element) { + WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); + if (insertOp) { + CPPUNIT_ASSERT_EQUAL(element, insertOp->getElement()); + } + + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); + if (updateOp) { + CPPUNIT_ASSERT_EQUAL(element, updateOp->getElement()); + } + } + } }; CPPUNIT_TEST_SUITE_REGISTRATION(WhiteboardClientTest); diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp index 3434e5e..58b8c19 100644 --- a/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp +++ b/Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp @@ -25,111 +25,111 @@ 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(); + CPPUNIT_TEST_SUITE(WhiteboardServerTest); + CPPUNIT_TEST(testSimpleOp); + CPPUNIT_TEST(testSimpleOp1); + CPPUNIT_TEST(testSimpleOp2); + CPPUNIT_TEST(testFewSimpleOps); + CPPUNIT_TEST_SUITE_END(); public: - void testSimpleOp() { - WhiteboardServer server; - WhiteboardInsertOperation::ref firstOp = boost::make_shared<WhiteboardInsertOperation>(); - firstOp->setID("0"); - server.handleLocalOperationReceived(firstOp); - WhiteboardInsertOperation::ref serverOp = boost::make_shared<WhiteboardInsertOperation>(); - serverOp->setID("b"); - serverOp->setParentID("0"); - serverOp->setPos(1); - server.handleLocalOperationReceived(serverOp); - WhiteboardInsertOperation::ref clientOp = boost::make_shared<WhiteboardInsertOperation>(); - WhiteboardEllipseElement::ref clientElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setID("a"); - clientOp->setParentID("0"); - clientOp->setPos(1); - clientOp->setElement(clientElement); - WhiteboardInsertOperation::ref op = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(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()); - CPPUNIT_ASSERT_EQUAL(clientElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(op->getElement())); - } + void testSimpleOp() { + WhiteboardServer server; + WhiteboardInsertOperation::ref firstOp = boost::make_shared<WhiteboardInsertOperation>(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardInsertOperation::ref serverOp = boost::make_shared<WhiteboardInsertOperation>(); + serverOp->setID("b"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + WhiteboardInsertOperation::ref clientOp = boost::make_shared<WhiteboardInsertOperation>(); + WhiteboardEllipseElement::ref clientElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setID("a"); + clientOp->setParentID("0"); + clientOp->setPos(1); + clientOp->setElement(clientElement); + WhiteboardInsertOperation::ref op = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(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()); + 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 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 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>(); - firstOp->setID("0"); - server.handleLocalOperationReceived(firstOp); - WhiteboardInsertOperation::ref serverOp = boost::make_shared<WhiteboardInsertOperation>(); - serverOp->setID("a"); - serverOp->setParentID("0"); - serverOp->setPos(1); - server.handleLocalOperationReceived(serverOp); - serverOp = boost::make_shared<WhiteboardInsertOperation>(); - serverOp->setID("b"); - serverOp->setParentID("a"); - serverOp->setPos(2); - server.handleLocalOperationReceived(serverOp); - serverOp = boost::make_shared<WhiteboardInsertOperation>(); - serverOp->setID("c"); - serverOp->setParentID("b"); - serverOp->setPos(3); - server.handleLocalOperationReceived(serverOp); - WhiteboardInsertOperation::ref clientOp = boost::make_shared<WhiteboardInsertOperation>(); - WhiteboardEllipseElement::ref clientElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); - clientOp->setID("d"); - clientOp->setParentID("0"); - clientOp->setPos(1); - clientOp->setElement(clientElement); - WhiteboardInsertOperation::ref op = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(server.handleClientOperationReceived(clientOp)); - CPPUNIT_ASSERT_EQUAL(std::string("c"), op->getParentID()); - CPPUNIT_ASSERT_EQUAL(std::string("d"), op->getID()); - CPPUNIT_ASSERT_EQUAL(1, op->getPos()); - CPPUNIT_ASSERT_EQUAL(clientElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(op->getElement())); - } + void testFewSimpleOps() { + WhiteboardServer server; + WhiteboardInsertOperation::ref firstOp = boost::make_shared<WhiteboardInsertOperation>(); + firstOp->setID("0"); + server.handleLocalOperationReceived(firstOp); + WhiteboardInsertOperation::ref serverOp = boost::make_shared<WhiteboardInsertOperation>(); + serverOp->setID("a"); + serverOp->setParentID("0"); + serverOp->setPos(1); + server.handleLocalOperationReceived(serverOp); + serverOp = boost::make_shared<WhiteboardInsertOperation>(); + serverOp->setID("b"); + serverOp->setParentID("a"); + serverOp->setPos(2); + server.handleLocalOperationReceived(serverOp); + serverOp = boost::make_shared<WhiteboardInsertOperation>(); + serverOp->setID("c"); + serverOp->setParentID("b"); + serverOp->setPos(3); + server.handleLocalOperationReceived(serverOp); + WhiteboardInsertOperation::ref clientOp = boost::make_shared<WhiteboardInsertOperation>(); + WhiteboardEllipseElement::ref clientElement = boost::make_shared<WhiteboardEllipseElement>(0,0,0,0); + clientOp->setID("d"); + clientOp->setParentID("0"); + clientOp->setPos(1); + clientOp->setElement(clientElement); + WhiteboardInsertOperation::ref op = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(server.handleClientOperationReceived(clientOp)); + CPPUNIT_ASSERT_EQUAL(std::string("c"), op->getParentID()); + CPPUNIT_ASSERT_EQUAL(std::string("d"), op->getID()); + CPPUNIT_ASSERT_EQUAL(1, op->getPos()); + CPPUNIT_ASSERT_EQUAL(clientElement, boost::dynamic_pointer_cast<WhiteboardEllipseElement>(op->getElement())); + } }; CPPUNIT_TEST_SUITE_REGISTRATION(WhiteboardServerTest); diff --git a/Swiften/Whiteboard/WhiteboardClient.cpp b/Swiften/Whiteboard/WhiteboardClient.cpp index 00f8cbc..f272a8c 100644 --- a/Swiften/Whiteboard/WhiteboardClient.cpp +++ b/Swiften/Whiteboard/WhiteboardClient.cpp @@ -19,112 +19,112 @@ #include <Swiften/Whiteboard/WhiteboardTransformer.h> namespace Swift { - WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) { - localOperations_.push_back(operation); - - WhiteboardOperation::ref op; - WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); - if (insertOp) { - op = boost::make_shared<WhiteboardInsertOperation>(*insertOp); - } - WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); - if (updateOp) { - op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp); - } - WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); - if (deleteOp) { - op = boost::make_shared<WhiteboardDeleteOperation>(*deleteOp); - } - - if (!bridge_.empty()) { - op->setParentID(bridge_.back()->getID()); - } - bridge_.push_back(op); - - if (lastSentOperationID_.empty()) - { - WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); - if (insertOp) { - op = boost::make_shared<WhiteboardInsertOperation>(*insertOp); - } - WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); - if (updateOp) { - op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp); - } - WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); - if (deleteOp) { - op = boost::make_shared<WhiteboardDeleteOperation>(*deleteOp); - } - - - if (!serverOperations_.empty()) { - op->setParentID(serverOperations_.back()->getID()); - } - lastSentOperationID_ = operation->getID(); - return op; - } else { - return WhiteboardOperation::ref(); - } - } - - WhiteboardClient::Result WhiteboardClient::handleServerOperationReceived(WhiteboardOperation::ref operation) { - serverOperations_.push_back(operation); - Result result; -// if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) { - //Situation where client and server are in sync - if (localOperations_.size() == serverOperations_.size()-1) { - localOperations_.push_back(operation); -// clientOp = operation; - result.client = operation; - } else if (lastSentOperationID_ == operation->getID()) { - //Client received confirmation about own operation and it sends next operation to server - if (!bridge_.empty() && lastSentOperationID_ == bridge_.front()->getID()) { - bridge_.erase(bridge_.begin()); - } - - if (!bridge_.empty() && (bridge_.front())->getParentID() == lastSentOperationID_) { - lastSentOperationID_ = (bridge_.front())->getID(); - result.server = bridge_.front(); - } - if (!result.server) { - lastSentOperationID_.clear(); - } - } else { - 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; - (*it)->setParentID(previousID); - previousID = (*it)->getID(); - } - - temp->setParentID(localOperations_.back()->getID()); - localOperations_.push_back(temp); - result.client = temp; - } - - return result; - } - - void WhiteboardClient::print() { - std::list<WhiteboardOperation::ref>::iterator it; - std::cout << "Client" << std::endl; - for(it = localOperations_.begin(); it != localOperations_.end(); ++it) { - std::cout << (*it)->getID() << " " << (*it)->getPos() << std::endl; - } - - std::cout << "Server" << std::endl; - for(it = serverOperations_.begin(); it != serverOperations_.end(); ++it) { - std::cout << (*it)->getID() << " " << (*it)->getPos() << std::endl; - } - } + WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) { + localOperations_.push_back(operation); + + WhiteboardOperation::ref op; + WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); + if (insertOp) { + op = boost::make_shared<WhiteboardInsertOperation>(*insertOp); + } + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); + if (updateOp) { + op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp); + } + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); + if (deleteOp) { + op = boost::make_shared<WhiteboardDeleteOperation>(*deleteOp); + } + + if (!bridge_.empty()) { + op->setParentID(bridge_.back()->getID()); + } + bridge_.push_back(op); + + if (lastSentOperationID_.empty()) + { + WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation); + if (insertOp) { + op = boost::make_shared<WhiteboardInsertOperation>(*insertOp); + } + WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation); + if (updateOp) { + op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp); + } + WhiteboardDeleteOperation::ref deleteOp = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(operation); + if (deleteOp) { + op = boost::make_shared<WhiteboardDeleteOperation>(*deleteOp); + } + + + if (!serverOperations_.empty()) { + op->setParentID(serverOperations_.back()->getID()); + } + lastSentOperationID_ = operation->getID(); + return op; + } else { + return WhiteboardOperation::ref(); + } + } + + WhiteboardClient::Result WhiteboardClient::handleServerOperationReceived(WhiteboardOperation::ref operation) { + serverOperations_.push_back(operation); + Result result; +// if (localOperations_.empty()) {// || localOperations_.back()->getID() == operation->getParentID()) { + //Situation where client and server are in sync + if (localOperations_.size() == serverOperations_.size()-1) { + localOperations_.push_back(operation); +// clientOp = operation; + result.client = operation; + } else if (lastSentOperationID_ == operation->getID()) { + //Client received confirmation about own operation and it sends next operation to server + if (!bridge_.empty() && lastSentOperationID_ == bridge_.front()->getID()) { + bridge_.erase(bridge_.begin()); + } + + if (!bridge_.empty() && (bridge_.front())->getParentID() == lastSentOperationID_) { + lastSentOperationID_ = (bridge_.front())->getID(); + result.server = bridge_.front(); + } + if (!result.server) { + lastSentOperationID_.clear(); + } + } else { + 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; + (*it)->setParentID(previousID); + previousID = (*it)->getID(); + } + + temp->setParentID(localOperations_.back()->getID()); + localOperations_.push_back(temp); + result.client = temp; + } + + return result; + } + + void WhiteboardClient::print() { + std::list<WhiteboardOperation::ref>::iterator it; + std::cout << "Client" << std::endl; + for(it = localOperations_.begin(); it != localOperations_.end(); ++it) { + std::cout << (*it)->getID() << " " << (*it)->getPos() << std::endl; + } + + std::cout << "Server" << std::endl; + for(it = serverOperations_.begin(); it != serverOperations_.end(); ++it) { + std::cout << (*it)->getID() << " " << (*it)->getPos() << std::endl; + } + } } diff --git a/Swiften/Whiteboard/WhiteboardClient.h b/Swiften/Whiteboard/WhiteboardClient.h index 37a92d9..15870c6 100644 --- a/Swiften/Whiteboard/WhiteboardClient.h +++ b/Swiften/Whiteboard/WhiteboardClient.h @@ -19,26 +19,26 @@ #include <Swiften/Elements/Whiteboard/WhiteboardOperation.h> namespace Swift { - class SWIFTEN_API WhiteboardClient { - public: - struct Result { - WhiteboardOperation::ref client; - WhiteboardOperation::ref server; - }; - /*! - * @return Operation to send - */ - WhiteboardOperation::ref handleLocalOperationReceived(WhiteboardOperation::ref operation); - /*! - * @return pair.first-element to handle locally, pair.second-element to send to server - */ - Result handleServerOperationReceived(WhiteboardOperation::ref operation); - void print(); + class SWIFTEN_API WhiteboardClient { + public: + struct Result { + WhiteboardOperation::ref client; + WhiteboardOperation::ref server; + }; + /*! + * @return Operation to send + */ + WhiteboardOperation::ref handleLocalOperationReceived(WhiteboardOperation::ref operation); + /*! + * @return pair.first-element to handle locally, pair.second-element to send to server + */ + Result handleServerOperationReceived(WhiteboardOperation::ref operation); + void print(); - private: - std::list<WhiteboardOperation::ref> localOperations_; - std::list<WhiteboardOperation::ref> serverOperations_; - std::list<WhiteboardOperation::ref> bridge_; - std::string lastSentOperationID_; - }; + private: + std::list<WhiteboardOperation::ref> localOperations_; + std::list<WhiteboardOperation::ref> serverOperations_; + std::list<WhiteboardOperation::ref> bridge_; + std::string lastSentOperationID_; + }; } diff --git a/Swiften/Whiteboard/WhiteboardResponder.cpp b/Swiften/Whiteboard/WhiteboardResponder.cpp index 2a725ec..5e35782 100644 --- a/Swiften/Whiteboard/WhiteboardResponder.cpp +++ b/Swiften/Whiteboard/WhiteboardResponder.cpp @@ -20,25 +20,25 @@ #include <Swiften/Whiteboard/WhiteboardSessionManager.h> namespace Swift { - WhiteboardResponder::WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router) : SetResponder<WhiteboardPayload>(router), sessionManager_(sessionManager), router_(router) { - } + WhiteboardResponder::WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router) : SetResponder<WhiteboardPayload>(router), sessionManager_(sessionManager), router_(router) { + } - bool WhiteboardResponder::handleSetRequest(const JID& from, const JID& /*to*/, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload) { - if (payload->getType() == WhiteboardPayload::SessionRequest) { - if (sessionManager_->getSession(from)) { - sendError(from, id, ErrorPayload::Conflict, ErrorPayload::Cancel); - } else { - sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>()); - IncomingWhiteboardSession::ref session = boost::make_shared<IncomingWhiteboardSession>(from, router_); - sessionManager_->handleIncomingSession(session); - } - } else { - sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>()); - WhiteboardSession::ref session = sessionManager_->getSession(from); - if (session != NULL) { - session->handleIncomingAction(payload); - } - } - return true; - } + bool WhiteboardResponder::handleSetRequest(const JID& from, const JID& /*to*/, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload) { + if (payload->getType() == WhiteboardPayload::SessionRequest) { + if (sessionManager_->getSession(from)) { + sendError(from, id, ErrorPayload::Conflict, ErrorPayload::Cancel); + } else { + sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>()); + IncomingWhiteboardSession::ref session = boost::make_shared<IncomingWhiteboardSession>(from, router_); + sessionManager_->handleIncomingSession(session); + } + } else { + sendResponse(from, id, boost::shared_ptr<WhiteboardPayload>()); + WhiteboardSession::ref session = sessionManager_->getSession(from); + if (session != NULL) { + session->handleIncomingAction(payload); + } + } + return true; + } } diff --git a/Swiften/Whiteboard/WhiteboardResponder.h b/Swiften/Whiteboard/WhiteboardResponder.h index 8336485..0821a9f 100644 --- a/Swiften/Whiteboard/WhiteboardResponder.h +++ b/Swiften/Whiteboard/WhiteboardResponder.h @@ -17,16 +17,16 @@ #include <Swiften/Queries/SetResponder.h> namespace Swift { - class IQRouter; - class WhiteboardSessionManager; + class IQRouter; + class WhiteboardSessionManager; - class SWIFTEN_API WhiteboardResponder : public SetResponder<WhiteboardPayload> { - public: - WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router); - bool handleSetRequest(const JID& from, const JID& /*to*/, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload); + class SWIFTEN_API WhiteboardResponder : public SetResponder<WhiteboardPayload> { + public: + WhiteboardResponder(WhiteboardSessionManager* sessionManager, IQRouter* router); + bool handleSetRequest(const JID& from, const JID& /*to*/, const std::string& id, boost::shared_ptr<WhiteboardPayload> payload); - private: - WhiteboardSessionManager* sessionManager_; - IQRouter* router_; - }; + private: + WhiteboardSessionManager* sessionManager_; + IQRouter* router_; + }; } diff --git a/Swiften/Whiteboard/WhiteboardServer.cpp b/Swiften/Whiteboard/WhiteboardServer.cpp index 7b24ae4..4a2a315 100644 --- a/Swiften/Whiteboard/WhiteboardServer.cpp +++ b/Swiften/Whiteboard/WhiteboardServer.cpp @@ -17,41 +17,41 @@ #include <Swiften/Whiteboard/WhiteboardTransformer.h> namespace Swift { - void WhiteboardServer::handleLocalOperationReceived(WhiteboardOperation::ref operation) { - operations_.push_back(operation); - } - - WhiteboardOperation::ref WhiteboardServer::handleClientOperationReceived(WhiteboardOperation::ref newOperation) { - std::list<WhiteboardOperation::ref>::reverse_iterator it; - if (operations_.empty() || newOperation->getParentID() == operations_.back()->getID()) { - operations_.push_back(newOperation); - return newOperation; - } - for (it = operations_.rbegin(); it != operations_.rend(); ++it) { - WhiteboardOperation::ref operation = *it; - while (newOperation->getParentID() == operation->getParentID()) { - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> tResult = WhiteboardTransformer::transform(newOperation, operation); - - if (it == operations_.rbegin()) { - operations_.push_back(tResult.second); - return tResult.second; - } else { - newOperation = tResult.second; - --it; - operation = *it; - } - - } - } - 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; - } - } + void WhiteboardServer::handleLocalOperationReceived(WhiteboardOperation::ref operation) { + operations_.push_back(operation); + } + + WhiteboardOperation::ref WhiteboardServer::handleClientOperationReceived(WhiteboardOperation::ref newOperation) { + std::list<WhiteboardOperation::ref>::reverse_iterator it; + if (operations_.empty() || newOperation->getParentID() == operations_.back()->getID()) { + operations_.push_back(newOperation); + return newOperation; + } + for (it = operations_.rbegin(); it != operations_.rend(); ++it) { + WhiteboardOperation::ref operation = *it; + while (newOperation->getParentID() == operation->getParentID()) { + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> tResult = WhiteboardTransformer::transform(newOperation, operation); + + if (it == operations_.rbegin()) { + operations_.push_back(tResult.second); + return tResult.second; + } else { + newOperation = tResult.second; + --it; + operation = *it; + } + + } + } + 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 efc7a1c..fcbdbe7 100644 --- a/Swiften/Whiteboard/WhiteboardServer.h +++ b/Swiften/Whiteboard/WhiteboardServer.h @@ -18,13 +18,13 @@ #include <Swiften/Elements/Whiteboard/WhiteboardInsertOperation.h> namespace Swift { - class SWIFTEN_API WhiteboardServer { - public: - void handleLocalOperationReceived(WhiteboardOperation::ref operation); - WhiteboardOperation::ref handleClientOperationReceived(WhiteboardOperation::ref operation); - void print(); + class SWIFTEN_API WhiteboardServer { + public: + void handleLocalOperationReceived(WhiteboardOperation::ref operation); + WhiteboardOperation::ref handleClientOperationReceived(WhiteboardOperation::ref operation); + void print(); - private: - std::list<WhiteboardOperation::ref> operations_; - }; + private: + std::list<WhiteboardOperation::ref> operations_; + }; } diff --git a/Swiften/Whiteboard/WhiteboardSession.cpp b/Swiften/Whiteboard/WhiteboardSession.cpp index 064ab3a..23ca312 100644 --- a/Swiften/Whiteboard/WhiteboardSession.cpp +++ b/Swiften/Whiteboard/WhiteboardSession.cpp @@ -21,54 +21,54 @@ #include <Swiften/Queries/IQRouter.h> namespace Swift { - WhiteboardSession::WhiteboardSession(const JID& jid, IQRouter* router) : toJID_(jid), router_(router) { - } + WhiteboardSession::WhiteboardSession(const JID& jid, IQRouter* router) : toJID_(jid), router_(router) { + } - WhiteboardSession::~WhiteboardSession() { - } + WhiteboardSession::~WhiteboardSession() { + } - void WhiteboardSession::handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload) { - switch (payload->getType()) { - case WhiteboardPayload::Data: - handleIncomingOperation(payload->getOperation()); - return; - case WhiteboardPayload::SessionAccept: - onRequestAccepted(toJID_); - return; - case WhiteboardPayload::SessionTerminate: - onSessionTerminated(toJID_); - return; + void WhiteboardSession::handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload) { + switch (payload->getType()) { + case WhiteboardPayload::Data: + handleIncomingOperation(payload->getOperation()); + return; + case WhiteboardPayload::SessionAccept: + onRequestAccepted(toJID_); + return; + case WhiteboardPayload::SessionTerminate: + onSessionTerminated(toJID_); + return; - //handled elsewhere - case WhiteboardPayload::SessionRequest: + //handled elsewhere + case WhiteboardPayload::SessionRequest: - case WhiteboardPayload::UnknownType: - return; - } - } + case WhiteboardPayload::UnknownType: + return; + } + } - void WhiteboardSession::sendElement(const WhiteboardElement::ref element) { - boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(); - payload->setElement(element); - boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); - request->send(); - } + void WhiteboardSession::sendElement(const WhiteboardElement::ref element) { + boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(); + payload->setElement(element); + boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); + request->send(); + } - void WhiteboardSession::sendPayload(boost::shared_ptr<WhiteboardPayload> payload) { - boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); - request->send(); - } + void WhiteboardSession::sendPayload(boost::shared_ptr<WhiteboardPayload> payload) { + boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); + request->send(); + } - void WhiteboardSession::cancel() { - if (router_->isAvailable()) { - boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionTerminate); - boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); - request->send(); - } - onSessionTerminated(toJID_); - } + void WhiteboardSession::cancel() { + if (router_->isAvailable()) { + boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>(WhiteboardPayload::SessionTerminate); + boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_); + request->send(); + } + onSessionTerminated(toJID_); + } - const JID& WhiteboardSession::getTo() const { - return toJID_; - } + const JID& WhiteboardSession::getTo() const { + return toJID_; + } } diff --git a/Swiften/Whiteboard/WhiteboardSession.h b/Swiften/Whiteboard/WhiteboardSession.h index 05c3dd2..da927b3 100644 --- a/Swiften/Whiteboard/WhiteboardSession.h +++ b/Swiften/Whiteboard/WhiteboardSession.h @@ -23,39 +23,39 @@ #include <Swiften/Queries/GenericRequest.h> namespace Swift { - class IQRouter; - class ErrorPayload; - class WhiteboardPayload; - - class SWIFTEN_API WhiteboardSession { - public: - typedef boost::shared_ptr<WhiteboardSession> ref; - - public: - WhiteboardSession(const JID& jid, IQRouter* router); - virtual ~WhiteboardSession(); - void handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload); - void sendElement(const WhiteboardElement::ref element); - virtual void sendOperation(WhiteboardOperation::ref operation) = 0; - void cancel(); - const JID& getTo() const; - - public: - boost::signal< void(const WhiteboardElement::ref element)> onElementReceived; - boost::signal< void(const WhiteboardOperation::ref operation)> onOperationReceived; - boost::signal< void(const JID& contact)> onSessionTerminated; - boost::signal< void(const JID& contact)> onRequestAccepted; - boost::signal< void(const JID& contact)> onRequestRejected; - - private: - virtual void handleIncomingOperation(WhiteboardOperation::ref operation) = 0; - - protected: - void sendPayload(boost::shared_ptr<WhiteboardPayload> payload); - - JID toJID_; - IQRouter* router_; - std::string lastOpID; - IDGenerator idGenerator; - }; + class IQRouter; + class ErrorPayload; + class WhiteboardPayload; + + class SWIFTEN_API WhiteboardSession { + public: + typedef boost::shared_ptr<WhiteboardSession> ref; + + public: + WhiteboardSession(const JID& jid, IQRouter* router); + virtual ~WhiteboardSession(); + void handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload); + void sendElement(const WhiteboardElement::ref element); + virtual void sendOperation(WhiteboardOperation::ref operation) = 0; + void cancel(); + const JID& getTo() const; + + public: + boost::signal< void(const WhiteboardElement::ref element)> onElementReceived; + boost::signal< void(const WhiteboardOperation::ref operation)> onOperationReceived; + boost::signal< void(const JID& contact)> onSessionTerminated; + boost::signal< void(const JID& contact)> onRequestAccepted; + boost::signal< void(const JID& contact)> onRequestRejected; + + private: + virtual void handleIncomingOperation(WhiteboardOperation::ref operation) = 0; + + protected: + void sendPayload(boost::shared_ptr<WhiteboardPayload> payload); + + JID toJID_; + IQRouter* router_; + std::string lastOpID; + IDGenerator idGenerator; + }; } diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.cpp b/Swiften/Whiteboard/WhiteboardSessionManager.cpp index a3bb2d5..36f02cc 100644 --- a/Swiften/Whiteboard/WhiteboardSessionManager.cpp +++ b/Swiften/Whiteboard/WhiteboardSessionManager.cpp @@ -23,96 +23,96 @@ #include <Swiften/Whiteboard/WhiteboardResponder.h> namespace Swift { - WhiteboardSessionManager::WhiteboardSessionManager(IQRouter* router, StanzaChannel* stanzaChannel, PresenceOracle* presenceOracle, EntityCapsProvider* capsProvider) : router_(router), stanzaChannel_(stanzaChannel), presenceOracle_(presenceOracle), capsProvider_(capsProvider) { - responder = new WhiteboardResponder(this, router); - responder->start(); - stanzaChannel_->onPresenceReceived.connect(boost::bind(&WhiteboardSessionManager::handlePresenceReceived, this, _1)); - stanzaChannel_->onAvailableChanged.connect(boost::bind(&WhiteboardSessionManager::handleAvailableChanged, this, _1)); - } - - WhiteboardSessionManager::~WhiteboardSessionManager() { - responder->stop(); - delete responder; - } - - WhiteboardSession::ref WhiteboardSessionManager::getSession(const JID& to) { - if (sessions_.find(to) == sessions_.end()) { - return boost::shared_ptr<WhiteboardSession>(); - } - return sessions_[to]; - } - - OutgoingWhiteboardSession::ref WhiteboardSessionManager::createOutgoingSession(const JID& to) { - JID fullJID = to; - if (fullJID.isBare()) { - fullJID = getFullJID(fullJID); - } - OutgoingWhiteboardSession::ref session = boost::make_shared<OutgoingWhiteboardSession>(fullJID, router_); - sessions_[fullJID] = session; - session->onSessionTerminated.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); - session->onRequestRejected.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); - return session; - } - - WhiteboardSession::ref WhiteboardSessionManager::requestSession(const JID& to) { - WhiteboardSession::ref session = getSession(to); - if (!session) { - OutgoingWhiteboardSession::ref outgoingSession = createOutgoingSession(to); - outgoingSession->startSession(); - return outgoingSession; - } else { - return session; - } - } - - void WhiteboardSessionManager::handleIncomingSession(IncomingWhiteboardSession::ref session) { - sessions_[session->getTo()] = session; - session->onSessionTerminated.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); - onSessionRequest(session); - } - - JID WhiteboardSessionManager::getFullJID(const JID& bareJID) { - JID fullReceipientJID; - int priority = INT_MIN; - - //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11 - std::vector<Presence::ref> presences = presenceOracle_->getAllPresence(bareJID); - - //iterate over them - foreach(Presence::ref pres, presences) { - if (pres->getPriority() > priority) { - // look up caps from the jid - DiscoInfo::ref info = capsProvider_->getCaps(pres->getFrom()); - if (info && info->hasFeature(DiscoInfo::WhiteboardFeature)) { - priority = pres->getPriority(); - fullReceipientJID = pres->getFrom(); - } - } - } - - return fullReceipientJID; - } - - void WhiteboardSessionManager::deleteSessionEntry(const JID& contact) { - sessions_.erase(contact); - } - - void WhiteboardSessionManager::handlePresenceReceived(Presence::ref presence) { - if (!presence->isAvailable()) { - WhiteboardSession::ref session = getSession(presence->getFrom()); - if (session) { - session->cancel(); - } - } - } - - void WhiteboardSessionManager::handleAvailableChanged(bool available) { - if (!available) { - std::map<JID, WhiteboardSession::ref> sessionsCopy = sessions_; - std::map<JID, WhiteboardSession::ref>::iterator it; - for (it = sessionsCopy.begin(); it != sessionsCopy.end(); ++it) { - it->second->cancel(); - } - } - } + WhiteboardSessionManager::WhiteboardSessionManager(IQRouter* router, StanzaChannel* stanzaChannel, PresenceOracle* presenceOracle, EntityCapsProvider* capsProvider) : router_(router), stanzaChannel_(stanzaChannel), presenceOracle_(presenceOracle), capsProvider_(capsProvider) { + responder = new WhiteboardResponder(this, router); + responder->start(); + stanzaChannel_->onPresenceReceived.connect(boost::bind(&WhiteboardSessionManager::handlePresenceReceived, this, _1)); + stanzaChannel_->onAvailableChanged.connect(boost::bind(&WhiteboardSessionManager::handleAvailableChanged, this, _1)); + } + + WhiteboardSessionManager::~WhiteboardSessionManager() { + responder->stop(); + delete responder; + } + + WhiteboardSession::ref WhiteboardSessionManager::getSession(const JID& to) { + if (sessions_.find(to) == sessions_.end()) { + return boost::shared_ptr<WhiteboardSession>(); + } + return sessions_[to]; + } + + OutgoingWhiteboardSession::ref WhiteboardSessionManager::createOutgoingSession(const JID& to) { + JID fullJID = to; + if (fullJID.isBare()) { + fullJID = getFullJID(fullJID); + } + OutgoingWhiteboardSession::ref session = boost::make_shared<OutgoingWhiteboardSession>(fullJID, router_); + sessions_[fullJID] = session; + session->onSessionTerminated.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); + session->onRequestRejected.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); + return session; + } + + WhiteboardSession::ref WhiteboardSessionManager::requestSession(const JID& to) { + WhiteboardSession::ref session = getSession(to); + if (!session) { + OutgoingWhiteboardSession::ref outgoingSession = createOutgoingSession(to); + outgoingSession->startSession(); + return outgoingSession; + } else { + return session; + } + } + + void WhiteboardSessionManager::handleIncomingSession(IncomingWhiteboardSession::ref session) { + sessions_[session->getTo()] = session; + session->onSessionTerminated.connect(boost::bind(&WhiteboardSessionManager::deleteSessionEntry, this, _1)); + onSessionRequest(session); + } + + JID WhiteboardSessionManager::getFullJID(const JID& bareJID) { + JID fullReceipientJID; + int priority = INT_MIN; + + //getAllPresence(bareJID) gives you all presences for the bare JID (i.e. all resources) Remko Tronçon @ 11:11 + std::vector<Presence::ref> presences = presenceOracle_->getAllPresence(bareJID); + + //iterate over them + foreach(Presence::ref pres, presences) { + if (pres->getPriority() > priority) { + // look up caps from the jid + DiscoInfo::ref info = capsProvider_->getCaps(pres->getFrom()); + if (info && info->hasFeature(DiscoInfo::WhiteboardFeature)) { + priority = pres->getPriority(); + fullReceipientJID = pres->getFrom(); + } + } + } + + return fullReceipientJID; + } + + void WhiteboardSessionManager::deleteSessionEntry(const JID& contact) { + sessions_.erase(contact); + } + + void WhiteboardSessionManager::handlePresenceReceived(Presence::ref presence) { + if (!presence->isAvailable()) { + WhiteboardSession::ref session = getSession(presence->getFrom()); + if (session) { + session->cancel(); + } + } + } + + void WhiteboardSessionManager::handleAvailableChanged(bool available) { + if (!available) { + std::map<JID, WhiteboardSession::ref> sessionsCopy = sessions_; + std::map<JID, WhiteboardSession::ref>::iterator it; + for (it = sessionsCopy.begin(); it != sessionsCopy.end(); ++it) { + it->second->cancel(); + } + } + } } diff --git a/Swiften/Whiteboard/WhiteboardSessionManager.h b/Swiften/Whiteboard/WhiteboardSessionManager.h index 3a435a1..44ec087 100644 --- a/Swiften/Whiteboard/WhiteboardSessionManager.h +++ b/Swiften/Whiteboard/WhiteboardSessionManager.h @@ -24,37 +24,37 @@ #include <Swiften/Whiteboard/WhiteboardSession.h> namespace Swift { - class IQRouter; - class WhiteboardResponder; - class PresenceOracle; - class EntityCapsProvider; - - class SWIFTEN_API WhiteboardSessionManager { - friend class WhiteboardResponder; - public: - WhiteboardSessionManager(IQRouter* router, StanzaChannel* stanzaChannel, PresenceOracle* presenceOracle, EntityCapsProvider* capsProvider); - ~WhiteboardSessionManager(); - - WhiteboardSession::ref getSession(const JID& to); - WhiteboardSession::ref requestSession(const JID& to); - - public: - boost::signal< void (IncomingWhiteboardSession::ref)> onSessionRequest; - - private: - JID getFullJID(const JID& bareJID); - OutgoingWhiteboardSession::ref createOutgoingSession(const JID& to); - void handleIncomingSession(IncomingWhiteboardSession::ref session); - void handlePresenceReceived(Presence::ref presence); - void handleAvailableChanged(bool available); - void deleteSessionEntry(const JID& contact); - - private: - std::map<JID, boost::shared_ptr<WhiteboardSession> > sessions_; - IQRouter* router_; - StanzaChannel* stanzaChannel_; - PresenceOracle* presenceOracle_; - EntityCapsProvider* capsProvider_; - WhiteboardResponder* responder; - }; + class IQRouter; + class WhiteboardResponder; + class PresenceOracle; + class EntityCapsProvider; + + class SWIFTEN_API WhiteboardSessionManager { + friend class WhiteboardResponder; + public: + WhiteboardSessionManager(IQRouter* router, StanzaChannel* stanzaChannel, PresenceOracle* presenceOracle, EntityCapsProvider* capsProvider); + ~WhiteboardSessionManager(); + + WhiteboardSession::ref getSession(const JID& to); + WhiteboardSession::ref requestSession(const JID& to); + + public: + boost::signal< void (IncomingWhiteboardSession::ref)> onSessionRequest; + + private: + JID getFullJID(const JID& bareJID); + OutgoingWhiteboardSession::ref createOutgoingSession(const JID& to); + void handleIncomingSession(IncomingWhiteboardSession::ref session); + void handlePresenceReceived(Presence::ref presence); + void handleAvailableChanged(bool available); + void deleteSessionEntry(const JID& contact); + + private: + std::map<JID, boost::shared_ptr<WhiteboardSession> > sessions_; + IQRouter* router_; + StanzaChannel* stanzaChannel_; + PresenceOracle* presenceOracle_; + EntityCapsProvider* capsProvider_; + WhiteboardResponder* responder; + }; } diff --git a/Swiften/Whiteboard/WhiteboardTransformer.cpp b/Swiften/Whiteboard/WhiteboardTransformer.cpp index ea0ba8c..40e364b 100644 --- a/Swiften/Whiteboard/WhiteboardTransformer.cpp +++ b/Swiften/Whiteboard/WhiteboardTransformer.cpp @@ -15,206 +15,206 @@ #include <boost/smart_ptr/make_shared.hpp> namespace Swift { - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardOperation::ref clientOp, WhiteboardOperation::ref serverOp) { - WhiteboardInsertOperation::ref clientInsert = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(clientOp); - WhiteboardInsertOperation::ref serverInsert = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(serverOp); - WhiteboardUpdateOperation::ref clientUpdate = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(clientOp); - WhiteboardUpdateOperation::ref serverUpdate = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(serverOp); - WhiteboardDeleteOperation::ref clientDelete = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(clientOp); - WhiteboardDeleteOperation::ref serverDelete = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(serverOp); - if (clientInsert && serverInsert) { - return transform(clientInsert, serverInsert); - } else if (clientUpdate && serverUpdate) { - return transform(clientUpdate, serverUpdate); - } else if (clientInsert && serverUpdate) { - return transform(clientInsert, serverUpdate); - } else if (clientUpdate && serverInsert) { - return transform(clientUpdate, serverInsert); - } else if (clientDelete && serverDelete) { - return transform(clientDelete, serverDelete); - } else if (clientInsert && serverDelete) { - return transform(clientInsert, serverDelete); - } else if (clientDelete && serverInsert) { - return transform(clientDelete, serverInsert); - } else if (clientUpdate && serverDelete) { - return transform(clientUpdate, serverDelete); - } else if (clientDelete && serverUpdate) { - return transform(clientDelete, serverUpdate); - } else { - return std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref>(); - } - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { - std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> result; - result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() <= serverOp->getPos()) { - result.first->setPos(result.first->getPos()+1); - } else { - result.second->setPos(result.second->getPos()+1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { - std::pair<WhiteboardUpdateOperation::ref, WhiteboardUpdateOperation::ref> result; - result.first = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - - if (clientOp->getPos() == serverOp->getPos()) { - result.second = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); - result.second->setID(clientOp->getID()); - result.second->setParentID(serverOp->getID()); - } else { - result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - } - - if (clientOp->getPos() < serverOp->getPos() && clientOp->getNewPos() > serverOp->getPos()) { - result.first->setPos(result.first->getPos()-1); - if (clientOp->getNewPos() >= serverOp->getNewPos()) { - result.first->setNewPos(result.first->getNewPos()-1); - } - } else if (clientOp->getNewPos() >= serverOp->getNewPos()) { - result.first->setNewPos(result.first->getNewPos()-1); - } - - if (serverOp->getPos() < clientOp->getPos() && serverOp->getNewPos() > clientOp->getPos()) { - result.second->setPos(result.second->getPos()-1); - if (serverOp->getNewPos() >= clientOp->getNewPos()) { - result.second->setNewPos(result.second->getNewPos()-1); - } - } else if (serverOp->getNewPos() >= clientOp->getNewPos()) { - result.second->setNewPos(result.second->getNewPos()-1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { - std::pair<WhiteboardInsertOperation::ref, WhiteboardUpdateOperation::ref> result; - result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - if (serverOp->getPos() <= clientOp->getPos()) { - result.second->setPos(result.second->getPos()+1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { - std::pair<WhiteboardUpdateOperation::ref, WhiteboardInsertOperation::ref> result; - result.first = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - if (serverOp->getPos() >= clientOp->getPos()) { - result.first->setPos(result.first->getPos()+1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { - std::pair<WhiteboardDeleteOperation::ref, WhiteboardDeleteOperation::ref> result; - result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); - 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); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { - std::pair<WhiteboardDeleteOperation::ref, WhiteboardInsertOperation::ref> result; - result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - if (clientOp->getPos() <= serverOp->getPos()) { - result.first->setPos(result.first->getPos()+1); - } else if (serverOp->getPos() != -1) { - result.second->setPos(result.second->getPos()-1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { - std::pair<WhiteboardInsertOperation::ref, WhiteboardDeleteOperation::ref> result; - result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardDeleteOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - if (serverOp->getPos() <= clientOp->getPos()) { - result.second->setPos(result.second->getPos()+1); - } 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, WhiteboardOperation::ref> result; - result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); - result.first->setParentID(clientOp->getID()); - WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); - result.second = updateOp; - result.second->setParentID(serverOp->getID()); - 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() && clientOp->getNewPos() <= serverOp->getPos()) { - result.second->setPos(result.second->getPos()-1); - } else if (clientOp->getPos() < serverOp->getPos() && clientOp->getNewPos() >= serverOp->getPos()) { - updateOp->setNewPos(updateOp->getNewPos()-1); - } else if (clientOp->getPos() > serverOp->getPos()) { - result.second->setPos(result.second->getPos()-1); - updateOp->setNewPos(updateOp->getNewPos()-1); - } - return result; - } - - std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { - std::pair<WhiteboardOperation::ref, WhiteboardDeleteOperation::ref> result; - WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); - result.first = updateOp; - result.first->setParentID(clientOp->getID()); - result.second = boost::make_shared<WhiteboardDeleteOperation>(*clientOp); - result.second->setParentID(serverOp->getID()); - 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() && clientOp->getPos() >= serverOp->getNewPos()) { - result.first->setPos(result.first->getPos()-1); - } else if (clientOp->getPos() > serverOp->getPos() && clientOp->getPos() <= serverOp->getNewPos()) { - updateOp->setNewPos(updateOp->getNewPos()-1); - } else if (clientOp->getPos() < serverOp->getPos()) { - result.first->setPos(result.first->getPos()-1); - updateOp->setNewPos(updateOp->getNewPos()-1); - } - return result; - } + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardOperation::ref clientOp, WhiteboardOperation::ref serverOp) { + WhiteboardInsertOperation::ref clientInsert = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(clientOp); + WhiteboardInsertOperation::ref serverInsert = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(serverOp); + WhiteboardUpdateOperation::ref clientUpdate = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(clientOp); + WhiteboardUpdateOperation::ref serverUpdate = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(serverOp); + WhiteboardDeleteOperation::ref clientDelete = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(clientOp); + WhiteboardDeleteOperation::ref serverDelete = boost::dynamic_pointer_cast<WhiteboardDeleteOperation>(serverOp); + if (clientInsert && serverInsert) { + return transform(clientInsert, serverInsert); + } else if (clientUpdate && serverUpdate) { + return transform(clientUpdate, serverUpdate); + } else if (clientInsert && serverUpdate) { + return transform(clientInsert, serverUpdate); + } else if (clientUpdate && serverInsert) { + return transform(clientUpdate, serverInsert); + } else if (clientDelete && serverDelete) { + return transform(clientDelete, serverDelete); + } else if (clientInsert && serverDelete) { + return transform(clientInsert, serverDelete); + } else if (clientDelete && serverInsert) { + return transform(clientDelete, serverInsert); + } else if (clientUpdate && serverDelete) { + return transform(clientUpdate, serverDelete); + } else if (clientDelete && serverUpdate) { + return transform(clientDelete, serverUpdate); + } else { + return std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref>(); + } + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { + std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> result; + result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + if (clientOp->getPos() <= serverOp->getPos()) { + result.first->setPos(result.first->getPos()+1); + } else { + result.second->setPos(result.second->getPos()+1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { + std::pair<WhiteboardUpdateOperation::ref, WhiteboardUpdateOperation::ref> result; + result.first = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + + if (clientOp->getPos() == serverOp->getPos()) { + result.second = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); + result.second->setID(clientOp->getID()); + result.second->setParentID(serverOp->getID()); + } else { + result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + } + + if (clientOp->getPos() < serverOp->getPos() && clientOp->getNewPos() > serverOp->getPos()) { + result.first->setPos(result.first->getPos()-1); + if (clientOp->getNewPos() >= serverOp->getNewPos()) { + result.first->setNewPos(result.first->getNewPos()-1); + } + } else if (clientOp->getNewPos() >= serverOp->getNewPos()) { + result.first->setNewPos(result.first->getNewPos()-1); + } + + if (serverOp->getPos() < clientOp->getPos() && serverOp->getNewPos() > clientOp->getPos()) { + result.second->setPos(result.second->getPos()-1); + if (serverOp->getNewPos() >= clientOp->getNewPos()) { + result.second->setNewPos(result.second->getNewPos()-1); + } + } else if (serverOp->getNewPos() >= clientOp->getNewPos()) { + result.second->setNewPos(result.second->getNewPos()-1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { + std::pair<WhiteboardInsertOperation::ref, WhiteboardUpdateOperation::ref> result; + result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + if (serverOp->getPos() <= clientOp->getPos()) { + result.second->setPos(result.second->getPos()+1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { + std::pair<WhiteboardUpdateOperation::ref, WhiteboardInsertOperation::ref> result; + result.first = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + if (serverOp->getPos() >= clientOp->getPos()) { + result.first->setPos(result.first->getPos()+1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { + std::pair<WhiteboardDeleteOperation::ref, WhiteboardDeleteOperation::ref> result; + result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); + 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); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp) { + std::pair<WhiteboardDeleteOperation::ref, WhiteboardInsertOperation::ref> result; + result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + if (clientOp->getPos() <= serverOp->getPos()) { + result.first->setPos(result.first->getPos()+1); + } else if (serverOp->getPos() != -1) { + result.second->setPos(result.second->getPos()-1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) { + std::pair<WhiteboardInsertOperation::ref, WhiteboardDeleteOperation::ref> result; + result.first = boost::make_shared<WhiteboardInsertOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardDeleteOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + if (serverOp->getPos() <= clientOp->getPos()) { + result.second->setPos(result.second->getPos()+1); + } 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, WhiteboardOperation::ref> result; + result.first = boost::make_shared<WhiteboardDeleteOperation>(*serverOp); + result.first->setParentID(clientOp->getID()); + WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>(*clientOp); + result.second = updateOp; + result.second->setParentID(serverOp->getID()); + 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() && clientOp->getNewPos() <= serverOp->getPos()) { + result.second->setPos(result.second->getPos()-1); + } else if (clientOp->getPos() < serverOp->getPos() && clientOp->getNewPos() >= serverOp->getPos()) { + updateOp->setNewPos(updateOp->getNewPos()-1); + } else if (clientOp->getPos() > serverOp->getPos()) { + result.second->setPos(result.second->getPos()-1); + updateOp->setNewPos(updateOp->getNewPos()-1); + } + return result; + } + + std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> WhiteboardTransformer::transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp) { + std::pair<WhiteboardOperation::ref, WhiteboardDeleteOperation::ref> result; + WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>(*serverOp); + result.first = updateOp; + result.first->setParentID(clientOp->getID()); + result.second = boost::make_shared<WhiteboardDeleteOperation>(*clientOp); + result.second->setParentID(serverOp->getID()); + 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() && clientOp->getPos() >= serverOp->getNewPos()) { + result.first->setPos(result.first->getPos()-1); + } else if (clientOp->getPos() > serverOp->getPos() && clientOp->getPos() <= serverOp->getNewPos()) { + updateOp->setNewPos(updateOp->getNewPos()-1); + } else if (clientOp->getPos() < serverOp->getPos()) { + result.first->setPos(result.first->getPos()-1); + updateOp->setNewPos(updateOp->getNewPos()-1); + } + return result; + } } diff --git a/Swiften/Whiteboard/WhiteboardTransformer.h b/Swiften/Whiteboard/WhiteboardTransformer.h index 1ef13a6..399e299 100644 --- a/Swiften/Whiteboard/WhiteboardTransformer.h +++ b/Swiften/Whiteboard/WhiteboardTransformer.h @@ -19,17 +19,17 @@ #include <Swiften/Elements/Whiteboard/WhiteboardUpdateOperation.h> namespace Swift { - class WhiteboardTransformer { - public: - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardOperation::ref clientOp, WhiteboardOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); - static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); - }; + class WhiteboardTransformer { + public: + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardOperation::ref clientOp, WhiteboardOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardUpdateOperation::ref clientOp, WhiteboardDeleteOperation::ref serverOp); + static std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> transform(WhiteboardDeleteOperation::ref clientOp, WhiteboardUpdateOperation::ref serverOp); + }; } |