00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #ifndef JSSVGPODTypeWrapper_h
00028 #define JSSVGPODTypeWrapper_h
00029
00030 #if ENABLE(SVG)
00031
00032 #include "Frame.h"
00033 #include <wtf/RefCounted.h>
00034 #include "SVGElement.h"
00035
00036 #include <wtf/Assertions.h>
00037 #include <wtf/HashMap.h>
00038
00039 namespace WebCore {
00040 template<typename PODType>
00041 class SVGPODListItem;
00042 }
00043
00044 using namespace WebCore;
00045
00046 namespace khtml {
00047
00048 template<typename PODType>
00049 class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > {
00050 public:
00051 JSSVGPODTypeWrapper() : RefCounted<JSSVGPODTypeWrapper<PODType> >(0) { }
00052 virtual ~JSSVGPODTypeWrapper() { }
00053
00054
00055 virtual operator PODType() = 0;
00056
00057
00058 virtual void commitChange(PODType, SVGElement*) = 0;
00059 };
00060
00061 template<typename PODType, typename PODTypeCreator>
00062 class JSSVGPODTypeWrapperCreatorReadWrite : public JSSVGPODTypeWrapper<PODType>
00063 {
00064 public:
00065 typedef PODType (PODTypeCreator::*GetterMethod)() const;
00066 typedef void (PODTypeCreator::*SetterMethod)(PODType);
00067
00068 JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)
00069 : m_creator(creator)
00070 , m_getter(getter)
00071 , m_setter(setter)
00072 {
00073 ASSERT(creator);
00074 ASSERT(getter);
00075 ASSERT(setter);
00076 }
00077
00078 virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { }
00079
00080
00081 virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
00082
00083
00084 virtual void commitChange(PODType type, SVGElement* context)
00085 {
00086 if (!m_setter)
00087 return;
00088
00089 (m_creator.get()->*m_setter)(type);
00090
00091 if (context)
00092 context->svgAttributeChanged(m_creator->associatedAttributeName());
00093 }
00094
00095 private:
00096
00097 RefPtr<PODTypeCreator> m_creator;
00098 GetterMethod m_getter;
00099 SetterMethod m_setter;
00100 };
00101
00102 template<typename PODType>
00103 class JSSVGPODTypeWrapperCreatorReadOnly : public JSSVGPODTypeWrapper<PODType>
00104 {
00105 public:
00106 JSSVGPODTypeWrapperCreatorReadOnly(PODType type)
00107 : m_podType(type)
00108 { }
00109
00110 virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { }
00111
00112
00113 virtual operator PODType() { return m_podType; }
00114
00115
00116 virtual void commitChange(PODType type, SVGElement*)
00117 {
00118 m_podType = type;
00119 }
00120
00121 private:
00122 PODType m_podType;
00123 };
00124
00125 template<typename PODType>
00126 class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType>
00127 {
00128 public:
00129 typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const;
00130 typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType);
00131
00132 JSSVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType>* creator, const QualifiedName& attributeName)
00133 : m_creator(creator)
00134 , m_getter(&SVGPODListItem<PODType>::value)
00135 , m_setter(&SVGPODListItem<PODType>::setValue)
00136 , m_associatedAttributeName(attributeName)
00137 {
00138 ASSERT(m_creator);
00139 ASSERT(m_getter);
00140 ASSERT(m_setter);
00141 }
00142
00143 virtual ~JSSVGPODTypeWrapperCreatorForList() { }
00144
00145
00146 virtual operator PODType() { return (m_creator.get()->*m_getter)(); }
00147
00148
00149 virtual void commitChange(PODType type, SVGElement* context)
00150 {
00151 if (!m_setter)
00152 return;
00153
00154 (m_creator.get()->*m_setter)(type);
00155
00156 if (context)
00157 context->svgAttributeChanged(m_associatedAttributeName);
00158 }
00159
00160 private:
00161
00162 RefPtr<SVGPODListItem<PODType> > m_creator;
00163 GetterMethod m_getter;
00164 SetterMethod m_setter;
00165 const QualifiedName& m_associatedAttributeName;
00166 };
00167
00168
00169 template<typename PODType, typename PODTypeCreator>
00170 struct PODTypeReadWriteHashInfo {
00171 typedef PODType (PODTypeCreator::*GetterMethod)() const;
00172 typedef void (PODTypeCreator::*SetterMethod)(PODType);
00173
00174
00175 PODTypeReadWriteHashInfo()
00176 : creator(0)
00177 , getter(0)
00178 , setter(0)
00179 {
00180 }
00181
00182
00183 PODTypeReadWriteHashInfo(WTF::HashTableDeletedValueType)
00184 : creator(reinterpret_cast<PODTypeCreator*>(-1))
00185 {
00186 }
00187 bool isHashTableDeletedValue() const
00188 {
00189 return creator == reinterpret_cast<PODTypeCreator*>(-1);
00190 }
00191
00192 PODTypeReadWriteHashInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter)
00193 : creator(_creator)
00194 , getter(_getter)
00195 , setter(_setter)
00196 {
00197 ASSERT(creator);
00198 ASSERT(getter);
00199 }
00200
00201 bool operator==(const PODTypeReadWriteHashInfo& other) const
00202 {
00203 return creator == other.creator && getter == other.getter && setter == other.setter;
00204 }
00205
00206 PODTypeCreator* creator;
00207 GetterMethod getter;
00208 SetterMethod setter;
00209 };
00210
00211 template<typename PODType, typename PODTypeCreator>
00212 struct PODTypeReadWriteHashInfoHash {
00213 static unsigned hash(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& info)
00214 {
00215 return StringImpl::computeHash(reinterpret_cast<const WebCore::UChar*>(&info), sizeof(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>) / sizeof(WebCore::UChar));
00216 }
00217
00218 static bool equal(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& a, const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& b)
00219 {
00220 return a == b;
00221 }
00222
00223 static const bool safeToCompareToEmptyOrDeleted = true;
00224 };
00225
00226 template<typename PODType, typename PODTypeCreator>
00227 struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > {
00228 static const bool emptyValueIsZero = true;
00229 static const bool needsDestruction = false;
00230
00231 static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& emptyValue()
00232 {
00233 static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key;
00234 return key;
00235 }
00236
00237 static void constructDeletedValue(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>* slot)
00238 {
00239 new (slot) PODTypeReadWriteHashInfo<PODType, PODTypeCreator>(WTF::HashTableDeletedValue);
00240 }
00241 static bool isDeletedValue(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& value)
00242 {
00243 return value.isHashTableDeletedValue();
00244 }
00245 };
00246
00247 template<typename PODType, typename PODTypeCreator>
00248 class JSSVGPODTypeWrapperCache
00249 {
00250 public:
00251 typedef PODType (PODTypeCreator::*GetterMethod)() const;
00252 typedef void (PODTypeCreator::*SetterMethod)(PODType);
00253
00254 typedef HashMap<PODTypeReadWriteHashInfo<PODType, PODTypeCreator>, JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>*, PODTypeReadWriteHashInfoHash<PODType, PODTypeCreator>, PODTypeReadWriteHashInfoTraits<PODType, PODTypeCreator> > ReadWriteHashMap;
00255 typedef typename ReadWriteHashMap::const_iterator ReadWriteHashMapIterator;
00256
00257 static ReadWriteHashMap& readWriteHashMap()
00258 {
00259 static ReadWriteHashMap _readWriteHashMap;
00260 return _readWriteHashMap;
00261 }
00262
00263
00264 static JSSVGPODTypeWrapper<PODType>* lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter)
00265 {
00266 ReadWriteHashMap& map(readWriteHashMap());
00267 PODTypeReadWriteHashInfo<PODType, PODTypeCreator> info(creator, getter, setter);
00268
00269 if (map.contains(info))
00270 return map.get(info);
00271
00272 JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>* wrapper = new JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>(creator, getter, setter);
00273 map.set(info, wrapper);
00274 return wrapper;
00275 }
00276
00277 static void forgetWrapper(JSSVGPODTypeWrapper<PODType>* wrapper)
00278 {
00279 ReadWriteHashMap& map(readWriteHashMap());
00280
00281 ReadWriteHashMapIterator it = map.begin();
00282 ReadWriteHashMapIterator end = map.end();
00283
00284 for (; it != end; ++it) {
00285 if (it->second != wrapper)
00286 continue;
00287
00288
00289 map.remove(it->first);
00290 break;
00291 }
00292 }
00293 };
00294
00295 };
00296
00297 #endif // ENABLE(SVG)
00298 #endif // JSSVGPODTypeWrapper_h