Skip to content

Commit

Permalink
Factor out a process that creates AnimationValue iterator from Proper…
Browse files Browse the repository at this point in the history
…tyDeclarationBlock.
  • Loading branch information
Hiroyuki Ikezoe committed Jun 8, 2017
1 parent 3244d62 commit 2b929a1
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 23 deletions.
59 changes: 59 additions & 0 deletions components/style/properties/declaration_block.rs
Expand Up @@ -11,13 +11,15 @@ use cssparser::{DeclarationListParser, parse_important};
use cssparser::{Parser, AtRuleParser, DeclarationParser, Delimiter};
use error_reporting::ParseErrorReporter;
use parser::{PARSING_MODE_DEFAULT, ParsingMode, ParserContext, log_css_error};
use properties::animated_properties::AnimationValue;
use shared_lock::Locked;
use std::fmt;
use std::slice::Iter;
use style_traits::ToCss;
use stylesheets::{CssRuleType, Origin, UrlExtraData};
use stylesheets::{MallocSizeOf, MallocSizeOfFn};
use super::*;
use values::computed::Context;
#[cfg(feature = "gecko")] use properties::animated_properties::AnimationValueMap;

/// The animation rules.
Expand Down Expand Up @@ -102,6 +104,55 @@ impl<'a> Iterator for PropertyDeclarationIterator<'a> {
}
}

/// Iterator for AnimationValue to be generated from PropertyDeclarationBlock.
pub struct AnimationValueIterator<'a, 'cx, 'cx_a:'cx> {
iter: Iter<'a, (PropertyDeclaration, Importance)>,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>,
}

impl<'a, 'cx, 'cx_a:'cx> AnimationValueIterator<'a, 'cx, 'cx_a> {
fn new(declarations: &'a PropertyDeclarationBlock,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>) -> AnimationValueIterator<'a, 'cx, 'cx_a> {
AnimationValueIterator {
iter: declarations.declarations().iter(),
context: context,
default_values: default_values,
}
}
}

impl<'a, 'cx, 'cx_a:'cx> Iterator for AnimationValueIterator<'a, 'cx, 'cx_a> {
type Item = (TransitionProperty, AnimationValue);
#[inline]
fn next(&mut self) -> Option<Self::Item> {
use properties::Importance;

loop {
let next = self.iter.next();
match next {
Some(&(ref decl, importance)) => {
if importance == Importance::Normal {
let property = TransitionProperty::from_declaration(decl);
let animation = AnimationValue::from_declaration(decl, &mut self.context,
self.default_values);
debug_assert!(property.is_none() == animation.is_none(),
"The failure condition of TransitionProperty::from_declaration \
and AnimationValue::from_declaration should be the same");
// Skip the property if either ::from_declaration fails.
match (property, animation) {
(Some(p), Some(a)) => return Some((p, a)),
(_, _) => {},
}
}
},
None => return None,
}
}
}
}

impl fmt::Debug for PropertyDeclarationBlock {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.declarations.fmt(f)
Expand Down Expand Up @@ -148,6 +199,14 @@ impl PropertyDeclarationBlock {
}
}

/// Return an iterator of (TransitionProperty, AnimationValue).
pub fn to_animation_value_iter<'a, 'cx, 'cx_a:'cx>(&'a self,
context: &'cx mut Context<'cx_a>,
default_values: &'a Arc<ComputedValues>)
-> AnimationValueIterator<'a, 'cx, 'cx_a> {
AnimationValueIterator::new(self, context, default_values)
}

/// Returns whether this block contains any declaration with `!important`.
///
/// This is based on the `important_count` counter,
Expand Down
24 changes: 1 addition & 23 deletions ports/geckolib/glue.rs
Expand Up @@ -2581,7 +2581,6 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
{
use std::mem;
use style::properties::LonghandIdSet;
use style::properties::declaration_block::Importance;

let data = PerDocumentStyleData::from_ffi(raw_data).borrow();
let metrics = get_metrics_provider_for_product();
Expand Down Expand Up @@ -2616,28 +2615,7 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis
let declarations = Locked::<PropertyDeclarationBlock>::as_arc(&declarations);
let guard = declarations.read_with(&guard);

let anim_iter = guard.declarations()
.iter()
.filter_map(|&(ref decl, imp)| {
if imp == Importance::Normal {
let property = TransitionProperty::from_declaration(decl);
let animation = AnimationValue::from_declaration(decl, &mut context,
default_values);
debug_assert!(property.is_none() == animation.is_none(),
"The failure condition of TransitionProperty::from_declaration \
and AnimationValue::from_declaration should be the same");
// Skip the property if either ::from_declaration fails.
if property.is_none() || animation.is_none() {
None
} else {
Some((property.unwrap(), animation.unwrap()))
}
} else {
None
}
});

for anim in anim_iter {
for anim in guard.to_animation_value_iter(&mut context, &default_values) {
if !seen.has_transition_property_bit(&anim.0) {
// This is safe since we immediately write to the uninitialized values.
unsafe { animation_values.set_len((property_index + 1) as u32) };
Expand Down

0 comments on commit 2b929a1

Please sign in to comment.