SVGAnimatedValueProperty.h [plain text]
#pragma once
#include "SVGAnimatedProperty.h"
namespace WebCore {
template<typename PropertyType>
class SVGAnimatedValueProperty : public SVGAnimatedProperty {
public:
using ValueType = typename PropertyType::ValueType;
template<typename... Arguments>
static Ref<SVGAnimatedValueProperty> create(SVGElement* contextElement, Arguments&&... arguments)
{
return adoptRef(*new SVGAnimatedValueProperty(contextElement, std::forward<Arguments>(arguments)...));
}
~SVGAnimatedValueProperty()
{
m_baseVal->detach();
if (m_animVal)
m_animVal->detach();
}
void setBaseValInternal(const ValueType& baseVal)
{
m_baseVal->setValue(baseVal);
if (m_animVal)
m_animVal->setValue(baseVal);
}
const Ref<PropertyType>& baseVal() const { return m_baseVal; }
Ref<PropertyType>& baseVal() { return m_baseVal; }
void setAnimVal(const ValueType& animVal)
{
ASSERT(isAnimating() && m_animVal);
m_animVal->setValue(animVal);
}
const RefPtr<PropertyType>& animVal() const { return const_cast<SVGAnimatedValueProperty*>(this)->ensureAnimVal(); }
RefPtr<PropertyType>& animVal() { return ensureAnimVal(); }
String baseValAsString() const override { return m_baseVal->valueAsString(); }
String animValAsString() const override
{
ASSERT(isAnimating() && m_animVal);
return m_animVal->valueAsString();
}
void setDirty() override { m_baseVal->setDirty(); }
bool isDirty() const override { return m_baseVal->isDirty(); }
Optional<String> synchronize() override { return m_baseVal->synchronize(); }
const ValueType& currentValue() const
{
ASSERT_IMPLIES(isAnimating(), m_animVal);
return (isAnimating() ? *m_animVal : m_baseVal.get()).value();
}
void startAnimation(SVGAttributeAnimator& animator) override
{
if (m_animVal)
m_animVal->setValue(m_baseVal->value());
else
ensureAnimVal();
SVGAnimatedProperty::startAnimation(animator);
}
void stopAnimation(SVGAttributeAnimator& animator) override
{
SVGAnimatedProperty::stopAnimation(animator);
if (m_animVal)
m_animVal->setValue(m_baseVal->value());
}
void instanceStartAnimation(SVGAttributeAnimator& animator, SVGAnimatedProperty& animated) override
{
if (isAnimating())
return;
m_animVal = static_cast<SVGAnimatedValueProperty&>(animated).animVal();
SVGAnimatedProperty::instanceStartAnimation(animator, animated);
}
void instanceStopAnimation(SVGAttributeAnimator& animator) override
{
if (!isAnimating())
return;
m_animVal = nullptr;
SVGAnimatedProperty::instanceStopAnimation(animator);
}
protected:
template<typename... Arguments>
SVGAnimatedValueProperty(SVGElement* contextElement, Arguments&&... arguments)
: SVGAnimatedProperty(contextElement)
, m_baseVal(PropertyType::create(this, SVGPropertyAccess::ReadWrite, ValueType(std::forward<Arguments>(arguments)...)))
{
}
template<typename... Arguments>
SVGAnimatedValueProperty(SVGElement* contextElement, SVGPropertyAccess access, Arguments&&... arguments)
: SVGAnimatedProperty(contextElement)
, m_baseVal(PropertyType::create(this, access, ValueType(std::forward<Arguments>(arguments)...)))
{
}
RefPtr<PropertyType>& ensureAnimVal()
{
if (!m_animVal)
m_animVal = PropertyType::create(this, SVGPropertyAccess::ReadOnly, m_baseVal->value());
return m_animVal;
}
void commitPropertyChange(SVGProperty* property) override
{
if (m_animVal)
m_animVal->setValue(m_baseVal->value());
SVGAnimatedProperty::commitPropertyChange(property);
}
Ref<PropertyType> m_baseVal;
mutable RefPtr<PropertyType> m_animVal;
};
}