Skip to content

Commit

Permalink
Bug 1332633 - Part 1: Implement ComputeDistance trait.
Browse files Browse the repository at this point in the history
Introduce ComputeDistance trait, which implement compute_distance and
compute_squared_distance.

For vector, compute_squared_distance is necessary because we use Euclidean
distance as the distance between two values. The easier way to implement
compute_squared_distance is to square the result from compute_distance, but
for some property values, they may have many components, e.g. (v1, v2, v3).
If we just square the result from compute_distance, the computation is
(sqrt(v1^2 + v2^2 + v3^2))^2. There are two redundant operators:
"square-root" and then "square". In order to avoid this, we should
implement compute_squared_distance separately for these types.

MozReview-Commit-ID: LmmrUXYlDb6
  • Loading branch information
BorisChiou committed Apr 21, 2017
1 parent 17dc598 commit 57f8700
Show file tree
Hide file tree
Showing 7 changed files with 733 additions and 11 deletions.
51 changes: 51 additions & 0 deletions components/style/properties/helpers.mako.rs
Expand Up @@ -95,6 +95,19 @@
self.0.interpolate(&other.0, progress).map(T)
}
}

use properties::animated_properties::ComputeDistance;
impl ComputeDistance for T {
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_distance(&other.0)
}

#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
self.0.compute_squared_distance(&other.0)
}
}
% endif
}

Expand Down Expand Up @@ -785,3 +798,41 @@
}
}
</%def>

/// Macro for defining ComputeDistance trait for tuple struct which has Option<T>,
/// e.g. struct T(pub Option<Au>).
<%def name="impl_compute_distance_for_option_tuple(value_for_none)">
impl ComputeDistance for T {
#[inline]
fn compute_distance(&self, other: &Self) -> Result<f64, ()> {
match (self, other) {
(&T(Some(ref this)), &T(Some(ref other))) => {
this.compute_distance(other)
},
(&T(Some(ref value)), &T(None)) |
(&T(None), &T(Some(ref value)))=> {
value.compute_distance(&${value_for_none})
},
(&T(None), &T(None)) => {
Ok(0.0)
},
}
}

#[inline]
fn compute_squared_distance(&self, other: &Self) -> Result<f64, ()> {
match (self, other) {
(&T(Some(ref this)), &T(Some(ref other))) => {
this.compute_squared_distance(other)
},
(&T(Some(ref value)), &T(None)) |
(&T(None), &T(Some(ref value))) => {
value.compute_squared_distance(&${value_for_none})
},
(&T(None), &T(None)) => {
Ok(0.0)
},
}
}
}
</%def>

0 comments on commit 57f8700

Please sign in to comment.