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.views = [new DocumentView(this)];
this.activeView = this.views[0];
this._selectedItems = [];
this._selectedItems = {};
this._selectedItemCount = 0;
},
getCurrentStyle: function() {
@ -60,34 +61,50 @@ var Document = this.Document = Base.extend({
getSelectedItems: function() {
// TODO: return groups if their children are all selected,
// 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?
_selectItem: function(item, select) {
if (select) {
this.selectedItemCount++;
this._selectedItems[item.getId()] = item;
} else {
this._selectedItemCount--;
delete this._selectedItems[item.getId()];
}
},
draw: function() {
if (this.canvas) {
var context = this.context;
// Initial tests conclude that clearing the canvas using clearRect
// is always faster than setting canvas.width = canvas.width
// 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.context.save();
context.save();
var param = { offset: new Point(0, 0) };
for (var i = 0, l = this.layers.length; i < l; i++)
Item.draw(this.layers[i], this.context, param);
this.context.restore();
Item.draw(this.layers[i], context, param);
context.restore();
// Draw the selection of the selected items in the document:
var selectedItems = this._selectedItems,
length = selectedItems.length;
if (length) {
this.context.strokeWidth = 1;
if (this._selectedItemCount > 0) {
context.save();
context.strokeWidth = 1;
// Todo: use Layer#color
this.context.strokeStyle = this.context.fillStyle = '#4f7aff';
context.strokeStyle = context.fillStyle = '#4f7aff';
param = { selection: true };
for (var i = 0; i < length; i++)
selectedItems[i].draw(this.context, param);
Base.each(this.selectedItems, function(item) {
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
// document, it needs to be removed from _selectedItems
this._selected = selected;
var selectedItems = this._document._selectedItems;
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._document._selectItem(this, selected);
}
}
},

View file

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

View file

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