1 /*
2     Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4 
5     This file is part of the KDE project
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16 
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22 
23 #ifndef SVGAnimatedTemplate_h
24 #define SVGAnimatedTemplate_h
25 
26 #if ENABLE(SVG)
27 #include <wtf/RefCounted.h>
28 //#include "AtomicString.h"
29 //#include "Attribute.h"
30 #include <wtf/HashTraits.h>
31 #include <wtf/HashMap.h>
32 
33 namespace WebCore
34 {
35 
36 class FloatRect;
37 class SVGAngle;
38 class SVGElement;
39 class SVGLength;
40 class SVGLengthList;
41 class SVGNumberList;
42 class SVGPreserveAspectRatio;
43 class SVGTransformList;
44 //class String;
45 //class QualifiedName;
46 
47 struct SVGAnimatedTypeWrapperKey {
48     // Empty value
SVGAnimatedTypeWrapperKeySVGAnimatedTypeWrapperKey49     SVGAnimatedTypeWrapperKey()
50         : element(nullptr)
51         , attributeName(nullptr)
52     { }
53 
54     // Deleted value
SVGAnimatedTypeWrapperKeySVGAnimatedTypeWrapperKey55     SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValueType)
56         : element(reinterpret_cast<SVGElement *>(-1))
57     {
58     }
isHashTableDeletedValueSVGAnimatedTypeWrapperKey59     bool isHashTableDeletedValue() const
60     {
61         return element == reinterpret_cast<SVGElement *>(-1);
62     }
63 
SVGAnimatedTypeWrapperKeySVGAnimatedTypeWrapperKey64     SVGAnimatedTypeWrapperKey(const SVGElement *_element, const AtomicString &_attributeName)
65         : element(_element)
66         , attributeName(_attributeName.impl())
67     {
68         ASSERT(element);
69         ASSERT(attributeName);
70     }
71 
72     bool operator==(const SVGAnimatedTypeWrapperKey &other) const
73     {
74         return element == other.element && attributeName == other.attributeName;
75     }
76 
77     const SVGElement *element;
78     AtomicStringImpl *attributeName;
79 };
80 
81 struct SVGAnimatedTypeWrapperKeyHash {
hashSVGAnimatedTypeWrapperKeyHash82     static unsigned hash(const SVGAnimatedTypeWrapperKey &key)
83     {
84         return StringImpl::computeHash(reinterpret_cast<const UChar *>(&key), sizeof(SVGAnimatedTypeWrapperKey) / sizeof(UChar));
85     }
86 
equalSVGAnimatedTypeWrapperKeyHash87     static bool equal(const SVGAnimatedTypeWrapperKey &a, const SVGAnimatedTypeWrapperKey &b)
88     {
89         return a == b;
90     }
91 
92     static const bool safeToCompareToEmptyOrDeleted = true;
93 };
94 
95 struct SVGAnimatedTypeWrapperKeyHashTraits : WTF::GenericHashTraits<SVGAnimatedTypeWrapperKey> {
96     static const bool emptyValueIsZero = true;
97 
constructDeletedValueSVGAnimatedTypeWrapperKeyHashTraits98     static void constructDeletedValue(SVGAnimatedTypeWrapperKey *slot)
99     {
100         new(slot) SVGAnimatedTypeWrapperKey(WTF::HashTableDeletedValue);
101     }
isDeletedValueSVGAnimatedTypeWrapperKeyHashTraits102     static bool isDeletedValue(const SVGAnimatedTypeWrapperKey &value)
103     {
104         return value.isHashTableDeletedValue();
105     }
106 };
107 
108 template<typename BareType>
109 class SVGAnimatedTemplate : public RefCounted<SVGAnimatedTemplate<BareType> >
110 {
111 public:
SVGAnimatedTemplate(const QualifiedName & attributeName)112     SVGAnimatedTemplate(const QualifiedName &attributeName)
113         : RefCounted<SVGAnimatedTemplate<BareType> >(0)
114         , m_associatedAttributeName(attributeName)
115     {
116     }
117 
~SVGAnimatedTemplate()118     virtual ~SVGAnimatedTemplate()
119     {
120         forgetWrapper(this);
121     }
122 
123     virtual BareType baseVal() const = 0;
124     virtual void setBaseVal(BareType newBaseVal) = 0;
125 
126     virtual BareType animVal() const = 0;
127     virtual void setAnimVal(BareType newAnimVal) = 0;
128 
129     typedef HashMap<SVGAnimatedTypeWrapperKey, SVGAnimatedTemplate<BareType>*, SVGAnimatedTypeWrapperKeyHash, SVGAnimatedTypeWrapperKeyHashTraits > ElementToWrapperMap;
130     typedef typename ElementToWrapperMap::const_iterator ElementToWrapperMapIterator;
131 
wrapperCache()132     static ElementToWrapperMap *wrapperCache()
133     {
134         static ElementToWrapperMap *s_wrapperCache = new ElementToWrapperMap;
135         return s_wrapperCache;
136     }
137 
forgetWrapper(SVGAnimatedTemplate<BareType> * wrapper)138     static void forgetWrapper(SVGAnimatedTemplate<BareType> *wrapper)
139     {
140         ElementToWrapperMap *cache = wrapperCache();
141         ElementToWrapperMapIterator itr = cache->begin();
142         ElementToWrapperMapIterator end = cache->end();
143         for (; itr != end; ++itr) {
144             if (itr->second == wrapper) {
145                 cache->remove(itr->first);
146                 break;
147             }
148         }
149     }
150 
associatedAttributeName()151     const QualifiedName &associatedAttributeName() const
152     {
153         return m_associatedAttributeName;
154     }
155 
156 private:
157     const QualifiedName &m_associatedAttributeName;
158 };
159 
160 template <class Type, class SVGElementSubClass>
lookupOrCreateWrapper(const SVGElementSubClass * element,const QualifiedName & domAttrName,const AtomicString & attrIdentifier)161 Type *lookupOrCreateWrapper(const SVGElementSubClass *element, const QualifiedName &domAttrName, const AtomicString &attrIdentifier)
162 {
163     SVGAnimatedTypeWrapperKey key(element, attrIdentifier);
164     Type *wrapper = static_cast<Type *>(Type::wrapperCache()->get(key));
165     if (!wrapper) {
166         wrapper = new Type(element, domAttrName);
167         Type::wrapperCache()->set(key, wrapper);
168     }
169     return wrapper;
170 }
171 
172 // Common type definitions, to ease IDL generation...
173 typedef SVGAnimatedTemplate<SVGAngle *> SVGAnimatedAngle;
174 typedef SVGAnimatedTemplate<bool> SVGAnimatedBoolean;
175 typedef SVGAnimatedTemplate<int> SVGAnimatedEnumeration;
176 typedef SVGAnimatedTemplate<long> SVGAnimatedInteger;
177 typedef SVGAnimatedTemplate<SVGLength> SVGAnimatedLength;
178 typedef SVGAnimatedTemplate<SVGLengthList *> SVGAnimatedLengthList;
179 typedef SVGAnimatedTemplate<float> SVGAnimatedNumber;
180 typedef SVGAnimatedTemplate<SVGNumberList *> SVGAnimatedNumberList;
181 typedef SVGAnimatedTemplate<SVGPreserveAspectRatio *> SVGAnimatedPreserveAspectRatio;
182 typedef SVGAnimatedTemplate<FloatRect> SVGAnimatedRect;
183 typedef SVGAnimatedTemplate<String> SVGAnimatedString;
184 typedef SVGAnimatedTemplate<SVGTransformList *> SVGAnimatedTransformList;
185 }
186 
187 #endif // ENABLE(SVG)
188 #endif // SVGAnimatedTemplate_h
189