SVGAnimatedProperty.h [plain text]
#ifndef SVGAnimatedProperty_h
#define SVGAnimatedProperty_h
#if ENABLE(SVG)
#include "SVGAnimatedPropertyDescription.h"
#include "SVGElement.h"
#include "SVGPropertyInfo.h"
#include <wtf/RefCounted.h>
namespace WebCore {
class SVGElement;
class SVGAnimatedProperty : public RefCounted<SVGAnimatedProperty> {
public:
SVGElement* contextElement() const { return m_contextElement.get(); }
const QualifiedName& attributeName() const { return m_attributeName; }
AnimatedPropertyType animatedPropertyType() const { return m_animatedPropertyType; }
bool isAnimating() const { return m_isAnimating; }
void commitChange()
{
ASSERT(m_contextElement);
m_contextElement->invalidateSVGAttributes();
m_contextElement->svgAttributeChanged(m_attributeName);
}
virtual bool isAnimatedListTearOff() const { return false; }
typedef HashMap<SVGAnimatedPropertyDescription, SVGAnimatedProperty*, SVGAnimatedPropertyDescriptionHash, SVGAnimatedPropertyDescriptionHashTraits> Cache;
virtual ~SVGAnimatedProperty()
{
Cache* cache = animatedPropertyCache();
const Cache::const_iterator end = cache->end();
for (Cache::const_iterator it = cache->begin(); it != end; ++it) {
if (it->second == this) {
cache->remove(it->first);
break;
}
}
ASSERT(!m_isAnimating);
}
template<typename TearOffType, typename PropertyType, bool isDerivedFromSVGElement>
struct LookupOrCreateHelper;
template<typename TearOffType, typename PropertyType>
struct LookupOrCreateHelper<TearOffType, PropertyType, false> {
static PassRefPtr<TearOffType> lookupOrCreateWrapper(void*, const SVGPropertyInfo*, PropertyType&)
{
ASSERT_NOT_REACHED();
return PassRefPtr<TearOffType>();
}
};
template<typename TearOffType, typename PropertyType>
struct LookupOrCreateHelper<TearOffType, PropertyType, true> {
static PassRefPtr<TearOffType> lookupOrCreateWrapper(SVGElement* element, const SVGPropertyInfo* info, PropertyType& property)
{
ASSERT(info);
SVGAnimatedPropertyDescription key(element, info->propertyIdentifier);
RefPtr<SVGAnimatedProperty> wrapper = animatedPropertyCache()->get(key);
if (!wrapper) {
wrapper = TearOffType::create(element, info->attributeName, info->animatedPropertyType, property);
animatedPropertyCache()->set(key, wrapper.get());
}
return static_pointer_cast<TearOffType>(wrapper);
}
};
template<typename OwnerType, typename TearOffType, typename PropertyType, bool isDerivedFromSVGElement>
static PassRefPtr<TearOffType> lookupOrCreateWrapper(OwnerType* element, const SVGPropertyInfo* info, PropertyType& property)
{
return LookupOrCreateHelper<TearOffType, PropertyType, isDerivedFromSVGElement>::lookupOrCreateWrapper(element, info, property);
}
template<typename TearOffType, bool isDerivedFromSVGElement>
struct LookupHelper;
template<typename TearOffType>
struct LookupHelper<TearOffType, false> {
static TearOffType* lookupWrapper(const void*, const SVGPropertyInfo*)
{
return 0;
}
};
template<typename TearOffType>
struct LookupHelper<TearOffType, true> {
static TearOffType* lookupWrapper(const SVGElement* element, const SVGPropertyInfo* info)
{
ASSERT(info);
SVGAnimatedPropertyDescription key(const_cast<SVGElement*>(element), info->propertyIdentifier);
return static_cast<TearOffType*>(animatedPropertyCache()->get(key));
}
};
template<typename OwnerType, typename TearOffType, bool isDerivedFromSVGElement>
static TearOffType* lookupWrapper(const OwnerType* element, const SVGPropertyInfo* info)
{
return LookupHelper<TearOffType, isDerivedFromSVGElement>::lookupWrapper(element, info);
}
protected:
SVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType)
: m_contextElement(contextElement)
, m_attributeName(attributeName)
, m_animatedPropertyType(animatedPropertyType)
, m_isAnimating(false)
{
}
private:
static Cache* animatedPropertyCache()
{
static Cache* s_cache = new Cache;
return s_cache;
}
RefPtr<SVGElement> m_contextElement;
const QualifiedName& m_attributeName;
AnimatedPropertyType m_animatedPropertyType;
protected:
bool m_isAnimating;
};
}
#endif // ENABLE(SVG)
#endif // SVGAnimatedProperty_h