Use #pragma once in WebCore
[WebKit-https.git] / Source / WebCore / svg / properties / SVGAnimatedPropertyMacros.h
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
3  * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
4  * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public License
17  * along with this library; see the file COPYING.LIB.  If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21
22 #pragma once
23
24 #include "Element.h"
25 #include "SVGAnimatedProperty.h"
26 #include "SVGAttributeToPropertyMap.h"
27 #include "SVGPropertyTraits.h"
28 #include <wtf/NeverDestroyed.h>
29 #include <wtf/StdLibExtras.h>
30
31 namespace WebCore {
32
33 // SVGSynchronizableAnimatedProperty implementation
34 template<typename PropertyType>
35 struct SVGSynchronizableAnimatedProperty {
36     SVGSynchronizableAnimatedProperty()
37         : value(SVGPropertyTraits<PropertyType>::initialValue())
38         , shouldSynchronize(false)
39         , isValid(false)
40     {
41     }
42
43     template<typename ConstructorParameter1>
44     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
45         : value(value1)
46         , shouldSynchronize(false)
47         , isValid(false)
48     {
49     }
50
51     template<typename ConstructorParameter1, typename ConstructorParameter2>
52     SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
53         : value(value1, value2)
54         , shouldSynchronize(false)
55         , isValid(false)
56     {
57     }
58
59     void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
60     {
61         ownerElement->setSynchronizedLazyAttribute(attrName, value);
62     }
63
64     PropertyType value;
65     bool shouldSynchronize : 1;
66     bool isValid : 1;
67 };
68
69 // Property registration helpers
70 #define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
71 SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
72 { \
73     static NeverDestroyed<SVGAttributeToPropertyMap> map; \
74     return map; \
75 } \
76 \
77 static void registerAnimatedPropertiesFor##OwnerType() \
78 { \
79     auto& map = OwnerType::attributeToPropertyMap(); \
80     if (!map.isEmpty()) \
81         return; \
82     typedef OwnerType UseOwnerType;
83
84 #define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) map.addProperty(*UseOwnerType::LowerProperty##PropertyInfo());
85 #define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) map.addProperties(ClassName::attributeToPropertyMap());
86 #define END_REGISTER_ANIMATED_PROPERTIES }
87
88 // Property definition helpers (used in SVG*.cpp files)
89 #define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \
90 const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \
91     static NeverDestroyed<const SVGPropertyInfo> s_propertyInfo = SVGPropertyInfo \
92                         (AnimatedPropertyTypeEnum, \
93                          PropertyIsReadWrite, \
94                          DOMAttribute, \
95                          SVGDOMAttributeIdentifier, \
96                          &OwnerType::synchronize##UpperProperty, \
97                          &OwnerType::lookupOrCreate##UpperProperty##Wrapper); \
98     return &s_propertyInfo.get(); \
99
100
101 // Property declaration helpers (used in SVG*.h files)
102 #define BEGIN_DECLARE_ANIMATED_PROPERTIES_BASE(OwnerType) \
103 public: \
104     static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
105     virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() \
106     { \
107         return attributeToPropertyMap(); \
108     } \
109     typedef OwnerType UseOwnerType;
110
111 #define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \
112 public: \
113     static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
114     SVGAttributeToPropertyMap& localAttributeToPropertyMap() override \
115     { \
116         return attributeToPropertyMap(); \
117     } \
118     typedef OwnerType UseOwnerType;
119
120 #define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty, OverrideSpecifier) \
121 public: \
122     static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \
123     PropertyType& LowerProperty() const \
124     { \
125         if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
126             if (wrapper->isAnimating()) \
127                 return wrapper->currentAnimatedValue(); \
128         } \
129         return m_##LowerProperty.value; \
130     } \
131 \
132     PropertyType& LowerProperty##BaseValue() const OverrideSpecifier \
133     { \
134         return m_##LowerProperty.value; \
135     } \
136 \
137     void set##UpperProperty##BaseValue(const PropertyType& type, const bool validValue = true) OverrideSpecifier \
138     { \
139         m_##LowerProperty.value = type; \
140         m_##LowerProperty.isValid = validValue; \
141     } \
142 \
143     Ref<TearOffType> LowerProperty##Animated() \
144     { \
145         m_##LowerProperty.shouldSynchronize = true; \
146         return static_reference_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
147     } \
148 \
149     bool LowerProperty##IsValid() const \
150     { \
151         return m_##LowerProperty.isValid; \
152     } \
153 \
154 private: \
155     void synchronize##UpperProperty() \
156     { \
157         if (!m_##LowerProperty.shouldSynchronize) \
158             return; \
159         AtomicString value(SVGPropertyTraits<PropertyType>::toString(m_##LowerProperty.value)); \
160         m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \
161     } \
162 \
163     static Ref<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \
164     { \
165         ASSERT(maskedOwnerType); \
166         UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
167         return SVGAnimatedProperty::lookupOrCreateWrapper<UseOwnerType, TearOffType, PropertyType>(ownerType, LowerProperty##PropertyInfo(), ownerType->m_##LowerProperty.value); \
168     } \
169 \
170     static void synchronize##UpperProperty(SVGElement* maskedOwnerType) \
171     { \
172         ASSERT(maskedOwnerType); \
173         UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
174         ownerType->synchronize##UpperProperty(); \
175     } \
176 \
177     mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
178
179 #define END_DECLARE_ANIMATED_PROPERTIES 
180
181 // List specific definition/declaration helpers
182 #define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
183 DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty, ) \
184 void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
185 { \
186     if (auto wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \
187         wrapper->detachListWrappers(newListSize); \
188 }
189
190 } // namespace WebCore