Add Graph#update

This can be used to reduce graph churn when there are
multiple changes to make.
This commit is contained in:
John Firebaugh
2013-01-25 13:04:46 -05:00
parent dfb38d7d0c
commit 4874199401
2 changed files with 79 additions and 17 deletions
+35 -17
View File
@@ -1,5 +1,5 @@
iD.Graph = function(entities) {
if (!(this instanceof iD.Graph)) return new iD.Graph(entities);
iD.Graph = function(entities, mutable) {
if (!(this instanceof iD.Graph)) return new iD.Graph(entities, mutable);
if (_.isArray(entities)) {
this.entities = {};
@@ -15,9 +15,8 @@ iD.Graph = function(entities) {
this._parentRels = {};
this._fetches = {};
if (iD.debug) {
Object.freeze(this);
Object.freeze(this.entities);
if (!mutable) {
this.freeze();
}
};
@@ -87,27 +86,46 @@ iD.Graph.prototype = {
},
merge: function(graph) {
var entities = _.clone(this.entities);
_.defaults(entities, graph.entities);
return iD.Graph(entities);
return this.update(function () {
_.defaults(this.entities, graph.entities);
});
},
replace: function(entity) {
var entities = _.clone(this.entities);
entities[entity.id] = entity;
return iD.Graph(entities);
return this.update(function () {
this.entities[entity.id] = entity;
});
},
remove: function(entity) {
var entities = _.clone(this.entities);
return this.update(function () {
if (entity.created()) {
delete this.entities[entity.id];
} else {
this.entities[entity.id] = undefined;
}
});
},
if (entity.created()) {
delete entities[entity.id];
} else {
entities[entity.id] = undefined;
update: function() {
var graph = this.frozen ? iD.Graph(_.clone(this.entities), true) : this;
for (var i = 0; i < arguments.length; i++) {
arguments[i].call(graph, graph);
}
return iD.Graph(entities);
return this.frozen ? graph.freeze() : this;
},
freeze: function() {
this.frozen = true;
if (iD.debug) {
Object.freeze(this);
Object.freeze(this.entities);
}
return this;
},
// get all objects that intersect an extent.
+44
View File
@@ -64,6 +64,50 @@ describe('iD.Graph', function() {
});
});
describe("#update", function () {
it("returns a new graph if self is frozen", function () {
var graph = iD.Graph();
expect(graph.update()).not.to.equal(graph);
});
it("returns self if self is not frozen", function () {
var graph = iD.Graph({}, true);
expect(graph.update()).to.equal(graph);
});
it("doesn't modify self is self is frozen", function () {
var node = iD.Node(),
graph = iD.Graph([node]);
graph.update(function (graph) { graph.remove(node); });
expect(graph.entity(node.id)).to.equal(node);
});
it("modifies self is self is not frozen", function () {
var node = iD.Node(),
graph = iD.Graph([node], true);
graph.update(function (graph) { graph.remove(node); });
expect(graph.entity(node.id)).to.be.undefined;
});
it("executes all of the given functions", function () {
var a = iD.Node(),
b = iD.Node(),
graph = iD.Graph([a]);
graph = graph.update(
function (graph) { graph.remove(a); },
function (graph) { graph.replace(b); }
);
expect(graph.entity(a.id)).to.be.undefined;
expect(graph.entity(b.id)).to.equal(b);
});
});
describe("#parentWays", function() {
it("returns an array of ways that contain the given node id", function () {
var node = iD.Node({id: "n1"}),