diff options
Diffstat (limited to 'WebCore/bindings/js/JSSVGPODTypeWrapper.h')
-rw-r--r-- | WebCore/bindings/js/JSSVGPODTypeWrapper.h | 286 |
1 files changed, 286 insertions, 0 deletions
diff --git a/WebCore/bindings/js/JSSVGPODTypeWrapper.h b/WebCore/bindings/js/JSSVGPODTypeWrapper.h new file mode 100644 index 0000000..1275950 --- /dev/null +++ b/WebCore/bindings/js/JSSVGPODTypeWrapper.h @@ -0,0 +1,286 @@ +/* + * Copyright (C) 2006, 2008 Nikolas Zimmermann <zimmermann@kde.org> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef JSSVGPODTypeWrapper_h +#define JSSVGPODTypeWrapper_h + +#if ENABLE(SVG) + +#include "Frame.h" +#include <wtf/RefCounted.h> +#include "SVGElement.h" + +#include <wtf/Assertions.h> +#include <wtf/HashMap.h> + +namespace WebCore { + +template<typename PODType> +class JSSVGPODTypeWrapper : public RefCounted<JSSVGPODTypeWrapper<PODType> > { +public: + JSSVGPODTypeWrapper() : RefCounted<JSSVGPODTypeWrapper<PODType> >(0) { } + virtual ~JSSVGPODTypeWrapper() { } + + // Getter wrapper + virtual operator PODType() = 0; + + // Setter wrapper + virtual void commitChange(PODType, SVGElement*) = 0; +}; + +template<typename PODType, typename PODTypeCreator> +class JSSVGPODTypeWrapperCreatorReadWrite : public JSSVGPODTypeWrapper<PODType> +{ +public: + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + JSSVGPODTypeWrapperCreatorReadWrite(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) + : m_creator(creator) + , m_getter(getter) + , m_setter(setter) + { + ASSERT(creator); + ASSERT(getter); + ASSERT(setter); + } + + virtual ~JSSVGPODTypeWrapperCreatorReadWrite() { } + + // Getter wrapper + virtual operator PODType() { return (m_creator.get()->*m_getter)(); } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement* context) + { + if (!m_setter) + return; + + (m_creator.get()->*m_setter)(type); + + if (context) + context->svgAttributeChanged(m_creator->associatedAttributeName()); + } + +private: + // Update callbacks + RefPtr<PODTypeCreator> m_creator; + GetterMethod m_getter; + SetterMethod m_setter; +}; + +template<typename PODType> +class JSSVGPODTypeWrapperCreatorReadOnly : public JSSVGPODTypeWrapper<PODType> +{ +public: + JSSVGPODTypeWrapperCreatorReadOnly(PODType type) + : m_podType(type) + { } + + virtual ~JSSVGPODTypeWrapperCreatorReadOnly() { } + + // Getter wrapper + virtual operator PODType() { return m_podType; } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement*) + { + m_podType = type; + } + +private: + PODType m_podType; +}; + +template<typename PODType> +class SVGPODListItem; + +template<typename PODType> +class JSSVGPODTypeWrapperCreatorForList : public JSSVGPODTypeWrapper<PODType> +{ +public: + typedef PODType (SVGPODListItem<PODType>::*GetterMethod)() const; + typedef void (SVGPODListItem<PODType>::*SetterMethod)(PODType); + + JSSVGPODTypeWrapperCreatorForList(SVGPODListItem<PODType>* creator, const QualifiedName& attributeName) + : m_creator(creator) + , m_getter(&SVGPODListItem<PODType>::value) + , m_setter(&SVGPODListItem<PODType>::setValue) + , m_associatedAttributeName(attributeName) + { + ASSERT(m_creator); + ASSERT(m_getter); + ASSERT(m_setter); + } + + virtual ~JSSVGPODTypeWrapperCreatorForList() { } + + // Getter wrapper + virtual operator PODType() { return (m_creator.get()->*m_getter)(); } + + // Setter wrapper + virtual void commitChange(PODType type, SVGElement* context) + { + if (!m_setter) + return; + + (m_creator.get()->*m_setter)(type); + + if (context) + context->svgAttributeChanged(m_associatedAttributeName); + } + +private: + // Update callbacks + RefPtr<SVGPODListItem<PODType> > m_creator; + GetterMethod m_getter; + SetterMethod m_setter; + const QualifiedName& m_associatedAttributeName; +}; + +// Caching facilities +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfo { + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + // Empty value + PODTypeReadWriteHashInfo() + : creator(0) + , getter(0) + , setter(0) + { } + + // Deleted value + explicit PODTypeReadWriteHashInfo(bool) + : creator(reinterpret_cast<PODTypeCreator*>(-1)) + , getter(0) + , setter(0) + { } + + PODTypeReadWriteHashInfo(PODTypeCreator* _creator, GetterMethod _getter, SetterMethod _setter) + : creator(_creator) + , getter(_getter) + , setter(_setter) + { + ASSERT(creator); + ASSERT(getter); + } + + bool operator==(const PODTypeReadWriteHashInfo& other) const + { + return creator == other.creator && getter == other.getter && setter == other.setter; + } + + PODTypeCreator* creator; + GetterMethod getter; + SetterMethod setter; +}; + +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfoHash { + static unsigned hash(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& info) + { + return StringImpl::computeHash((::UChar*) &info, sizeof(PODTypeReadWriteHashInfo<PODType, PODTypeCreator>) / sizeof(::UChar)); + } + + static bool equal(const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& a, const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& b) + { + return a == b; + } + + static const bool safeToCompareToEmptyOrDeleted = true; +}; + +template<typename PODType, typename PODTypeCreator> +struct PODTypeReadWriteHashInfoTraits : WTF::GenericHashTraits<PODTypeReadWriteHashInfo<PODType, PODTypeCreator> > { + static const bool emptyValueIsZero = true; + static const bool needsDestruction = false; + + static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& deletedValue() + { + static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key(true); + return key; + } + + static const PODTypeReadWriteHashInfo<PODType, PODTypeCreator>& emptyValue() + { + static PODTypeReadWriteHashInfo<PODType, PODTypeCreator> key; + return key; + } +}; + +template<typename PODType, typename PODTypeCreator> +class JSSVGPODTypeWrapperCache +{ +public: + typedef PODType (PODTypeCreator::*GetterMethod)() const; + typedef void (PODTypeCreator::*SetterMethod)(PODType); + + typedef HashMap<PODTypeReadWriteHashInfo<PODType, PODTypeCreator>, JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>*, PODTypeReadWriteHashInfoHash<PODType, PODTypeCreator>, PODTypeReadWriteHashInfoTraits<PODType, PODTypeCreator> > ReadWriteHashMap; + typedef typename ReadWriteHashMap::const_iterator ReadWriteHashMapIterator; + + static ReadWriteHashMap& readWriteHashMap() + { + static ReadWriteHashMap _readWriteHashMap; + return _readWriteHashMap; + } + + // Used for readwrite attributes only + static JSSVGPODTypeWrapper<PODType>* lookupOrCreateWrapper(PODTypeCreator* creator, GetterMethod getter, SetterMethod setter) + { + ReadWriteHashMap& map(readWriteHashMap()); + PODTypeReadWriteHashInfo<PODType, PODTypeCreator> info(creator, getter, setter); + + if (map.contains(info)) + return map.get(info); + + JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>* wrapper = new JSSVGPODTypeWrapperCreatorReadWrite<PODType, PODTypeCreator>(creator, getter, setter); + map.set(info, wrapper); + return wrapper; + } + + static void forgetWrapper(JSSVGPODTypeWrapper<PODType>* wrapper) + { + ReadWriteHashMap& map(readWriteHashMap()); + + ReadWriteHashMapIterator it = map.begin(); + ReadWriteHashMapIterator end = map.end(); + + for (; it != end; ++it) { + if (it->second != wrapper) + continue; + + // It's guaruanteed that there's just one object we need to take care of. + map.remove(it->first); + break; + } + } +}; + +}; + +#endif // ENABLE(SVG) +#endif // JSSVGPODTypeWrapper_h |