[dali_2.3.27] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / common / property-metadata.h
1 #ifndef DALI_INTERNAL_PROPERTY_METADATA_H
2 #define DALI_INTERNAL_PROPERTY_METADATA_H
3
4 /*
5  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <algorithm>
23 #include <utility>
24
25 // INTERNAL INCLUDES
26 #include <dali/internal/common/const-string.h>
27 #include <dali/public-api/common/constants.h>
28 #include <dali/public-api/object/property-value.h>
29 #include <dali/public-api/object/property.h>
30
31 namespace Dali
32 {
33 namespace Internal
34 {
35 namespace SceneGraph
36 {
37 class PropertyBase;
38 }
39
40 /**
41  * @brief Base class for the Metadata required by custom and registered animatable properties.
42  *
43  * The value type field should be queried, before accessing the scene-graph property:
44  *
45  * @code
46  * void Example(PropertyEntry entry)
47  * {
48  *   if (entry.value.GetType() == Property::VECTOR3)
49  *   {
50  *     SceneGraph::AnimatableProperty<Vector3>* property = dynamic_cast< SceneGraph::AnimatableProperty<Vector3>* >( entry.property );
51  *     ...
52  *   }
53  * @endcode
54  *
55  */
56 class PropertyMetadata
57 {
58 public:
59   /**
60    * @brief Virtual Destructor.
61    */
62   virtual ~PropertyMetadata() = default;
63
64   /**
65    * @brief Returns whether the property is animatable (i.e. if its a scene graph property).
66    * @return True if animatable, false otherwise
67    */
68   bool IsAnimatable(void) const
69   {
70     return nullptr != mSceneGraphProperty;
71   }
72
73   /**
74    * @brief Whether the property can be written to.
75    * @return True if the property can be written to, false otherwise
76    */
77   bool IsWritable(void) const
78   {
79     return mWritable;
80   }
81
82   /**
83    * @brief Retrieves the scene-graph property.
84    * @return The scene graph property
85    *
86    * @note Should only be called if the scene-graph property was passed in originally. Will debug assert if the stored property is NULL.
87    */
88   const SceneGraph::PropertyBase* GetSceneGraphProperty() const
89   {
90     DALI_ASSERT_DEBUG(mSceneGraphProperty && "Accessing uninitialized SceneGraph property");
91     return mSceneGraphProperty;
92   }
93
94   /**
95    * @brief Retrieve the type of the property.
96    * @return Type of the held property value
97    */
98   inline Property::Type GetType() const
99   {
100     return value.GetType();
101   }
102
103   /**
104    * Set the cached value of the property.
105    * @param[in] value The propertyValue to set.
106    */
107   void SetPropertyValue(const Property::Value& propertyValue);
108
109   /**
110    * Get the cached value of a the property.
111    * @return The cached value of the property.
112    */
113   Property::Value GetPropertyValue() const;
114
115   /**
116    * Modifies the stored value by the relativeValue.
117    * @param[in] relativeValue The value to change by.
118    */
119   void AdjustPropertyValueBy(const Property::Value& relativeValue);
120
121 protected:
122   /**
123    * @brief Constructor to create Metadata for a property.
124    * @param[in] propertyValue       The value of the property (this is used by the event thread)
125    * @param[in] sceneGraphProperty  A pointer to the scene-graph owned property
126    * @param[in] writable            Whether the property is writable
127    */
128   PropertyMetadata(Property::Value                 propertyValue,
129                    const SceneGraph::PropertyBase* sceneGraphProperty,
130                    bool                            writable)
131   : value(mStoredValue),
132     componentIndex(Property::INVALID_COMPONENT_INDEX),
133     mStoredValue(std::move(propertyValue)),
134     mSceneGraphProperty(sceneGraphProperty),
135     mWritable(writable)
136   {
137   }
138
139   /**
140    * @brief Constructor to create Metadata for a component of another property.
141    * @param[in] sceneGraphProperty      A pointer to the scene-graph owned property
142    * @param[in] writable                Whether the property is writable
143    * @param[in] baseValueRef            A reference to the metadata of the base animatable property
144    * @param[in] propertyComponentIndex  The component index of the property
145    */
146   PropertyMetadata(const SceneGraph::PropertyBase* sceneGraphProperty, bool writable, Property::Value& baseValueRef, int32_t propertyComponentIndex)
147   : value(baseValueRef),
148     componentIndex(propertyComponentIndex),
149     mStoredValue(),
150     mSceneGraphProperty(sceneGraphProperty),
151     mWritable(writable)
152   {
153   }
154
155 private:
156   // Not implemented
157   PropertyMetadata(const PropertyMetadata&);
158   PropertyMetadata& operator=(const PropertyMetadata&);
159
160 public: // Data
161   /**
162    * @brief The value of this property used to read/write by the event thread.
163    *
164    * If this PropertyMetadata is for property component, then refers to the value in the PropertyMetadata of the base property
165    * to ensure the components are kept in sync with the overall value on the event thread.
166    * Otherwise, this refers to mStoredValue.
167    */
168   Property::Value& value;
169
170   /**
171    * @brief The index of the property component.
172    */
173   int32_t componentIndex;
174
175 private:
176   Property::Value                 mStoredValue;        ///< The cached property value used to read/write by the event thread
177   const SceneGraph::PropertyBase* mSceneGraphProperty; ///< A pointer to a scene-graph property; should not be modified from actor-thread
178   bool                            mWritable : 1;       ///< Whether the property is writable
179 };
180
181 /**
182  * @brief Metadata for a registered animatable property.
183  */
184 class AnimatablePropertyMetadata : public PropertyMetadata
185 {
186 public:
187   /**
188    * @brief Constructs metadata for a registered animatable property.
189    * @param[in] propertyIndex           The index of the animatable property
190    * @param[in] propertyComponentIndex  The component index of the animatable property
191    * @param[in] propertyValue           The value of the property (this is used by the event thread)
192    * @param[in] sceneGraphProperty      A pointer to the scene-graph owned property
193    *
194    * @note The base animatable property MUST be created before the component animatable property.
195    */
196   AnimatablePropertyMetadata(Property::Index                 propertyIndex,
197                              Property::Value                 propertyValue,
198                              const SceneGraph::PropertyBase* sceneGraphProperty)
199   : PropertyMetadata(std::move(propertyValue), sceneGraphProperty, true),
200     index(propertyIndex)
201   {
202     DALI_ASSERT_DEBUG(sceneGraphProperty && "Uninitialized scene-graph property");
203   }
204
205   /**
206    * @brief Constructs metadata for a registered animatable component of another property.
207    * @param[in] propertyIndex           The index of the animatable property
208    * @param[in] propertyComponentIndex  The component index of the animatable property
209    * @param[in] baseValueRef            A reference to the metadata of the base animatable property
210    * @param[in] sceneGraphProperty      A pointer to the scene-graph owned property
211    *
212    * @note The base animatable property MUST be created before the component animatable property.
213    */
214   AnimatablePropertyMetadata(Property::Index                 propertyIndex,
215                              int                             propertyComponentIndex,
216                              Property::Value&                baseValueRef,
217                              const SceneGraph::PropertyBase* sceneGraphProperty)
218   : PropertyMetadata(sceneGraphProperty, true, baseValueRef, propertyComponentIndex),
219     index(propertyIndex)
220   {
221     DALI_ASSERT_DEBUG(sceneGraphProperty && "Uninitialized scene-graph property");
222   }
223
224   /**
225    * @brief Destructor.
226    */
227   ~AnimatablePropertyMetadata() override = default;
228
229 private:
230   // Not implemented
231   AnimatablePropertyMetadata();
232   AnimatablePropertyMetadata(const AnimatablePropertyMetadata&);
233   AnimatablePropertyMetadata& operator=(const AnimatablePropertyMetadata&);
234
235 public:                  // Data
236   Property::Index index; ///< The index of the property.
237 };
238
239 class CustomPropertyMetadata : public PropertyMetadata
240 {
241 public:
242   /**
243    * Constructs Metadata for scene-graph-based custom properties, i.e. animatable custom properties.
244    * @param[in] propertyName        The name of the custom property
245    * @param[in] propertyKey         The key of the custom property
246    * @param[in] propertyValue       The value of the property (this is used by the event thread)
247    * @param[in] sceneGraphProperty  A pointer to the scene-graph owned property
248    *
249    * @note A valid sceneGraphProperty is mandatory otherwise this will debug assert.
250    */
251   CustomPropertyMetadata(ConstString                     propertyName,
252                          Property::Index                 propertyKey,
253                          Property::Value                 propertyValue,
254                          const SceneGraph::PropertyBase* sceneGraphProperty)
255   : PropertyMetadata(std::move(propertyValue), sceneGraphProperty, true),
256     name(propertyName),
257     key(propertyKey),
258     childPropertyIndex(Property::INVALID_INDEX)
259   {
260     DALI_ASSERT_DEBUG(sceneGraphProperty && "Uninitialized scene-graph property");
261   }
262
263   /**
264    * Constructs metadata for event side only custom properties.
265    * @param[in] propertyName   The name of the custom property
266    * @param[in] propertyValue  The value of the property (this is used by the event thread)
267    * @param[in] accessMode     The access mode of the custom property (writable, animatable etc)
268    *
269    * @note The access mode MUST NOT be animatable otherwise this will debug assert.
270    */
271   CustomPropertyMetadata(ConstString          propertyName,
272                          Property::Value      propertyValue,
273                          Property::AccessMode accessMode)
274   : PropertyMetadata(std::move(propertyValue), nullptr, (accessMode != Property::READ_ONLY)),
275     name(propertyName),
276     key(Property::INVALID_KEY),
277     childPropertyIndex(Property::INVALID_INDEX)
278   {
279     DALI_ASSERT_DEBUG(accessMode != Property::ANIMATABLE && "Event side only properties should not be animatable");
280   }
281
282   /**
283    * @brief Destructor.
284    */
285   ~CustomPropertyMetadata() override = default;
286
287 private:
288   // Not implemented
289   CustomPropertyMetadata();
290   CustomPropertyMetadata(const CustomPropertyMetadata&);
291   CustomPropertyMetadata& operator=(const CustomPropertyMetadata&);
292
293 public:                               // Data
294   ConstString     name;               ///< The name of the property.
295   Property::Index key;                ///< The key of the property.
296   Property::Index childPropertyIndex; ///< The index as a child property.
297 };
298
299 } // namespace Internal
300
301 } // namespace Dali
302
303 #endif // DALI_INTERNAL_PROPERTY_METADATA_H