Skip to content

Commit

Permalink
Implement Clone for AnimationValue by hand 馃悏馃惒
Browse files Browse the repository at this point in the history
We use the same trick as in PropertyDeclaration::clone.
  • Loading branch information
nox committed Feb 11, 2018
1 parent b95b6c6 commit c92d0a8
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
60 changes: 58 additions & 2 deletions components/style/properties/helpers/animated_properties.mako.rs
Expand Up @@ -27,8 +27,9 @@ use properties::{LonghandId, ShorthandId};
use selectors::parser::SelectorParseErrorKind;
use servo_arc::Arc;
use smallvec::SmallVec;
use std::{cmp, mem, ptr};
use std::{cmp, ptr};
use std::fmt::{self, Write};
use std::mem::{self, ManuallyDrop};
#[cfg(feature = "gecko")] use hash::FnvHashMap;
use style_traits::{CssWriter, ParseError, ToCss};
use super::ComputedValues;
Expand Down Expand Up @@ -346,7 +347,7 @@ unsafe impl HasSimpleFFI for AnimationValueMap {}
/// FIXME: We need to add a path for custom properties, but that's trivial after
/// this (is a similar path to that of PropertyDeclaration).
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive(Clone, Debug)]
#[derive(Debug)]
#[repr(u16)]
pub enum AnimationValue {
% for prop in data.longhands:
Expand Down Expand Up @@ -376,6 +377,61 @@ struct AnimationValueVariantRepr<T> {
value: T
}

impl Clone for AnimationValue {
#[inline]
fn clone(&self) -> Self {
use self::AnimationValue::*;

<%
[copy, others] = [list(g) for _, g in groupby(animated, key=lambda x: not x.specified_is_copy())]
%>

let self_tag = unsafe { *(self as *const _ as *const u16) };
if self_tag <= LonghandId::${copy[-1].camel_case} as u16 {
#[derive(Clone, Copy)]
#[repr(u16)]
enum CopyVariants {
% for prop in copy:
_${prop.camel_case}(${prop.animated_type()}),
% endfor
}

unsafe {
let mut out = mem::uninitialized();
ptr::write(
&mut out as *mut _ as *mut CopyVariants,
*(self as *const _ as *const CopyVariants),
);
return out;
}
}

match *self {
% for ty, props in groupby(others, key=lambda x: x.animated_type()):
<% props = list(props) %>
${" |\n".join("{}(ref value)".format(prop.camel_case) for prop in props)} => {
% if len(props) == 1:
${props[0].camel_case}(value.clone())
% else:
unsafe {
let mut out = ManuallyDrop::new(mem::uninitialized());
ptr::write(
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
AnimationValueVariantRepr {
tag: *(self as *const _ as *const u16),
value: value.clone(),
},
);
ManuallyDrop::into_inner(out)
}
% endif
}
% endfor
_ => unsafe { debug_unreachable!() }
}
}
}

impl PartialEq for AnimationValue {
#[inline]
fn eq(&self, other: &Self) -> bool {
Expand Down
2 changes: 1 addition & 1 deletion components/style/values/computed/border.rs
Expand Up @@ -88,7 +88,7 @@ impl ToAnimatedZero for BorderCornerRadius {
/// The computed value of the `border-image-repeat` property:
///
/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword);

impl BorderImageRepeat {
Expand Down

0 comments on commit c92d0a8

Please sign in to comment.