Add beginning of value caching (_length, _bounds) and change tracking to invalidate cached values.

This commit is contained in:
Jürg Lehni 2011-05-02 00:17:21 +01:00
parent 4bac4b89f6
commit 0a4150a5c9
4 changed files with 77 additions and 23 deletions

View file

@ -35,6 +35,11 @@ var Curve = this.Curve = Base.extend({
}
},
_changed: function() {
// Clear cached values.
delete this._length;
},
_updateSegments: function() {
if (this._path) {
this._index2 = this._index1 + 1;
@ -153,11 +158,19 @@ var Curve = this.Curve = Base.extend({
},
getLength: function(/* from, to */) {
var from = arguments[0],
to = arguments[1];
fullLength = arguments.length == 0 || from == 0 && to == 1;
if (fullLength && this._length != null)
return this._length;
// Hide parameters from Bootstrap so it injects bean too
var args = this.getCurveValues();
if (arguments.length > 0)
args.push(arguments[0], arguments[1]);
return Curve.getLength.apply(Curve, args);
if (!fullLength)
args.push(from, to);
var length = Curve.getLength.apply(Curve, args);
if (fullLength)
this._length = length;
return length;
},
/**

View file

@ -28,6 +28,13 @@ var Path = this.Path = PathItem.extend({
|| typeof segments[0] !== 'object' ? arguments : segments);
},
_changed: function() {
// Clear cached values.
delete this._length;
delete this._bounds;
delete this._strokeBounds;
},
/**
* The segments contained within the path.
*/
@ -102,6 +109,7 @@ var Path = this.Path = PathItem.extend({
if (closed)
this._curves[i = length - 1] = Curve.create(this, i);
}
this._changed();
}
},
@ -116,6 +124,7 @@ var Path = this.Path = PathItem.extend({
this._segments[i]._transformCoordinates(matrix, coords, true);
}
}
this._changed();
},
/**
@ -163,6 +172,7 @@ var Path = this.Path = PathItem.extend({
if (this._closed)
this._curves[l - 1]._updateSegments();
}
this._changed();
return segment;
},
@ -199,6 +209,7 @@ var Path = this.Path = PathItem.extend({
segment._selectionState = 0;
}
}
this._changed();
return segments;
}
return null;
@ -245,6 +256,7 @@ var Path = this.Path = PathItem.extend({
segment._handleIn = segment._handleOut;
segment._handleOut = handleIn;
}
this._changed();
},
join: function(path) {
@ -282,17 +294,20 @@ var Path = this.Path = PathItem.extend({
last1.remove();
this.setClosed(true);
}
this._changed();
return true;
}
return false;
},
getLength: function() {
var curves = this.getCurves();
var length = 0;
for (var i = 0, l = curves.length; i < l; i++)
length += curves[i].getLength();
return length;
if (this._length == null) {
var curves = this.getCurves();
this._length = 0;
for (var i = 0, l = curves.length; i < l; i++)
this._length += curves[i].getLength();
}
return this._length;
},
_getOffset: function(location) {
@ -977,9 +992,12 @@ var Path = this.Path = PathItem.extend({
getBounds: function(/* matrix */) {
// Pass the matrix hidden from Bootstrap, so it still inject
// getBounds as bean too.
var bounds = getBounds(this, arguments[0]);
return LinkedRectangle.create(this, 'setBounds',
bounds.x, bounds.y, bounds.width, bounds.height);
if (!this._bounds) {
var bounds = getBounds(this, arguments[0]);
this._bounds = LinkedRectangle.create(this, 'setBounds',
bounds.x, bounds.y, bounds.width, bounds.height);
}
return this._bounds;
},
/**

View file

@ -51,6 +51,28 @@ var Segment = this.Segment = Base.extend({
this._handleOut = SegmentPoint.create(this, 0, 0);
},
_changed: function(point) {
if (this._path) {
// Delegate changes to affected curves if they exist
if (this._path._curves) {
var curve = this.getCurve(), other;
if (curve) {
curve._changed();
// Get the other affected curve, which is the previous one
// for _point or _handleIn changing when this segment is
// _segment1 of the curve, for all other cases it's the next
// (e.g. _handleOut or this segment == _segment2)
if (other = (curve[point == this._point
|| point == this._handleIn && curve._segment1 == this
? 'getPrevious' : 'getNext']())) {
other._changed();
}
}
}
this._path._changed();
}
},
getPoint: function() {
return this._point;
},
@ -105,7 +127,7 @@ var Segment = this.Segment = Base.extend({
},
getCurve: function() {
if (this._path != null) {
if (this._path) {
var index = this._index;
// The last segment of an open path belongs to the last curve
if (!this._path._closed && index == this._path._segments.length - 1)

View file

@ -8,7 +8,7 @@ var SegmentPoint = Point.extend({
set: function(x, y) {
this._x = x;
this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
return this;
},
@ -18,7 +18,7 @@ var SegmentPoint = Point.extend({
setX: function(x) {
this._x = x;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
},
getY: function() {
@ -27,7 +27,7 @@ var SegmentPoint = Point.extend({
setY: function(y) {
this._y = y;
// this._segment._markDirty(DirtyFlags.BOUNDS);
this._segment._changed(this);
},
setSelected: function(selected) {
@ -39,15 +39,16 @@ var SegmentPoint = Point.extend({
},
statics: {
create: function(segment, arg1, arg2) {
var point;
if (arguments.length == 2) {
point = new SegmentPoint(arg1);
} else {
point = new SegmentPoint(SegmentPoint.dont);
point._x = arg1;
point._y = arg2;
create: function(segment, x, y) {
if (y === undefined) {
// Use the normal point constructor to read in point values
var tmp = new Point(x);
x = tmp.x;
y = tmp.y;
}
var point = new SegmentPoint(SegmentPoint.dont);
point._x = x;
point._y = y;
point._segment = segment;
return point;
}