Operation can now save static content/Operations

This commit is contained in:
Kevin Jahns 2015-04-19 18:54:03 +02:00
parent b02662c36e
commit 2a78cdba48
14 changed files with 1243 additions and 1025 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -7,7 +7,8 @@ module.exports = function() {
ops = {};
execution_listener = [];
ops.Operation = (function() {
function Operation(custom_type, uid) {
function Operation(custom_type, uid, content, content_operations) {
var name, op;
if (custom_type != null) {
this.custom_type = custom_type;
}
@ -17,10 +18,61 @@ module.exports = function() {
if (uid != null) {
this.uid = uid;
}
if (content === void 0) {
} else if ((content != null) && (content.creator != null)) {
this.saveOperation('content', content);
} else {
this.content = content;
}
if (content_operations != null) {
this.content_operations = {};
for (name in content_operations) {
op = content_operations[name];
this.saveOperation(name, op, 'content_operations');
}
}
}
Operation.prototype.type = "Operation";
Operation.prototype.getContent = function(name) {
var content, n, ref, ref1, v;
if (this.content != null) {
if (this.content.getCustomType != null) {
return this.content.getCustomType();
} else if (this.content.constructor === Object) {
if (name != null) {
if (this.content[name] != null) {
return this.content[name];
} else {
return this.content_operations[name].getCustomType();
}
} else {
content = {};
ref = this.content;
for (n in ref) {
v = ref[n];
content[n] = v;
}
if (this.content_operations != null) {
ref1 = this.content_operations;
for (n in ref1) {
v = ref1[n];
v = v.getCustomType();
content[n] = v;
}
}
return content;
}
} else {
return this.content;
}
} else {
return this.content;
}
};
Operation.prototype.retrieveSub = function() {
throw new Error("sub properties are not enable on this operation type!");
};
@ -124,34 +176,22 @@ module.exports = function() {
Operation.prototype.execute = function() {
var j, l, len;
this.is_executed = true;
if (this.uid == null) {
this.uid = this.HB.getNextOperationIdentifier();
}
if (this.uid.noOperation == null) {
this.HB.addOperation(this);
for (j = 0, len = execution_listener.length; j < len; j++) {
l = execution_listener[j];
l(this._encode());
if (this.validateSavedOperations()) {
this.is_executed = true;
if (this.uid == null) {
this.uid = this.HB.getNextOperationIdentifier();
}
}
return this;
};
Operation.prototype._encode = function(json) {
if (json == null) {
json = {};
}
json.type = this.type;
json.uid = this.getUid();
if (this.custom_type != null) {
if (this.custom_type.constructor === String) {
json.custom_type = this.custom_type;
} else {
json.custom_type = this.custom_type._name;
if (this.uid.noOperation == null) {
this.HB.addOperation(this);
for (j = 0, len = execution_listener.length; j < len; j++) {
l = execution_listener[j];
l(this._encode());
}
}
return this;
} else {
return false;
}
return json;
};
Operation.prototype.saveOperation = function(name, op, base) {
@ -159,6 +199,9 @@ module.exports = function() {
if (base == null) {
base = "this";
}
if ((op != null) && (op._getModel != null)) {
op = op._getModel(this.custom_types, this.operations);
}
if (op == null) {
} else if ((op.execute != null) || !((op.op_number != null) && (op.creator != null))) {
@ -188,7 +231,7 @@ module.exports = function() {
Operation.prototype.validateSavedOperations = function() {
var base, base_name, dest, j, last_path, len, name, op, op_uid, path, paths, ref, success, uninstantiated;
uninstantiated = {};
success = this;
success = true;
ref = this.unchecked;
for (base_name in ref) {
base = ref[base_name];
@ -217,11 +260,13 @@ module.exports = function() {
}
}
}
delete this.unchecked;
if (!success) {
this.unchecked = uninstantiated;
return false;
} else {
delete this.unchecked;
return this;
}
return success;
};
Operation.prototype.getCustomType = function() {
@ -243,6 +288,40 @@ module.exports = function() {
}
};
Operation.prototype._encode = function(json) {
var n, o, operations, ref, ref1;
if (json == null) {
json = {};
}
json.type = this.type;
json.uid = this.getUid();
if (this.custom_type != null) {
if (this.custom_type.constructor === String) {
json.custom_type = this.custom_type;
} else {
json.custom_type = this.custom_type._name;
}
}
if (((ref = this.content) != null ? ref.getUid : void 0) != null) {
json.content = this.content.getUid();
} else {
json.content = this.content;
}
if (this.content_operations != null) {
operations = {};
ref1 = this.content_operations;
for (n in ref1) {
o = ref1[n];
if (o._getModel != null) {
o = o._getModel(this.custom_types, this.operations);
}
operations[n] = o.getUid();
}
json.content_operations = operations;
}
return json;
};
return Operation;
})();
@ -289,21 +368,6 @@ module.exports = function() {
extend(Insert, superClass);
function Insert(custom_type, content, content_operations, parent, uid, prev_cl, next_cl, origin) {
var name, op;
if (content === void 0) {
} else if ((content != null) && (content.creator != null)) {
this.saveOperation('content', content);
} else {
this.content = content;
}
if (content_operations != null) {
this.content_operations = {};
for (name in content_operations) {
op = content_operations[name];
this.saveOperation(name, op, 'content_operations');
}
}
this.saveOperation('parent', parent);
this.saveOperation('prev_cl', prev_cl);
this.saveOperation('next_cl', next_cl);
@ -312,37 +376,13 @@ module.exports = function() {
} else {
this.saveOperation('origin', prev_cl);
}
Insert.__super__.constructor.call(this, custom_type, uid);
Insert.__super__.constructor.call(this, custom_type, uid, content, content_operations);
}
Insert.prototype.type = "Insert";
Insert.prototype.val = function() {
var content, n, ref, ref1, v;
if (this.content != null) {
if (this.content.getCustomType != null) {
return this.content.getCustomType();
} else if (this.content.constructor === Object) {
content = {};
ref = this.content;
for (n in ref) {
v = ref[n];
content[n] = v;
}
if (this.content_operations != null) {
ref1 = this.content_operations;
for (n in ref1) {
v = ref1[n];
content[n] = v;
}
}
return content;
} else {
return this.content;
}
} else {
return this.content;
}
return this.getContent();
};
Insert.prototype.getNext = function(i) {
@ -524,7 +564,6 @@ module.exports = function() {
};
Insert.prototype._encode = function(json) {
var n, o, operations, ref, ref1;
if (json == null) {
json = {};
}
@ -536,20 +575,6 @@ module.exports = function() {
json.origin = this.origin.getUid();
}
json.parent = this.parent.getUid();
if (((ref = this.content) != null ? ref.getUid : void 0) != null) {
json.content = this.content.getUid();
} else {
json.content = JSON.stringify(this.content);
}
if (this.content_operations != null) {
operations = {};
ref1 = this.content_operations;
for (n in ref1) {
o = ref1[n];
operations[n] = o.getUid();
}
json.content_operations = operations;
}
return Insert.__super__._encode.call(this, json);
};
@ -559,9 +584,6 @@ module.exports = function() {
ops.Insert.parse = function(json) {
var content, content_operations, next, origin, parent, prev, uid;
content = json['content'], content_operations = json['content_operations'], uid = json['uid'], prev = json['prev'], next = json['next'], origin = json['origin'], parent = json['parent'];
if (typeof content === "string") {
content = JSON.parse(content);
}
return new this(null, content, content_operations, parent, uid, prev, next, origin);
};
ops.Delimiter = (function(superClass) {

View File

@ -11,9 +11,11 @@ module.exports = function() {
ops.MapManager = (function(superClass) {
extend(MapManager, superClass);
function MapManager(custom_type, uid) {
function MapManager(custom_type, uid, content, content_operations) {
this._map = {};
MapManager.__super__.constructor.call(this, custom_type, uid);
console.log("delete this ...");
this.constructed_with = [custom_type, content, content_operations];
MapManager.__super__.constructor.call(this, custom_type, uid, content, content_operations);
}
MapManager.prototype.type = "MapManager";
@ -109,20 +111,20 @@ module.exports = function() {
})(ops.Operation);
ops.MapManager.parse = function(json) {
var custom_type, uid;
uid = json['uid'], custom_type = json['custom_type'];
return new this(custom_type, uid);
var content, content_operations, custom_type, uid;
uid = json['uid'], custom_type = json['custom_type'], content = json['content'], content_operations = json['content_operations'];
return new this(custom_type, uid, content, content_operations);
};
ops.ListManager = (function(superClass) {
extend(ListManager, superClass);
function ListManager(custom_type, uid) {
function ListManager(custom_type, uid, content, content_operations) {
this.beginning = new ops.Delimiter(void 0, void 0);
this.end = new ops.Delimiter(this.beginning, void 0);
this.beginning.next_cl = this.end;
this.beginning.execute();
this.end.execute();
ListManager.__super__.constructor.call(this, custom_type, uid);
ListManager.__super__.constructor.call(this, custom_type, uid, content, content_operations);
}
ListManager.prototype.type = "ListManager";
@ -359,9 +361,9 @@ module.exports = function() {
})(ops.Operation);
ops.ListManager.parse = function(json) {
var custom_type, uid;
uid = json['uid'], custom_type = json['custom_type'];
return new this(custom_type, uid);
var content, content_operations, custom_type, uid;
uid = json['uid'], custom_type = json['custom_type'], content = json['content'], content_operations = json['content_operations'];
return new this(custom_type, uid, content, content_operations);
};
ops.Composition = (function(superClass) {
extend(Composition, superClass);
@ -369,8 +371,6 @@ module.exports = function() {
function Composition(custom_type, _composition_value, composition_value_operations, uid, tmp_composition_ref) {
var n, o;
this._composition_value = _composition_value;
console.log("delete this ...");
this.constructed_with = [custom_type, this._composition_value, composition_value_operations, uid, tmp_composition_ref];
Composition.__super__.constructor.call(this, custom_type, uid);
if (tmp_composition_ref != null) {
this.tmp_composition_ref = tmp_composition_ref;

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

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

View File

@ -22,7 +22,7 @@ module.exports = ()->
# @param {Object} uid A unique identifier.
# If uid is undefined, a new uid will be created before at the end of the execution sequence
#
constructor: (custom_type, uid)->
constructor: (custom_type, uid, content, content_operations)->
if custom_type?
@custom_type = custom_type
@is_deleted = false
@ -31,8 +31,44 @@ module.exports = ()->
if uid?
@uid = uid
# see encode to see, why we are doing it this way
if content is undefined
# nop
else if content? and content.creator?
@saveOperation 'content', content
else
@content = content
if content_operations?
@content_operations = {}
for name, op of content_operations
@saveOperation name, op, 'content_operations'
type: "Operation"
getContent: (name)->
if @content?
if @content.getCustomType?
@content.getCustomType()
else if @content.constructor is Object
if name?
if @content[name]?
@content[name]
else
@content_operations[name].getCustomType()
else
content = {}
for n,v of @content
content[n] = v
if @content_operations?
for n,v of @content_operations
v = v.getCustomType()
content[n] = v
content
else
@content
else
@content
retrieveSub: ()->
throw new Error "sub properties are not enable on this operation type!"
@ -137,32 +173,20 @@ module.exports = ()->
# Notify the all the listeners.
#
execute: ()->
@is_executed = true
if not @uid?
# When this operation was created without a uid, then set it here.
# There is only one other place, where this can be done - before an Insertion
# is executed (because we need the creator_id)
@uid = @HB.getNextOperationIdentifier()
if not @uid.noOperation?
@HB.addOperation @
for l in execution_listener
l @_encode()
@
#
# @private
# Encode this operation in such a way that it can be parsed by remote peers.
#
_encode: (json = {})->
json.type = @type
json.uid = @getUid()
if @custom_type?
if @custom_type.constructor is String
json.custom_type = @custom_type
else
json.custom_type = @custom_type._name
json
if @validateSavedOperations()
@is_executed = true
if not @uid?
# When this operation was created without a uid, then set it here.
# There is only one other place, where this can be done - before an Insertion
# is executed (because we need the creator_id)
@uid = @HB.getNextOperationIdentifier()
if not @uid.noOperation?
@HB.addOperation @
for l in execution_listener
l @_encode()
@
else
false
#
# @private
@ -183,7 +207,8 @@ module.exports = ()->
# @param {Operation} op An Operation object
#
saveOperation: (name, op, base = "this")->
if op? and op._getModel?
op = op._getModel(@custom_types, @operations)
#
# Every instance of $Operation must have an $execute function.
# We use duck-typing to check if op is instantiated since there
@ -218,7 +243,7 @@ module.exports = ()->
#
validateSavedOperations: ()->
uninstantiated = {}
success = @
success = true
for base_name, base of @unchecked
for name, op_uid of base
op = @HB.getOperation op_uid
@ -236,10 +261,12 @@ module.exports = ()->
uninstantiated[base_name] ?= {}
uninstantiated[base_name][name] = op_uid
success = false
delete @unchecked
if not success
@unchecked = uninstantiated
success
return false
else
delete @unchecked
return @
getCustomType: ()->
if not @custom_type?
@ -255,6 +282,31 @@ module.exports = ()->
@custom_type._setModel @
@custom_type
#
# @private
# Encode this operation in such a way that it can be parsed by remote peers.
#
_encode: (json = {})->
json.type = @type
json.uid = @getUid()
if @custom_type?
if @custom_type.constructor is String
json.custom_type = @custom_type
else
json.custom_type = @custom_type._name
if @content?.getUid?
json.content = @content.getUid()
else
json.content = @content
if @content_operations?
operations = {}
for n,o of @content_operations
if o._getModel?
o = o._getModel(@custom_types, @operations)
operations[n] = o.getUid()
json.content_operations = operations
json
#
# @nodoc
@ -325,17 +377,6 @@ module.exports = ()->
# @param {Operation} next_cl The successor of this operation in the complete-list (cl)
#
constructor: (custom_type, content, content_operations, parent, uid, prev_cl, next_cl, origin)->
# see encode to see, why we are doing it this way
if content is undefined
# nop
else if content? and content.creator?
@saveOperation 'content', content
else
@content = content
if content_operations?
@content_operations = {}
for name, op of content_operations
@saveOperation name, op, 'content_operations'
@saveOperation 'parent', parent
@saveOperation 'prev_cl', prev_cl
@saveOperation 'next_cl', next_cl
@ -343,26 +384,12 @@ module.exports = ()->
@saveOperation 'origin', origin
else
@saveOperation 'origin', prev_cl
super custom_type, uid
super custom_type, uid, content, content_operations
type: "Insert"
val: ()->
if @content?
if @content.getCustomType?
@content.getCustomType()
else if @content.constructor is Object
content = {}
for n,v of @content
content[n] = v
if @content_operations?
for n,v of @content_operations
content[n] = v
content
else
@content
else
@content
@getContent()
getNext: (i=1)->
n = @
@ -551,15 +578,6 @@ module.exports = ()->
# if not (json.prev? and json.next?)
json.parent = @parent.getUid()
if @content?.getUid?
json.content = @content.getUid()
else
json.content = JSON.stringify @content
if @content_operations?
operations = {}
for n,o of @content_operations
operations[n] = o.getUid()
json.content_operations = operations
super json
ops.Insert.parse = (json)->
@ -572,8 +590,6 @@ module.exports = ()->
'origin' : origin
'parent' : parent
} = json
if typeof content is "string"
content = JSON.parse(content)
new this null, content, content_operations, parent, uid, prev, next, origin
#

View File

@ -13,9 +13,11 @@ module.exports = ()->
#
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
#
constructor: (custom_type, uid)->
constructor: (custom_type, uid, content, content_operations)->
@_map = {}
super custom_type, uid
console.log("delete this ...")
this.constructed_with = [custom_type, content, content_operations] # debug!
super custom_type, uid, content, content_operations
type: "MapManager"
@ -83,8 +85,10 @@ module.exports = ()->
{
'uid' : uid
'custom_type' : custom_type
'content' : content
'content_operations' : content_operations
} = json
new this(custom_type, uid)
new this(custom_type, uid, content, content_operations)
@ -99,13 +103,13 @@ module.exports = ()->
# @param {Object} uid A unique identifier. If uid is undefined, a new uid will be created.
# @param {Delimiter} beginning Reference or Object.
# @param {Delimiter} end Reference or Object.
constructor: (custom_type, uid)->
constructor: (custom_type, uid, content, content_operations)->
@beginning = new ops.Delimiter undefined, undefined
@end = new ops.Delimiter @beginning, undefined
@beginning.next_cl = @end
@beginning.execute()
@end.execute()
super custom_type, uid
super custom_type, uid, content, content_operations
type: "ListManager"
@ -307,12 +311,10 @@ module.exports = ()->
{
'uid' : uid
'custom_type': custom_type
'content' : content
'content_operations' : content_operations
} = json
new this(custom_type, uid)
new this(custom_type, uid, content, content_operations)
class ops.Composition extends ops.ListManager
@ -320,8 +322,6 @@ module.exports = ()->
# we can't use @seveOperation 'composition_ref', tmp_composition_ref here,
# because then there is a "loop" (insertion refers to parant, refers to insertion..)
# This is why we have to check in @callOperationSpecificInsertEvents until we find it
console.log("delete this ...")
this.constructed_with = [custom_type, @_composition_value, composition_value_operations, uid, tmp_composition_ref] # debug!
super custom_type, uid
if tmp_composition_ref?
@tmp_composition_ref = tmp_composition_ref

File diff suppressed because one or more lines are too long

4
y.js

File diff suppressed because one or more lines are too long