summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Whiteboard')
-rw-r--r--Swiften/Whiteboard/IncomingWhiteboardSession.cpp70
-rw-r--r--Swiften/Whiteboard/IncomingWhiteboardSession.h24
-rw-r--r--Swiften/Whiteboard/OutgoingWhiteboardSession.cpp68
-rw-r--r--Swiften/Whiteboard/OutgoingWhiteboardSession.h32
-rw-r--r--Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp1302
-rw-r--r--Swiften/Whiteboard/UnitTest/WhiteboardServerTest.cpp200
-rw-r--r--Swiften/Whiteboard/WhiteboardClient.cpp216
-rw-r--r--Swiften/Whiteboard/WhiteboardClient.h42
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.cpp40
-rw-r--r--Swiften/Whiteboard/WhiteboardResponder.h20
-rw-r--r--Swiften/Whiteboard/WhiteboardServer.cpp72
-rw-r--r--Swiften/Whiteboard/WhiteboardServer.h16
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.cpp84
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.h70
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.cpp184
-rw-r--r--Swiften/Whiteboard/WhiteboardSessionManager.h66
-rw-r--r--Swiften/Whiteboard/WhiteboardTransformer.cpp404
-rw-r--r--Swiften/Whiteboard/WhiteboardTransformer.h26
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);
+ };
}