Skip to content
Browse files

Moving the ui updating in to the main loop to fix the bug that I ment…

…ion in the TODO, and fix the client/server communication
  • Loading branch information...
1 parent fafde50 commit ce05e8e8b0af2aa00b60d656126fc418d4b8fd9f @fitzgen committed
Showing with 54 additions and 58 deletions.
  1. +2 −2 apply.js
  2. +52 −56 client.js
View
4 apply.js
@@ -27,11 +27,11 @@ define(["./operations"], function (operations) {
if ( doc.indexOf(operations.val(op[i])) !== 0 ) {
throw new TypeError("Expected '" + operations.val(op[i])
+ "' to delete, found '" + doc.slice(0, 10)
- + "...'");
+ + "'");
} else {
doc = doc.slice(operations.val(op[i]).length);
- break;
}
+ break;
default:
throw new TypeError("Unknown operation: "
+ operations.type(op[i]));
View
108 client.js
@@ -29,7 +29,7 @@ define([
msg = outgoing[i];
xform(messages.operation(msg), ops, function (aPrime, bPrime) {
messages.operation(msg, aPrime);
- messages.document(msg, apply(messages.document(msg), aPrime));
+ messages.document(msg, aPrime, apply(aPrime, messages.document(msg)));
messages.revision(msg, messages.revision(msg)+1);
ops = bPrime;
});
@@ -49,7 +49,30 @@ define([
});
}
- function init (outgoing, socket, ui, initialData) {
+ // Might need to start sending client id's back and forth. Don't really want
+ // to have to do a deep equality test on every check here.
+ function isOurOutgoing (msg, outgoing) {
+ var top = outgoing[0],
+ topOps = messages.operation(top),
+ msgOps = messages.operation(msg),
+ i = 0,
+ len = msgOps.length;
+ if ( messages.id(msg) !== messages.id(top) ) {
+ return false;
+ }
+ if ( messages.revision(msg) !== messages.revision(top) ) {
+ return false;
+ }
+ if ( len !== topOps.length ) {
+ return false;
+ }
+ if ( topOps.join() !== msgOps.join() ) {
+ return false;
+ }
+ return true;
+ }
+
+ function init (outgoing, incoming, socket, ui, initialData) {
var previousDoc = messages.document(initialData),
previousRevision = messages.revision(initialData),
id = messages.id(initialData);
@@ -60,6 +83,7 @@ define([
var msg,
oldOutgoingLength = outgoing.length,
uiDoc = ui.getDocument();
+
if ( uiDoc !== previousDoc ) {
msg = {};
messages.operation(msg, operations.operation(previousDoc, uiDoc));
@@ -69,46 +93,42 @@ define([
outgoing.push(msg);
previousDoc = uiDoc;
+ }
- if ( oldOutgoingLength === 0 ) {
- socket.send({
- type: "update",
- data: outgoing[0]
- });
+ while ( (msg = incoming.shift()) ) {
+ if ( outgoing.length && isOurOutgoing(msg, outgoing) ) {
+ outgoing.shift();
+ } else {
+ // TODO: need to handle cursor selection and index
+ xformEach(outgoing, messages.operation(msg));
+ previousRevision++;
+
+ // TODO: cursor position
+ if ( outgoing.length ) {
+ ui.update(previousDoc = messages.document(outgoing[outgoing.length-1]));
+ } else {
+ ui.update(previousDoc = messages.document(msg));
+ }
}
}
+
+ if ( outgoing.length ) {
+ socket.send({
+ type: "update",
+ data: outgoing[0]
+ });
+ }
+
setTimeout(loop, 1000);
}
setTimeout(loop, 10);
}
- // Might need to start sending client id's back and forth. Don't really want
- // to have to do a deep equality test on every check here.
- function isOurOutgoing (msg, outgoing) {
- var top = outgoing[0],
- topOps = messages.operation(top),
- msgOps = messages.operation(msg),
- i = 0,
- len = msgOps.length;
- if ( messages.id(msg) !== messages.id(top) ) {
- return false;
- }
- if ( messages.revision(msg) !== messages.revision(top) ) {
- return false;
- }
- if ( len !== topOps.length ) {
- return false;
- }
- if ( topOps.join() !== msgOps.join() ) {
- return false;
- }
- return true;
- }
-
return {
OTDocument: function (opts) {
var outgoing = [],
+ incoming = [],
socket = opts.socket || error("socket is required"),
ui = opts.ui || error("ui is required"),
docId = opts.id,
@@ -116,43 +136,19 @@ define([
connect(socket, docId);
- // TODO: what happens if we receive an update message from the
- // server and we update the client and they lose what they were just
- // typeing because we havent saved the operations in the outgoing
- // buffer yet? Do I need to merge the main loop and handling of
- // socket messages? Maybe just have the socket's receive handler
- // queue events in an inbox and have the main loop process one
- // change that the client is creating, then one message from the
- // inbox.
-
socket.onMessage(function (event) {
- var msg;
-
switch ( event.type ) {
case "connect":
if ( ! initialized ) {
- init(outgoing, socket, ui, event.data);
+ init(outgoing, incoming, socket, ui, event.data);
} else {
error("Already initialized");
}
break;
case "update":
- msg = event.data;
- if ( outgoing.length && isOurOutgoing(msg, outgoing) ) {
- outgoing.shift();
- } else {
- // TODO: need to handle cursor selection and index
- xformEach(outgoing, messages.operation(msg));
-
- // TODO: cursor position
- if ( outgoing.length ) {
- ui.update(messages.document(outgoing[outgoing.length-1]));
- } else {
- ui.update(messages.document(msg));
- }
- }
+ incoming.push(event.data);
break;
default:

0 comments on commit ce05e8e

Please sign in to comment.
Something went wrong with that request. Please try again.