summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMateusz Piekos <mateuszpiekos@gmail.com>2012-07-16 12:14:05 (GMT)
committerMateusz Piekos <mateuszpiekos@gmail.com>2012-07-16 12:14:05 (GMT)
commitb2e11d7f32db65a6be001dfdf74b74f16f4c9ec3 (patch)
treee99331d9c20e8199fda582e5f1b603d01b368f2a
parent0ba890e7e8c7e09c1257a7c3b1018f396e6896d1 (diff)
downloadswift-contrib-b2e11d7f32db65a6be001dfdf74b74f16f4c9ec3.zip
swift-contrib-b2e11d7f32db65a6be001dfdf74b74f16f4c9ec3.tar.bz2
Extended classes handling synchronization with update operation
-rw-r--r--Swiften/Parser/PayloadParsers/WhiteboardParser.cpp21
-rw-r--r--Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp16
-rw-r--r--Swiften/Whiteboard/Elements/WhiteboardLineElement.h14
-rw-r--r--Swiften/Whiteboard/IncomingWhiteboardSession.cpp14
-rw-r--r--Swiften/Whiteboard/IncomingWhiteboardSession.h2
-rw-r--r--Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h32
-rw-r--r--Swiften/Whiteboard/OutgoingWhiteboardSession.cpp2
-rw-r--r--Swiften/Whiteboard/OutgoingWhiteboardSession.h2
-rw-r--r--Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp109
-rw-r--r--Swiften/Whiteboard/WhiteboardClient.cpp37
-rw-r--r--Swiften/Whiteboard/WhiteboardServer.cpp16
-rw-r--r--Swiften/Whiteboard/WhiteboardServer.h2
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.cpp9
-rw-r--r--Swiften/Whiteboard/WhiteboardSession.h4
-rw-r--r--Swiften/Whiteboard/WhiteboardTransformer.cpp60
-rw-r--r--Swiften/Whiteboard/WhiteboardTransformer.h7
16 files changed, 306 insertions, 41 deletions
diff --git a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
index 037eae2..5d4aef1 100644
--- a/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
+++ b/Swiften/Parser/PayloadParsers/WhiteboardParser.cpp
@@ -13,6 +13,7 @@
#include <Swiften/Whiteboard/Elements/WhiteboardFreehandPathElement.h>
#include <Swiften/Whiteboard/Elements/Color.h>
#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h>
+#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h>
#include <boost/optional.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <boost/lexical_cast.hpp>
@@ -35,6 +36,15 @@ namespace Swift {
} catch (boost::bad_lexical_cast&) {
}
operation = insertOp;
+ } else if (type == "update") {
+ WhiteboardUpdateOperation::ref updateOp = boost::make_shared<WhiteboardUpdateOperation>();
+ try {
+ updateOp->setID(attributes.getAttributeValue("id").get_value_or(""));
+ updateOp->setParentID(attributes.getAttributeValue("parentid").get_value_or(""));
+ updateOp->setPos(boost::lexical_cast<int>(attributes.getAttributeValue("pos").get_value_or("0")));
+ } catch (boost::bad_lexical_cast&) {
+ }
+ operation = updateOp;
}
} else if (level_ == 2) {
if (element == "line") {
@@ -42,15 +52,21 @@ namespace Swift {
int y1 = 0;
int x2 = 0;
int y2 = 0;
+ int xShift = 0;
+ int yShift = 0;
try {
x1 = boost::lexical_cast<int>(attributes.getAttributeValue("x1").get_value_or("0"));
y1 = boost::lexical_cast<int>(attributes.getAttributeValue("y1").get_value_or("0"));
x2 = boost::lexical_cast<int>(attributes.getAttributeValue("x2").get_value_or("0"));
y2 = boost::lexical_cast<int>(attributes.getAttributeValue("y2").get_value_or("0"));
+ xShift = boost::lexical_cast<int>(attributes.getAttributeValue("xshift").get_value_or("0"));
+ yShift = boost::lexical_cast<int>(attributes.getAttributeValue("yshift").get_value_or("0"));
} catch (boost::bad_lexical_cast&) {
}
WhiteboardLineElement::ref whiteboardElement = boost::make_shared<WhiteboardLineElement>(x1, y1, x2, y2);
+ whiteboardElement->setShift(xShift, yShift);
+
Color color(attributes.getAttributeValue("stroke").get_value_or("#000000"));
color.setAlpha(opacityToAlpha(attributes.getAttributeValue("opacity").get_value_or("1")));
whiteboardElement->setColor(color);
@@ -253,6 +269,11 @@ namespace Swift {
if (insertOp) {
insertOp->setElement(wbElement);
}
+
+ WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
+ if (updateOp) {
+ updateOp->setElement(wbElement);
+ }
getPayloadInternal()->setOperation(operation);
} else if (level_ == 2) {
if (element == "text") {
diff --git a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
index 0cd4779..965939a 100644
--- a/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
+++ b/Swiften/Serializer/PayloadSerializers/WhiteboardSerializer.cpp
@@ -10,6 +10,7 @@
#include <boost/lexical_cast.hpp>
#include <Swiften/Serializer/XML/XMLTextNode.h>
#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h>
+#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h>
namespace Swift {
void WhiteboardElementSerializingVisitor::visit(WhiteboardLineElement& line) {
@@ -19,6 +20,8 @@ namespace Swift {
element->setAttribute("y1", boost::lexical_cast<std::string>(line.y1()));
element->setAttribute("x2", boost::lexical_cast<std::string>(line.x2()));
element->setAttribute("y2", boost::lexical_cast<std::string>(line.y2()));
+ element->setAttribute("xshift", boost::lexical_cast<std::string>(line.getXShift()));
+ element->setAttribute("yshift", boost::lexical_cast<std::string>(line.getYShift()));
element->setAttribute("id", line.getID());
element->setAttribute("stroke", line.getColor().toHex());
element->setAttribute("stroke-width", boost::lexical_cast<std::string>(line.getPenWidth()));
@@ -151,6 +154,19 @@ namespace Swift {
insertOp->getElement()->accept(visitor);
operationNode->addNode(visitor.getResult());
}
+ WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(payload->getOperation());
+ if (updateOp) {
+ try {
+ operationNode->setAttribute("type", "update");
+ operationNode->setAttribute("pos", boost::lexical_cast<std::string>(updateOp->getPos()));
+ operationNode->setAttribute("id", updateOp->getID());
+ operationNode->setAttribute("parentid", updateOp->getParentID());
+ } catch (boost::bad_lexical_cast&) {
+ }
+ updateOp->getElement()->accept(visitor);
+ operationNode->addNode(visitor.getResult());
+
+ }
element.addNode(operationNode);
}
element.setAttribute("type", typeToString(payload->getType()));
diff --git a/Swiften/Whiteboard/Elements/WhiteboardLineElement.h b/Swiften/Whiteboard/Elements/WhiteboardLineElement.h
index 20455b6..85e6302 100644
--- a/Swiften/Whiteboard/Elements/WhiteboardLineElement.h
+++ b/Swiften/Whiteboard/Elements/WhiteboardLineElement.h
@@ -37,6 +37,19 @@ namespace Swift {
return y2_;
}
+ int getXShift() const {
+ return xShift_;
+ }
+
+ int getYShift() const {
+ return yShift_;
+ }
+
+ void setShift(int x, int y) {
+ xShift_ = x;
+ yShift_ = y;
+ }
+
const Color& getColor() const {
return color_;
}
@@ -67,6 +80,7 @@ namespace Swift {
private:
int x1_, y1_, x2_, y2_;
+ int xShift_, yShift_;
Color color_;
int penWidth_;
std::string id_;
diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
index 60faa2e..42f5934 100644
--- a/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
+++ b/Swiften/Whiteboard/IncomingWhiteboardSession.cpp
@@ -26,21 +26,21 @@ namespace Swift {
void IncomingWhiteboardSession::handleIncomingOperation(WhiteboardOperation::ref operation) {
// std::cout << "incoming pos: " << operation->getPos() << std::endl;
- WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
- if (insertOp) {
- WhiteboardOperation::ref op = server.handleClientOperationReceived(insertOp);
+// WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+// if (insertOp) {
+ WhiteboardOperation::ref op = server.handleClientOperationReceived(operation);
//std::cout << "in1: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID() << std::endl;
//std::cout << "in2: " << op->getID() << " " << op->getPos() << " " << op->getParentID() << std::endl;
onOperationReceived(op);
WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>();
payload->setOperation(op);
sendPayload(payload);
- } else {
- std::cout << "unknown operation" << std::endl;
- }
+// } else {
+// std::cout << "unknown operation" << std::endl;
+// }
}
- void IncomingWhiteboardSession::handleSendOperationRequest(WhiteboardOperation::ref operation) {
+ void IncomingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) {
//std::cout << "out: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID()<< std::endl;
server.handleLocalOperationReceived(operation);
WhiteboardPayload::ref payload = boost::make_shared<WhiteboardPayload>();
diff --git a/Swiften/Whiteboard/IncomingWhiteboardSession.h b/Swiften/Whiteboard/IncomingWhiteboardSession.h
index 33c1a78..99d3e44 100644
--- a/Swiften/Whiteboard/IncomingWhiteboardSession.h
+++ b/Swiften/Whiteboard/IncomingWhiteboardSession.h
@@ -24,7 +24,7 @@ namespace Swift {
private:
void handleIncomingOperation(WhiteboardOperation::ref operation);
- void handleSendOperationRequest(WhiteboardOperation::ref operation);
+ void sendOperation(WhiteboardOperation::ref operation);
WhiteboardServer server;
};
diff --git a/Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h b/Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h
new file mode 100644
index 0000000..7c4b088
--- /dev/null
+++ b/Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012 Mateusz Piękos
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Whiteboard/Operations/WhiteboardOperation.h>
+
+#include <Swiften/Whiteboard/Elements/WhiteboardElement.h>
+
+namespace Swift {
+ class WhiteboardUpdateOperation : public WhiteboardOperation {
+ public:
+ typedef boost::shared_ptr<WhiteboardUpdateOperation> ref;
+ public:
+ ~WhiteboardUpdateOperation() {
+ }
+
+ WhiteboardElement::ref getElement() const {
+ return element_;
+ }
+
+ void setElement(WhiteboardElement::ref element) {
+ element_ = element;
+ }
+
+ private:
+ WhiteboardElement::ref element_;
+ };
+}
diff --git a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp
index da4d3cf..b3722ac 100644
--- a/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp
+++ b/Swiften/Whiteboard/OutgoingWhiteboardSession.cpp
@@ -51,7 +51,7 @@ namespace Swift {
}
}
- void OutgoingWhiteboardSession::handleSendOperationRequest(WhiteboardOperation::ref operation) {
+ void OutgoingWhiteboardSession::sendOperation(WhiteboardOperation::ref operation) {
//std::cout << "out1: " << operation->getID() << " " << operation->getPos() << " " << operation->getParentID() << std::endl;
WhiteboardOperation::ref result = client.handleLocalOperationReceived(operation);
diff --git a/Swiften/Whiteboard/OutgoingWhiteboardSession.h b/Swiften/Whiteboard/OutgoingWhiteboardSession.h
index fbd0f20..66b2d3f 100644
--- a/Swiften/Whiteboard/OutgoingWhiteboardSession.h
+++ b/Swiften/Whiteboard/OutgoingWhiteboardSession.h
@@ -25,7 +25,7 @@ namespace Swift {
private:
void handleRequestResponse(boost::shared_ptr<WhiteboardPayload> payload, ErrorPayload::ref error);
void handleIncomingOperation(WhiteboardOperation::ref operation);
- void handleSendOperationRequest(WhiteboardOperation::ref operation);
+ void sendOperation(WhiteboardOperation::ref operation);
WhiteboardClient client;
};
diff --git a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
index 1b89ae4..996d8a3 100644
--- a/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
+++ b/Swiften/Whiteboard/UnitTest/WhiteboardClientTest.cpp
@@ -11,6 +11,7 @@
#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Whiteboard/WhiteboardClient.h>
#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h>
+#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h>
#include <Swiften/Whiteboard/Elements/WhiteboardEllipseElement.h>
using namespace Swift;
@@ -22,6 +23,7 @@ class WhiteboardClientTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testSynchronize_nonInterrupted);
CPPUNIT_TEST(testSynchronize_clientInterruption);
CPPUNIT_TEST(testSynchronize_serverInterruption);
+ CPPUNIT_TEST(testSynchronize_nonInterruptedMixOperations);
CPPUNIT_TEST_SUITE_END();
public:
@@ -481,6 +483,95 @@ public:
}
+ /*!
+ * /\
+ * / \
+ * \ /
+ * \/
+ */
+ 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);
+ clientOp->setOrigin(WhiteboardOperation::Local);
+ 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);
+ serverOp->setOrigin(WhiteboardOperation::Other);
+ 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);
+ serverOp->setOrigin(WhiteboardOperation::Other);
+ 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);
+ serverUpdateOp->setOrigin(WhiteboardOperation::Other);
+ 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.
+ }
+
WhiteboardInsertOperation::ref createInsertOperation(std::string id, std::string parent, int pos) {
WhiteboardInsertOperation::ref operation = boost::make_shared<WhiteboardInsertOperation>();
operation->setParentID(parent);
@@ -489,6 +580,14 @@ public:
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;
+ }
+
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());
@@ -497,7 +596,15 @@ public:
}
if (element) {
- CPPUNIT_ASSERT_EQUAL(element, boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation)->getElement());
+ 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());
+ }
}
}
};
diff --git a/Swiften/Whiteboard/WhiteboardClient.cpp b/Swiften/Whiteboard/WhiteboardClient.cpp
index 9610247..2dd9e45 100644
--- a/Swiften/Whiteboard/WhiteboardClient.cpp
+++ b/Swiften/Whiteboard/WhiteboardClient.cpp
@@ -12,7 +12,16 @@ namespace Swift {
WhiteboardOperation::ref WhiteboardClient::handleLocalOperationReceived(WhiteboardOperation::ref operation) {
localOperations_.push_back(operation);
// if (bridge_.size() > 0) {
- WhiteboardOperation::ref op = boost::make_shared<WhiteboardInsertOperation>(*boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation).get());
+ WhiteboardOperation::ref op;
+ WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+ if (insertOp) {
+ op = boost::make_shared<WhiteboardInsertOperation>(*insertOp.get());
+ }
+ WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
+ if (updateOp) {
+ op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp.get());
+ }
+
if (bridge_.size() > 0) {
op->setParentID(bridge_.back()->getID());
}
@@ -20,7 +29,15 @@ namespace Swift {
// }
if (lastSentOperationID_.empty())
{
- WhiteboardOperation::ref op = boost::make_shared<WhiteboardInsertOperation>(*boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation).get());
+ WhiteboardInsertOperation::ref insertOp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+ if (insertOp) {
+ op = boost::make_shared<WhiteboardInsertOperation>(*insertOp.get());
+ }
+ WhiteboardUpdateOperation::ref updateOp = boost::dynamic_pointer_cast<WhiteboardUpdateOperation>(operation);
+ if (updateOp) {
+ op = boost::make_shared<WhiteboardUpdateOperation>(*updateOp.get());
+ }
+
if (serverOperations_.size() > 0) {
op->setParentID(serverOperations_.back()->getID());
}
@@ -62,23 +79,22 @@ namespace Swift {
result.server = bridge_.front();
result.server->setOrigin(WhiteboardOperation::Other);
}
-
if (!result.server) {
lastSentOperationID_.clear();
}
} else {
if (bridge_.size() > 0 && bridge_.front()->getParentID() == operation->getParentID()) {
std::list<WhiteboardOperation::ref>::iterator it = bridge_.begin();
- std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair;
- WhiteboardInsertOperation::ref temp;
- opPair = WhiteboardTransformer::transform(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*it), boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation));
+ 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(boost::dynamic_pointer_cast<WhiteboardInsertOperation>(*it), temp);
+ opPair = WhiteboardTransformer::transform(*it, temp);
temp = opPair.first;
*it = opPair.second;
(*it)->setParentID(previousID);
@@ -90,7 +106,7 @@ namespace Swift {
result.client = temp;
} else {
//doesn't get executed
- std::list<WhiteboardOperation::ref>::reverse_iterator it;
+/* std::list<WhiteboardOperation::ref>::reverse_iterator it;
std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> opPair;
WhiteboardInsertOperation::ref temp = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
bool end = false;
@@ -113,8 +129,9 @@ namespace Swift {
}
if (end) {
break;
- }
- }
+ }*/
+
+
}
}
diff --git a/Swiften/Whiteboard/WhiteboardServer.cpp b/Swiften/Whiteboard/WhiteboardServer.cpp
index 36dea87..e84ddb3 100644
--- a/Swiften/Whiteboard/WhiteboardServer.cpp
+++ b/Swiften/Whiteboard/WhiteboardServer.cpp
@@ -12,7 +12,7 @@ namespace Swift {
operations_.push_back(operation);
}
- WhiteboardOperation::ref WhiteboardServer::handleClientOperationReceived(WhiteboardInsertOperation::ref newOperation) {
+ WhiteboardOperation::ref WhiteboardServer::handleClientOperationReceived(WhiteboardOperation::ref newOperation) {
std::list<WhiteboardOperation::ref>::reverse_iterator it;
if (operations_.size() == 0 || newOperation->getParentID() == operations_.back()->getID()) {
operations_.push_back(newOperation);
@@ -21,9 +21,9 @@ namespace Swift {
for (it = operations_.rbegin(); it != operations_.rend(); ++it) {
WhiteboardOperation::ref operation = *it;
while (newOperation->getParentID() == operation->getParentID()) {
- WhiteboardInsertOperation::ref insertOperation = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
- if (insertOperation) {
- std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> tResult = WhiteboardTransformer::transform(newOperation, insertOperation);
+// WhiteboardInsertOperation::ref insertOperation = boost::dynamic_pointer_cast<WhiteboardInsertOperation>(operation);
+// if (insertOperation) {
+ std::pair<WhiteboardOperation::ref, WhiteboardOperation::ref> tResult = WhiteboardTransformer::transform(newOperation, operation);
if (it == operations_.rbegin()) {
operations_.push_back(tResult.second);
@@ -33,10 +33,10 @@ namespace Swift {
--it;
operation = *it;
}
- } else {
- operations_.push_back(operation);
- return *it;
- }
+// } else {
+// operations_.push_back(operation);
+// return *it;
+// }
}
}
return WhiteboardOperation::ref();
diff --git a/Swiften/Whiteboard/WhiteboardServer.h b/Swiften/Whiteboard/WhiteboardServer.h
index 11ef64d..6ee4ac6 100644
--- a/Swiften/Whiteboard/WhiteboardServer.h
+++ b/Swiften/Whiteboard/WhiteboardServer.h
@@ -14,7 +14,7 @@ namespace Swift {
class WhiteboardServer {
public:
void handleLocalOperationReceived(WhiteboardOperation::ref operation);
- WhiteboardOperation::ref handleClientOperationReceived(WhiteboardInsertOperation::ref operation);
+ WhiteboardOperation::ref handleClientOperationReceived(WhiteboardOperation::ref operation);
private:
std::list<WhiteboardOperation::ref> operations_;
diff --git a/Swiften/Whiteboard/WhiteboardSession.cpp b/Swiften/Whiteboard/WhiteboardSession.cpp
index 2828436..492aec5 100644
--- a/Swiften/Whiteboard/WhiteboardSession.cpp
+++ b/Swiften/Whiteboard/WhiteboardSession.cpp
@@ -44,14 +44,9 @@ namespace Swift {
request->send();
}
- void WhiteboardSession::sendOperation(const WhiteboardOperation::ref operation) {
-/* boost::shared_ptr<WhiteboardPayload> payload = boost::make_shared<WhiteboardPayload>();
- // payload->setElement(operation->getElement());
- payload->setOperation(operation);
- boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_);
- request->send();*/
+/* void WhiteboardSession::sendOperation(const WhiteboardOperation::ref operation) {
handleSendOperationRequest(operation);
- }
+ }*/
void WhiteboardSession::sendPayload(boost::shared_ptr<WhiteboardPayload> payload) {
boost::shared_ptr<GenericRequest<WhiteboardPayload> > request = boost::make_shared<GenericRequest<WhiteboardPayload> >(IQ::Set, toJID_, payload, router_);
diff --git a/Swiften/Whiteboard/WhiteboardSession.h b/Swiften/Whiteboard/WhiteboardSession.h
index 7fb03e6..1eb76a4 100644
--- a/Swiften/Whiteboard/WhiteboardSession.h
+++ b/Swiften/Whiteboard/WhiteboardSession.h
@@ -28,7 +28,7 @@ namespace Swift {
virtual ~WhiteboardSession();
void handleIncomingAction(boost::shared_ptr<WhiteboardPayload> payload);
void sendElement(const WhiteboardElement::ref element);
- void sendOperation(WhiteboardOperation::ref operation);
+ virtual void sendOperation(WhiteboardOperation::ref operation) = 0;
void cancel();
const JID& getTo() const;
virtual std::string getClientID() const = 0;
@@ -43,7 +43,7 @@ namespace Swift {
private:
virtual void handleIncomingOperation(WhiteboardOperation::ref operation) = 0;
- virtual void handleSendOperationRequest(WhiteboardOperation::ref operation) = 0;
+ //virtual void handleSendOperationRequest(WhiteboardOperation::ref operation) = 0;
protected:
void sendPayload(boost::shared_ptr<WhiteboardPayload> payload);
diff --git a/Swiften/Whiteboard/WhiteboardTransformer.cpp b/Swiften/Whiteboard/WhiteboardTransformer.cpp
index 32e9815..32b1183 100644
--- a/Swiften/Whiteboard/WhiteboardTransformer.cpp
+++ b/Swiften/Whiteboard/WhiteboardTransformer.cpp
@@ -8,7 +8,25 @@
#include <boost/smart_ptr/make_shared.hpp>
namespace Swift {
- std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> WhiteboardTransformer::transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp) {
+ 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);
+ 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 {
+ 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.get());
result.first->setParentID(clientOp->getID());
@@ -17,4 +35,44 @@ namespace Swift {
result.second->setParentID(serverOp->getID());
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.get());
+ result.first->setParentID(clientOp->getID());
+
+ if (clientOp->getPos() == serverOp->getPos()) {
+ result.second = boost::make_shared<WhiteboardUpdateOperation>(*serverOp.get());
+ result.second->setID(clientOp->getID());
+ result.second->setParentID(serverOp->getID());
+ } else {
+ result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp.get());
+ result.second->setParentID(serverOp->getID());
+ }
+ 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.get());
+ result.first->setParentID(clientOp->getID());
+ result.second = boost::make_shared<WhiteboardUpdateOperation>(*clientOp.get());
+ 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.get());
+ result.first->setParentID(clientOp->getID());
+ result.second = boost::make_shared<WhiteboardInsertOperation>(*clientOp.get());
+ result.second->setParentID(serverOp->getID());
+ if (serverOp->getPos() >= clientOp->getPos()) {
+ result.first->setPos(result.first->getPos()+1);
+ }
+ return result;
+ }
}
diff --git a/Swiften/Whiteboard/WhiteboardTransformer.h b/Swiften/Whiteboard/WhiteboardTransformer.h
index 33086d8..0bab4d3 100644
--- a/Swiften/Whiteboard/WhiteboardTransformer.h
+++ b/Swiften/Whiteboard/WhiteboardTransformer.h
@@ -7,11 +7,16 @@
#pragma once
#include <Swiften/Whiteboard/Operations/WhiteboardInsertOperation.h>
+#include <Swiften/Whiteboard/Operations/WhiteboardUpdateOperation.h>
#include <utility>
namespace Swift {
class WhiteboardTransformer {
public:
- static std::pair<WhiteboardInsertOperation::ref, WhiteboardInsertOperation::ref> transform(WhiteboardInsertOperation::ref clientOp, WhiteboardInsertOperation::ref serverOp);
+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);
};
}