KHTML
JSSVGPODTypeWrapper.h
Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> 00003 * Copyright (C) 2008 Apple Inc. All rights reserved. 00004 * 00005 * Redistribution and use in source and binary forms, with or without 00006 * modification, are permitted provided that the following conditions 00007 * are met: 00008 * 1. Redistributions of source code must retain the above copyright 00009 * notice, this list of conditions and the following disclaimer. 00010 * 2. Redistributions in binary form must reproduce the above copyright 00011 * notice, this list of conditions and the following disclaimer in the 00012 * documentation and/or other materials provided with the distribution. 00013 * 00014 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 00015 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00016 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00017 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 00018 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00019 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00020 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00021 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00022 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00023 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00024 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 // Getter wrapper 00055 virtual operator PODType() = 0; 00056 00057 // Setter wrapper 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 // Getter wrapper 00081 virtual operator PODType() { return (m_creator.get()->*m_getter)(); } 00082 00083 // Setter wrapper 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 // Update callbacks 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 // Getter wrapper 00113 virtual operator PODType() { return m_podType; } 00114 00115 // Setter wrapper 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 // Getter wrapper 00146 virtual operator PODType() { return (m_creator.get()->*m_getter)(); } 00147 00148 // Setter wrapper 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 // Update callbacks 00162 RefPtr<SVGPODListItem<PODType> > m_creator; 00163 GetterMethod m_getter; 00164 SetterMethod m_setter; 00165 const QualifiedName& m_associatedAttributeName; 00166 }; 00167 00168 // Caching facilities 00169 template<typename PODType, typename PODTypeCreator> 00170 struct PODTypeReadWriteHashInfo { 00171 typedef PODType (PODTypeCreator::*GetterMethod)() const; 00172 typedef void (PODTypeCreator::*SetterMethod)(PODType); 00173 00174 // Empty value 00175 PODTypeReadWriteHashInfo() 00176 : creator(0) 00177 , getter(0) 00178 , setter(0) 00179 { 00180 } 00181 00182 // Deleted value 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 // Used for readwrite attributes only 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 // It's guaruanteed that there's just one object we need to take care of. 00289 map.remove(it->first); 00290 break; 00291 } 00292 } 00293 }; 00294 00295 }; 00296 00297 #endif // ENABLE(SVG) 00298 #endif // JSSVGPODTypeWrapper_h
KDE 4.6 API Reference