/* * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann * Copyright (C) 2004, 2005 Rob Buis * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public License * along with this library; see the file COPYING.LIB. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef SVGAnimatedTemplate_h #define SVGAnimatedTemplate_h #if ENABLE(SVG) #include "SVGAnimatedPropertyTraits.h" #include #include namespace WebCore { class SVGAngle; class SVGElement; class SVGLengthList; class SVGNumberList; class SVGPreserveAspectRatio; class SVGTransformList; class QualifiedName; struct SVGAnimatedTypeWrapperKey { // Empty value SVGAnimatedTypeWrapperKey() : element(0) , attributeName(0) { } // Deleted value SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValueType) : element(reinterpret_cast(-1)) { } bool isHashTableDeletedValue() const { return element == reinterpret_cast(-1); } SVGAnimatedTypeWrapperKey(const SVGElement* _element, const AtomicString& _attributeName) : element(_element) , attributeName(_attributeName.impl()) { ASSERT(element); ASSERT(attributeName); } bool operator==(const SVGAnimatedTypeWrapperKey& other) const { return element == other.element && attributeName == other.attributeName; } const SVGElement* element; AtomicStringImpl* attributeName; }; struct SVGAnimatedTypeWrapperKeyHash { static unsigned hash(const SVGAnimatedTypeWrapperKey& key) { return StringImpl::computeHash(reinterpret_cast(&key), sizeof(SVGAnimatedTypeWrapperKey) / sizeof(UChar)); } static bool equal(const SVGAnimatedTypeWrapperKey& a, const SVGAnimatedTypeWrapperKey& b) { return a == b; } static const bool safeToCompareToEmptyOrDeleted = true; }; struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits { static const bool emptyValueIsZero = true; static void constructDeletedValue(SVGAnimatedTypeWrapperKey& slot) { new (&slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue); } static bool isDeletedValue(const SVGAnimatedTypeWrapperKey& value) { return value.isHashTableDeletedValue(); } }; template class SVGAnimatedTemplate : public RefCounted > { public: typedef typename SVGAnimatedPropertyTraits::PassType PassType; typedef typename SVGAnimatedPropertyTraits::ReturnType ReturnType; virtual ~SVGAnimatedTemplate() { forgetWrapper(this); } virtual ReturnType baseVal() const = 0; virtual void setBaseVal(PassType) = 0; virtual ReturnType animVal() const = 0; virtual void setAnimVal(PassType) = 0; virtual const QualifiedName& associatedAttributeName() const = 0; typedef HashMap*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap; typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator; static ElementToWrapperMap* wrapperCache() { static ElementToWrapperMap* s_wrapperCache = new ElementToWrapperMap; return s_wrapperCache; } static void forgetWrapper(SVGAnimatedTemplate* wrapper) { ElementToWrapperMap* cache = wrapperCache(); ElementToWrapperMapIterator itr = cache->begin(); ElementToWrapperMapIterator end = cache->end(); for (; itr != end; ++itr) { if (itr->second == wrapper) { cache->remove(itr->first); break; } } } }; template class SVGAnimatedProperty; template PassRefPtr lookupOrCreateWrapper(SVGElement* element, SVGAnimatedProperty& creator, const QualifiedName& attrName) { SVGAnimatedTypeWrapperKey key(element, attrName.localName()); RefPtr wrapper = static_cast(AnimatedTearOff::wrapperCache()->get(key)); if (!wrapper) { wrapper = AnimatedTearOff::create(creator, element); AnimatedTearOff::wrapperCache()->set(key, wrapper.get()); } return wrapper.release(); } // Common type definitions, to ease IDL generation. typedef SVGAnimatedTemplate SVGAnimatedAngle; typedef SVGAnimatedTemplate SVGAnimatedBoolean; typedef SVGAnimatedTemplate SVGAnimatedEnumeration; typedef SVGAnimatedTemplate SVGAnimatedInteger; typedef SVGAnimatedTemplate SVGAnimatedLength; typedef SVGAnimatedTemplate SVGAnimatedLengthList; typedef SVGAnimatedTemplate SVGAnimatedNumber; typedef SVGAnimatedTemplate SVGAnimatedNumberList; typedef SVGAnimatedTemplate SVGAnimatedPreserveAspectRatio; typedef SVGAnimatedTemplate SVGAnimatedRect; typedef SVGAnimatedTemplate SVGAnimatedString; typedef SVGAnimatedTemplate SVGAnimatedTransformList; } #endif #endif