summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2023-01-29 17:54:14 +0100
committerRoland Reichwein <mail@reichwein.it>2023-01-29 17:54:14 +0100
commitb2f3b566c0c0edd41b0314fcbf516a3d7876e14b (patch)
tree1cebf349b746ae606354733e9464581d530fb5e7
parent32b5b50dacb1bfc02a0baef0eda47df8d5f2be37 (diff)
Fix concurrent edit, tests
-rw-r--r--diff.cpp12
-rw-r--r--diff.h2
-rw-r--r--html/whiteboard.js19
-rw-r--r--tests/test-diff.cpp32
-rw-r--r--whiteboard.cpp12
5 files changed, 68 insertions, 9 deletions
diff --git a/diff.cpp b/diff.cpp
index ea9b04e..85d3167 100644
--- a/diff.cpp
+++ b/diff.cpp
@@ -21,9 +21,10 @@ std::string Diff::apply(const std::string& old_version) const
{
std::string result{old_version};
- result.erase(m_pos0, m_pos1 - m_pos0);
-
- result.insert(m_pos0, m_data);
+ if (m_pos0 <= m_pos1 && m_pos1 <= old_version.size()) {
+ result.erase(m_pos0, m_pos1 - m_pos0);
+ result.insert(m_pos0, m_data);
+ }
return result;
}
@@ -143,6 +144,11 @@ void Diff::create(const std::string& xml)
create(ptree);
}
+bool Diff::empty() const
+{
+ return m_pos0 == m_pos1 && m_data.empty();
+}
+
boost::property_tree::ptree Diff::get_structure() const
{
pt::ptree ptree;
diff --git a/diff.h b/diff.h
index 09d0936..5c2c335 100644
--- a/diff.h
+++ b/diff.h
@@ -19,6 +19,8 @@ public:
std::string apply(const std::string& old_version) const;
+ bool empty() const;
+
boost::property_tree::ptree get_structure() const;
std::string get_xml() const;
diff --git a/html/whiteboard.js b/html/whiteboard.js
index a6dc089..b11dc96 100644
--- a/html/whiteboard.js
+++ b/html/whiteboard.js
@@ -4,6 +4,7 @@ function init() {
}
var revision;
+var modify_in_progress = 0;
var baseline = ""; // data contents relating to revision, acknowledged by server
var baseline_candidate = ""; // will become baseline, after ack by server
@@ -51,7 +52,7 @@ function on_getfile(data, rev, pos)
function on_getdiff(diff, rev, pos)
{
if (rev != revision + 1)
- alert("Revision skipped: " + rev + " after " + revision);
+ console.log("Revision skipped on diff receive: " + rev + " after " + revision);
var board = document.getElementById("board");
@@ -95,8 +96,12 @@ function on_version(version)
function on_modify_ack(rev)
{
+ if (rev != revision + 1)
+ console.log("Revision skipped on published local change: " + rev + " after " + revision);
+
revision = rev;
baseline = baseline_candidate;
+ modify_in_progress = 0;
}
function on_message(e) {
@@ -228,6 +233,13 @@ function redirect_to_new_page()
// local change done
function on_input()
{
+ if (modify_in_progress == 1) {
+ console.log("Deferring on_input handler by 100ms");
+ setTimeout(function(){on_input();}, 100); // re-try after 100ms
+ return;
+ }
+ modify_in_progress = 1;
+
var parser = new DOMParser();
var xmlDocument = parser.parseFromString("<request></request>", "text/xml");
@@ -243,6 +255,11 @@ function on_input()
baseline_candidate = document.getElementById("board").value;
+ if (baseline == baseline_candidate) {
+ modify_in_progress = 0;
+ return;
+ }
+
var revisionElement = xmlDocument.createElement("baserev");
revisionElement.appendChild(document.createTextNode(revision));
requestElement.appendChild(revisionElement);
diff --git a/tests/test-diff.cpp b/tests/test-diff.cpp
index 1625716..d09c58e 100644
--- a/tests/test-diff.cpp
+++ b/tests/test-diff.cpp
@@ -147,6 +147,38 @@ TEST_F(DiffTest, constructor)
Diff d{"baaaab", "baab"};
EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>3</end><data/></diff>");
}
+ {
+ Diff d{"baaaab", "baaaaaaab"};
+ EXPECT_EQ(d.get_xml(), "<diff><start>1</start><end>1</end><data>aaa</data></diff>");
+ }
+}
+
+TEST_F(DiffTest, empty)
+{
+ {
+ Diff d;
+ EXPECT_TRUE(d.empty());
+ }
+
+ {
+ Diff d{"<diff><start>1</start><end>3</end><data/></diff>"};
+ EXPECT_FALSE(d.empty());
+ }
+
+ {
+ Diff d{"<diff><start>1</start><end>1</end><data/></diff>"};
+ EXPECT_TRUE(d.empty());
+ }
+
+ {
+ Diff d{"<diff><start>1</start><end>1</end><data>abc</data></diff>"};
+ EXPECT_FALSE(d.empty());
+ }
+
+ {
+ Diff d{"<diff><start>0</start><end>0</end><data/></diff>"};
+ EXPECT_TRUE(d.empty());
+ }
}
TEST_F(DiffTest, diff_create)
diff --git a/whiteboard.cpp b/whiteboard.cpp
index fcfdca8..8736726 100644
--- a/whiteboard.cpp
+++ b/whiteboard.cpp
@@ -167,12 +167,14 @@ std::string Whiteboard::handle_request(Whiteboard::connection& c, const std::str
pt::ptree ptree;
ptree.put_child("diff", xml.get_child("request.diff"));
Diff d{ptree};
- std::string data {m_storage->getDocument(id)};
- data = d.apply(data);
+ if (!d.empty()) {
+ std::string data {m_storage->getDocument(id)};
+ data = d.apply(data);
- m_storage->setDocument(id, data);
- m_registry.setId(c, id);
- notify_other_connections_diff(c, id, d);
+ m_storage->setDocument(id, data);
+ m_registry.setId(c, id);
+ notify_other_connections_diff(c, id, d);
+ }
int pos {xml.get<int>("request.pos")};
if (m_storage->getCursorPos(id) != pos) {