added support to use existing user ids! Fixes #23
This commit is contained in:
parent
a9c2ec6ba0
commit
dc3c6a5d42
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -154,7 +154,7 @@ module.exports = {
|
|||||||
this.send(user, {
|
this.send(user, {
|
||||||
sync_step: "getHB",
|
sync_step: "getHB",
|
||||||
send_again: "true",
|
send_again: "true",
|
||||||
data: []
|
data: this.getStateVector()
|
||||||
});
|
});
|
||||||
if (!this.sent_hb_to_all_users) {
|
if (!this.sent_hb_to_all_users) {
|
||||||
this.sent_hb_to_all_users = true;
|
this.sent_hb_to_all_users = true;
|
||||||
@ -184,7 +184,7 @@ module.exports = {
|
|||||||
this.send(user, {
|
this.send(user, {
|
||||||
sync_step: "getHB",
|
sync_step: "getHB",
|
||||||
send_again: "true",
|
send_again: "true",
|
||||||
data: []
|
data: this.getStateVector()
|
||||||
});
|
});
|
||||||
hb = this.getHB([]).hb;
|
hb = this.getHB([]).hb;
|
||||||
_hb = [];
|
_hb = [];
|
||||||
@ -221,8 +221,14 @@ module.exports = {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
whenReceivedStateVector: function(f) {
|
||||||
|
if (this.when_received_state_vector_listeners == null) {
|
||||||
|
this.when_received_state_vector_listeners = [];
|
||||||
|
}
|
||||||
|
return this.when_received_state_vector_listeners.push(f);
|
||||||
|
},
|
||||||
receiveMessage: function(sender, res) {
|
receiveMessage: function(sender, res) {
|
||||||
var _hb, data, f, hb, i, j, len, len1, o, ref, results, sendApplyHB, send_again;
|
var _hb, data, f, hb, i, j, k, len, len1, len2, o, ref, ref1, results, sendApplyHB, send_again;
|
||||||
if (res.sync_step == null) {
|
if (res.sync_step == null) {
|
||||||
ref = this.receive_handlers;
|
ref = this.receive_handlers;
|
||||||
results = [];
|
results = [];
|
||||||
@ -236,6 +242,14 @@ module.exports = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (res.sync_step === "getHB") {
|
if (res.sync_step === "getHB") {
|
||||||
|
if (this.when_received_state_vector_listeners != null) {
|
||||||
|
ref1 = this.when_received_state_vector_listeners;
|
||||||
|
for (j = 0, len1 = ref1.length; j < len1; j++) {
|
||||||
|
f = ref1[j];
|
||||||
|
f.call(this, res.data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete this.when_received_state_vector_listeners;
|
||||||
data = this.getHB(res.data);
|
data = this.getHB(res.data);
|
||||||
hb = data.hb;
|
hb = data.hb;
|
||||||
_hb = [];
|
_hb = [];
|
||||||
@ -252,8 +266,8 @@ module.exports = {
|
|||||||
};
|
};
|
||||||
})(this);
|
})(this);
|
||||||
}
|
}
|
||||||
for (j = 0, len1 = hb.length; j < len1; j++) {
|
for (k = 0, len2 = hb.length; k < len2; k++) {
|
||||||
o = hb[j];
|
o = hb[k];
|
||||||
_hb.push(o);
|
_hb.push(o);
|
||||||
if (_hb.length > 10) {
|
if (_hb.length > 10) {
|
||||||
sendApplyHB({
|
sendApplyHB({
|
||||||
@ -271,10 +285,10 @@ module.exports = {
|
|||||||
send_again = (function(_this) {
|
send_again = (function(_this) {
|
||||||
return function(sv) {
|
return function(sv) {
|
||||||
return function() {
|
return function() {
|
||||||
var k, len2;
|
var l, len3;
|
||||||
hb = _this.getHB(sv).hb;
|
hb = _this.getHB(sv).hb;
|
||||||
for (k = 0, len2 = hb.length; k < len2; k++) {
|
for (l = 0, len3 = hb.length; l < len3; l++) {
|
||||||
o = hb[k];
|
o = hb[l];
|
||||||
_hb.push(o);
|
_hb.push(o);
|
||||||
if (_hb.length > 10) {
|
if (_hb.length > 10) {
|
||||||
_this.send(sender, {
|
_this.send(sender, {
|
||||||
|
@ -16,30 +16,26 @@ HistoryBuffer = (function() {
|
|||||||
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
setTimeout(this.emptyGarbage, this.garbageCollectTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryBuffer.prototype.resetUserId = function(id) {
|
HistoryBuffer.prototype.setUserId = function(user_id1, state_vector) {
|
||||||
var o, o_name, own;
|
var base, buff, counter_diff, name, o, o_name, ref;
|
||||||
own = this.buffer[this.user_id];
|
this.user_id = user_id1;
|
||||||
if (own != null) {
|
if ((base = this.buffer)[name = this.user_id] == null) {
|
||||||
for (o_name in own) {
|
base[name] = [];
|
||||||
o = own[o_name];
|
|
||||||
if (o.uid.creator != null) {
|
|
||||||
o.uid.creator = id;
|
|
||||||
}
|
|
||||||
if (o.uid.alt != null) {
|
|
||||||
o.uid.alt.creator = id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (this.buffer[id] != null) {
|
|
||||||
throw new Error("You are re-assigning an old user id - this is not (yet) possible!");
|
|
||||||
}
|
|
||||||
this.buffer[id] = own;
|
|
||||||
delete this.buffer[this.user_id];
|
|
||||||
}
|
}
|
||||||
if (this.operation_counter[this.user_id] != null) {
|
buff = this.buffer[this.user_id];
|
||||||
this.operation_counter[id] = this.operation_counter[this.user_id];
|
counter_diff = state_vector[this.user_id] || 0;
|
||||||
delete this.operation_counter[this.user_id];
|
if (this.buffer._temp != null) {
|
||||||
|
ref = this.buffer._temp;
|
||||||
|
for (o_name in ref) {
|
||||||
|
o = ref[o_name];
|
||||||
|
o.uid.creator = this.user_id;
|
||||||
|
o.uid.op_number += counter_diff;
|
||||||
|
buff[o.uid.op_number] = o;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this.user_id = id;
|
this.operation_counter[this.user_id] = (this.operation_counter._temp || 0) + counter_diff;
|
||||||
|
delete this.operation_counter._temp;
|
||||||
|
return delete this.buffer._temp;
|
||||||
};
|
};
|
||||||
|
|
||||||
HistoryBuffer.prototype.emptyGarbage = function() {
|
HistoryBuffer.prototype.emptyGarbage = function() {
|
||||||
@ -243,15 +239,13 @@ HistoryBuffer = (function() {
|
|||||||
if ((base = this.operation_counter)[name = o.uid.creator] == null) {
|
if ((base = this.operation_counter)[name = o.uid.creator] == null) {
|
||||||
base[name] = 0;
|
base[name] = 0;
|
||||||
}
|
}
|
||||||
if (o.uid.creator !== this.getUserId()) {
|
if (o.uid.op_number === this.operation_counter[o.uid.creator]) {
|
||||||
if (o.uid.op_number === this.operation_counter[o.uid.creator]) {
|
this.operation_counter[o.uid.creator]++;
|
||||||
this.operation_counter[o.uid.creator]++;
|
|
||||||
}
|
|
||||||
while (this.buffer[o.uid.creator][this.operation_counter[o.uid.creator]] != null) {
|
|
||||||
this.operation_counter[o.uid.creator]++;
|
|
||||||
}
|
|
||||||
return void 0;
|
|
||||||
}
|
}
|
||||||
|
while (this.buffer[o.uid.creator][this.operation_counter[o.uid.creator]] != null) {
|
||||||
|
this.operation_counter[o.uid.creator]++;
|
||||||
|
}
|
||||||
|
return void 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
return HistoryBuffer;
|
return HistoryBuffer;
|
||||||
|
@ -10,15 +10,15 @@ adaptConnector = require("./ConnectorAdapter");
|
|||||||
|
|
||||||
createY = function(connector) {
|
createY = function(connector) {
|
||||||
var HB, ct, engine, model, ops, ops_manager, user_id;
|
var HB, ct, engine, model, ops, ops_manager, user_id;
|
||||||
user_id = null;
|
|
||||||
if (connector.user_id != null) {
|
if (connector.user_id != null) {
|
||||||
user_id = connector.user_id;
|
user_id = connector.user_id;
|
||||||
} else {
|
} else {
|
||||||
user_id = "_temp";
|
user_id = "_temp";
|
||||||
connector.on_user_id_set = function(id) {
|
connector.when_received_state_vector_listeners = [
|
||||||
user_id = id;
|
function(state_vector) {
|
||||||
return HB.resetUserId(id);
|
return HB.setUserId(this.user_id, state_vector);
|
||||||
};
|
}
|
||||||
|
];
|
||||||
}
|
}
|
||||||
HB = new HistoryBuffer(user_id);
|
HB = new HistoryBuffer(user_id);
|
||||||
ops_manager = structured_ops_uninitialized(HB, this.constructor);
|
ops_manager = structured_ops_uninitialized(HB, this.constructor);
|
||||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
20152
build/test/selections-test.js
Normal file
20152
build/test/selections-test.js
Normal file
File diff suppressed because one or more lines are too long
18741
build/test/text-test.js
Normal file
18741
build/test/text-test.js
Normal file
File diff suppressed because one or more lines are too long
@ -102,7 +102,7 @@ module.exports =
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Execute a function _when_ we are connected. If not connected, wait until connected.
|
# Execute a function _when_ we are connected. If not connected, wait until connected.
|
||||||
# @param f {Function} Will be executed on the PeerJs-Connector context.
|
# @param f {Function} Will be executed on the Connector context.
|
||||||
#
|
#
|
||||||
whenSynced: (args)->
|
whenSynced: (args)->
|
||||||
if args.constructor is Function
|
if args.constructor is Function
|
||||||
@ -143,7 +143,7 @@ module.exports =
|
|||||||
@send user,
|
@send user,
|
||||||
sync_step: "getHB"
|
sync_step: "getHB"
|
||||||
send_again: "true"
|
send_again: "true"
|
||||||
data: [] # @getStateVector()
|
data: @getStateVector()
|
||||||
if not @sent_hb_to_all_users
|
if not @sent_hb_to_all_users
|
||||||
@sent_hb_to_all_users = true
|
@sent_hb_to_all_users = true
|
||||||
|
|
||||||
@ -171,7 +171,7 @@ module.exports =
|
|||||||
@send user,
|
@send user,
|
||||||
sync_step: "getHB"
|
sync_step: "getHB"
|
||||||
send_again: "true"
|
send_again: "true"
|
||||||
data: []
|
data: @getStateVector()
|
||||||
hb = @getHB([]).hb
|
hb = @getHB([]).hb
|
||||||
_hb = []
|
_hb = []
|
||||||
for o in hb
|
for o in hb
|
||||||
@ -199,6 +199,12 @@ module.exports =
|
|||||||
delete @compute_when_synced
|
delete @compute_when_synced
|
||||||
null
|
null
|
||||||
|
|
||||||
|
# executed when the a state_vector is received. listener will be called only once!
|
||||||
|
whenReceivedStateVector: (f)->
|
||||||
|
@when_received_state_vector_listeners ?= []
|
||||||
|
@when_received_state_vector_listeners.push f
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# You received a raw message, and you know that it is intended for to Yjs. Then call this function.
|
# You received a raw message, and you know that it is intended for to Yjs. Then call this function.
|
||||||
#
|
#
|
||||||
@ -210,6 +216,12 @@ module.exports =
|
|||||||
if sender is @user_id
|
if sender is @user_id
|
||||||
return
|
return
|
||||||
if res.sync_step is "getHB"
|
if res.sync_step is "getHB"
|
||||||
|
# call listeners
|
||||||
|
if @when_received_state_vector_listeners?
|
||||||
|
for f in @when_received_state_vector_listeners
|
||||||
|
f.call this, res.data
|
||||||
|
delete @when_received_state_vector_listeners
|
||||||
|
|
||||||
data = @getHB(res.data)
|
data = @getHB(res.data)
|
||||||
hb = data.hb
|
hb = data.hb
|
||||||
_hb = []
|
_hb = []
|
||||||
|
@ -22,22 +22,32 @@ class HistoryBuffer
|
|||||||
@reserved_identifier_counter = 0
|
@reserved_identifier_counter = 0
|
||||||
setTimeout @emptyGarbage, @garbageCollectTimeout
|
setTimeout @emptyGarbage, @garbageCollectTimeout
|
||||||
|
|
||||||
resetUserId: (id)->
|
# At the beginning (when the user id was not assigned yet),
|
||||||
own = @buffer[@user_id]
|
# the operations are added to buffer._temp. When you finally get your user id,
|
||||||
if own?
|
# the operations are copies from buffer._temp to buffer[id]. Furthermore, when buffer[id] does already contain operations
|
||||||
for o_name,o of own
|
# (because of a previous session), the uid.op_numbers of the operations have to be reassigned.
|
||||||
if o.uid.creator?
|
# This is what this function does. It adds them to buffer[id],
|
||||||
o.uid.creator = id
|
# and assigns them the correct uid.op_number and uid.creator
|
||||||
if o.uid.alt?
|
setUserId: (@user_id, state_vector)->
|
||||||
o.uid.alt.creator = id
|
@buffer[@user_id] ?= []
|
||||||
if @buffer[id]?
|
buff = @buffer[@user_id]
|
||||||
throw new Error "You are re-assigning an old user id - this is not (yet) possible!"
|
|
||||||
@buffer[id] = own
|
# we assumed that we started with counter = 0.
|
||||||
delete @buffer[@user_id]
|
# when we receive tha state_vector, and actually have
|
||||||
if @operation_counter[@user_id]?
|
# counter = 10. Then we have to add 10 to every op_counter
|
||||||
@operation_counter[id] = @operation_counter[@user_id]
|
counter_diff = state_vector[@user_id] or 0
|
||||||
delete @operation_counter[@user_id]
|
|
||||||
@user_id = id
|
if @buffer._temp?
|
||||||
|
for o_name,o of @buffer._temp
|
||||||
|
o.uid.creator = @user_id
|
||||||
|
o.uid.op_number += counter_diff
|
||||||
|
buff[o.uid.op_number] = o
|
||||||
|
|
||||||
|
@operation_counter[@user_id] = (@operation_counter._temp or 0) + counter_diff
|
||||||
|
|
||||||
|
delete @operation_counter._temp
|
||||||
|
delete @buffer._temp
|
||||||
|
|
||||||
|
|
||||||
emptyGarbage: ()=>
|
emptyGarbage: ()=>
|
||||||
for o in @garbage
|
for o in @garbage
|
||||||
@ -207,17 +217,11 @@ class HistoryBuffer
|
|||||||
#
|
#
|
||||||
addToCounter: (o)->
|
addToCounter: (o)->
|
||||||
@operation_counter[o.uid.creator] ?= 0
|
@operation_counter[o.uid.creator] ?= 0
|
||||||
if o.uid.creator isnt @getUserId()
|
# TODO: check if operations are send in order
|
||||||
# TODO: check if operations are send in order
|
if o.uid.op_number is @operation_counter[o.uid.creator]
|
||||||
if o.uid.op_number is @operation_counter[o.uid.creator]
|
@operation_counter[o.uid.creator]++
|
||||||
@operation_counter[o.uid.creator]++
|
while @buffer[o.uid.creator][@operation_counter[o.uid.creator]]?
|
||||||
while @buffer[o.uid.creator][@operation_counter[o.uid.creator]]?
|
@operation_counter[o.uid.creator]++
|
||||||
@operation_counter[o.uid.creator]++
|
undefined
|
||||||
undefined
|
|
||||||
|
|
||||||
#if @operation_counter[o.uid.creator] isnt (o.uid.op_number + 1)
|
|
||||||
#console.log (@operation_counter[o.uid.creator] - (o.uid.op_number + 1))
|
|
||||||
#console.log o
|
|
||||||
#throw new Error "You don't receive operations in the proper order. Try counting like this 0,1,2,3,4,.. ;)"
|
|
||||||
|
|
||||||
module.exports = HistoryBuffer
|
module.exports = HistoryBuffer
|
||||||
|
@ -6,14 +6,13 @@ Engine = require "./Engine"
|
|||||||
adaptConnector = require "./ConnectorAdapter"
|
adaptConnector = require "./ConnectorAdapter"
|
||||||
|
|
||||||
createY = (connector)->
|
createY = (connector)->
|
||||||
user_id = null
|
|
||||||
if connector.user_id?
|
if connector.user_id?
|
||||||
user_id = connector.user_id # TODO: change to getUniqueId()
|
user_id = connector.user_id # TODO: change to getUniqueId()
|
||||||
else
|
else
|
||||||
user_id = "_temp"
|
user_id = "_temp"
|
||||||
connector.on_user_id_set = (id)->
|
connector.when_received_state_vector_listeners = [(state_vector)->
|
||||||
user_id = id
|
HB.setUserId this.user_id, state_vector
|
||||||
HB.resetUserId id
|
]
|
||||||
HB = new HistoryBuffer user_id
|
HB = new HistoryBuffer user_id
|
||||||
ops_manager = structured_ops_uninitialized HB, this.constructor
|
ops_manager = structured_ops_uninitialized HB, this.constructor
|
||||||
ops = ops_manager.operations
|
ops = ops_manager.operations
|
||||||
|
Loading…
x
Reference in New Issue
Block a user