Document: use a hash for Document#_selectedItems to speed up adding to and removing from it.

This commit is contained in:
Jonathan Puckey 2011-04-21 20:43:42 +02:00
parent 745f002cd3
commit be8ee90f75
4 changed files with 38 additions and 41 deletions

View file

@ -37,7 +37,8 @@ var Document = this.Document = Base.extend({
this.symbols = []; this.symbols = [];
this.views = [new DocumentView(this)]; this.views = [new DocumentView(this)];
this.activeView = this.views[0]; this.activeView = this.views[0];
this._selectedItems = []; this._selectedItems = {};
this._selectedItemCount = 0;
}, },
getCurrentStyle: function() { getCurrentStyle: function() {
@ -60,34 +61,50 @@ var Document = this.Document = Base.extend({
getSelectedItems: function() { getSelectedItems: function() {
// TODO: return groups if their children are all selected, // TODO: return groups if their children are all selected,
// and filter out their children from the list. // and filter out their children from the list.
return this._selectedItems; var items = [];
Base.each(items, function(item) {
items.push(item);
});
return items;
}, },
// TODO: implement setSelectedItems? // TODO: implement setSelectedItems?
_selectItem: function(item, select) {
if (select) {
this.selectedItemCount++;
this._selectedItems[item.getId()] = item;
} else {
this._selectedItemCount--;
delete this._selectedItems[item.getId()];
}
},
draw: function() { draw: function() {
if (this.canvas) { if (this.canvas) {
var context = this.context;
// Initial tests conclude that clearing the canvas using clearRect // Initial tests conclude that clearing the canvas using clearRect
// is always faster than setting canvas.width = canvas.width // is always faster than setting canvas.width = canvas.width
// http://jsperf.com/clearrect-vs-setting-width/7 // http://jsperf.com/clearrect-vs-setting-width/7
this.context.clearRect(0, 0, context.clearRect(0, 0,
this.size.width + 1, this.size.height + 1); this.size.width + 1, this.size.height + 1);
this.context.save(); context.save();
var param = { offset: new Point(0, 0) }; var param = { offset: new Point(0, 0) };
for (var i = 0, l = this.layers.length; i < l; i++) for (var i = 0, l = this.layers.length; i < l; i++)
Item.draw(this.layers[i], this.context, param); Item.draw(this.layers[i], context, param);
this.context.restore(); context.restore();
// Draw the selection of the selected items in the document: // Draw the selection of the selected items in the document:
var selectedItems = this._selectedItems, if (this._selectedItemCount > 0) {
length = selectedItems.length; context.save();
if (length) { context.strokeWidth = 1;
this.context.strokeWidth = 1;
// Todo: use Layer#color // Todo: use Layer#color
this.context.strokeStyle = this.context.fillStyle = '#4f7aff'; context.strokeStyle = context.fillStyle = '#4f7aff';
param = { selection: true }; param = { selection: true };
for (var i = 0; i < length; i++) Base.each(this.selectedItems, function(item) {
selectedItems[i].draw(this.context, param); item.draw(context, param);
});
context.restore();
} }
} }
}, },

View file

@ -64,15 +64,7 @@ var Item = this.Item = Base.extend({
// TODO: when an item is removed or moved to another // TODO: when an item is removed or moved to another
// document, it needs to be removed from _selectedItems // document, it needs to be removed from _selectedItems
this._selected = selected; this._selected = selected;
var selectedItems = this._document._selectedItems; this._document._selectItem(this, selected);
if (selected) {
selectedItems.push(this);
} else {
// TODO: is there a faster way?
var index = selectedItems.indexOf(this);
if (index != -1)
selectedItems.splice(index, 1);
}
} }
} }
}, },

View file

@ -136,17 +136,8 @@ var Path = this.Path = PathItem.extend({
setSelected: function(selected) { setSelected: function(selected) {
var wasSelected = this.isSelected(); var wasSelected = this.isSelected();
var length = this._segments.length; var length = this._segments.length;
if (!wasSelected != !selected && length) { if (!wasSelected != !selected && length)
var selectedItems = this._document._selectedItems; this._document._selectItem(this, selected);
if (selected) {
selectedItems.push(this);
} else {
// TODO: is there a faster way?
var index = selectedItems.indexOf(this);
if (index != -1)
selectedItems.splice(index, 1);
}
}
this._selectedSegmentCount = selected ? length : 0; this._selectedSegmentCount = selected ? length : 0;
for (var i = 0; i < length; i++) for (var i = 0; i < length; i++)
this._segments[i]._selectionState = selected this._segments[i]._selectionState = selected

View file

@ -221,15 +221,12 @@ var Segment = this.Segment = Base.extend({
selectedItems = path._document._selectedItems; selectedItems = path._document._selectedItems;
if (!this._selectionState) { if (!this._selectionState) {
path._selectedSegmentCount--; path._selectedSegmentCount--;
if (path._selectedSegmentCount == 0) { if (path._selectedSegmentCount == 0)
var index = selectedItems.indexOf(this); path._document._selectItem(path, true);
selectedItems.slice(index, 1);
}
} else { } else {
path._selectedSegmentCount++; path._selectedSegmentCount++;
if (path._selectedSegmentCount == 1) { if (path._selectedSegmentCount == 1)
selectedItems.push(path); path._document._selectItem(path, false);
}
} }
} }
}, },