2fe6ebaf11f3c1f2ba8841bcbd12070bd3dc5814
[platform/core/uifw/dali-core.git] / dali / internal / event / common / object-impl.h
1 #ifndef DALI_INTERNAL_OBJECT_H
2 #define DALI_INTERNAL_OBJECT_H
3
4 /*
5  * Copyright (c) 2021 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 <cstdint> // uint32_t
23
24 // INTERNAL INCLUDES
25 #include <dali/devel-api/common/owner-container.h>
26 #include <dali/devel-api/object/handle-devel.h>
27 #include <dali/internal/common/const-string.h>
28 #include <dali/internal/event/animation/animation-impl.h>
29 #include <dali/internal/event/common/event-thread-services.h>
30 #include <dali/internal/event/common/property-input-impl.h>
31 #include <dali/internal/event/common/property-metadata.h>
32 #include <dali/internal/update/common/property-base.h>
33 #include <dali/public-api/animation/constraint.h>
34 #include <dali/public-api/common/dali-vector.h>
35 #include <dali/public-api/common/vector-wrapper.h>
36 #include <dali/public-api/object/base-object.h>
37 #include <dali/public-api/object/handle.h>
38 #include <dali/public-api/object/property-index-ranges.h>
39 #include <dali/public-api/object/property-input.h>
40 #include <dali/public-api/object/property-map.h>
41 #include <dali/public-api/object/property-notification.h>
42 #include <dali/public-api/object/property.h>
43
44 namespace Dali
45 {
46 class PropertyNotification;
47
48 namespace Internal
49 {
50 class ConstraintBase;
51 class EventThreadServices;
52 class PropertyCondition;
53 class PropertyInputImpl;
54 class Stage;
55 class TypeInfo;
56
57 namespace SceneGraph
58 {
59 class PropertyBase;
60 class PropertyOwner;
61 } // namespace SceneGraph
62
63 using ConstraintContainer = std::vector<Dali::Constraint>;
64 using ConstraintIter      = ConstraintContainer::iterator;
65 using ConstraintConstIter = ConstraintContainer::const_iterator;
66
67 class KeyRef
68 {
69 public:
70   KeyRef(const Property::Key& key)
71   : mType(key.type)
72   {
73     if(mType == Property::Key::STRING)
74     {
75       mString = ConstString(key.stringKey);
76     }
77     else
78     {
79       mIndex = key.indexKey;
80     }
81   }
82   KeyRef(ConstString str)
83   : mType(Property::Key::STRING)
84   {
85     mString = str;
86   }
87   KeyRef(Property::Index index)
88   : mType(Property::Key::INDEX)
89   {
90     mIndex = index;
91   }
92   Property::Key::Type mType;
93   Property::Index     mIndex{Property::INVALID_INDEX};
94   ConstString         mString;
95 };
96
97 /**
98  * A base class for objects which optionally provide properties.
99  * The concrete derived class is responsible for implementing the property system methods.
100  * Classes may derive from Dali::BaseObject, until any properties are required.
101  *
102  * An object for a property-owning object in the scene-graph.
103  * This provides an interface for observing the addition/removal of scene-objects.
104  *
105  * The derived class should either:
106  *   a) Create their own scene-graph object and pass it to Object constructor.
107  *   b) pass nullptr to Object constructor, in this case Object will create default scene object for property handling
108  */
109 class Object : public Dali::BaseObject
110 {
111 public:
112   using Capability = Dali::Handle::Capability;
113
114   class Observer
115   {
116   public:
117     /**
118      * Called immediately after the object has created & passed ownership of a scene-graph object.
119      * @param[in] object The object object.
120      */
121     virtual void SceneObjectAdded(Object& object) = 0;
122
123     /**
124      * Called shortly before the object sends a message to remove its scene object.
125      * @param[in] object The object object.
126      */
127     virtual void SceneObjectRemoved(Object& object) = 0;
128
129     /**
130      * Called shortly before the object itself is destroyed; no further callbacks will be received.
131      * @param[in] object The object object.
132      */
133     virtual void ObjectDestroyed(Object& object) = 0;
134
135   protected:
136     /**
137      * Virtual destructor
138      */
139     virtual ~Observer() = default;
140   };
141
142   /**
143    * Creates a new object
144    *
145    * @return an smart pointer to the object
146    */
147   static IntrusivePtr<Object> New();
148
149   /**
150    * Add an observer to the object.
151    * @param[in] observer The observer to add.
152    */
153   void AddObserver(Observer& observer);
154
155   /**
156    * Remove an observer from the object
157    * @pre The observer has already been added.
158    * @param[in] observer The observer to remove.
159    */
160   void RemoveObserver(Observer& observer);
161
162   /**
163    * @copydoc Dali::Handle::Supports()
164    */
165   bool Supports(Capability capability) const;
166
167   /**
168    * @copydoc Dali::Handle::GetPropertyCount()
169    */
170   uint32_t GetPropertyCount() const;
171
172   /**
173    * @copydoc Dali::Handle::GetPropertyName()
174    */
175   std::string_view GetPropertyName(Property::Index index) const;
176
177   /**
178    * @copydoc Dali::Handle::GetPropertyIndex()
179    */
180   Property::Index GetPropertyIndex(KeyRef key) const;
181
182   /**
183    * @copydoc Dali::Handle::IsPropertyWritable()
184    */
185   bool IsPropertyWritable(Property::Index index) const;
186
187   /**
188    * @copydoc Dali::Handle::IsPropertyAnimatable()
189    */
190   bool IsPropertyAnimatable(Property::Index index) const;
191
192   /**
193    * @copydoc Dali::Handle::IsPropertyAConstraintInput()
194    */
195   bool IsPropertyAConstraintInput(Property::Index index) const;
196
197   /**
198    * @copydoc Dali::Handle::GetPropertyType()
199    */
200   Property::Type GetPropertyType(Property::Index index) const;
201
202   /**
203    * @copydoc Dali::Handle::SetProperty()
204    */
205   void SetProperty(Property::Index index, Property::Value propertyValue);
206
207   /**
208    * @copydoc Dali::Handle::GetProperty()
209    */
210   Property::Value GetProperty(Property::Index index) const;
211
212   /**
213    * @brief Retrieves the latest value of the property on the scene-graph.
214    * @param[in]  index  The index of the property required.
215    * @return The latest value of the property on the scene-graph.
216    */
217   Property::Value GetCurrentProperty(Property::Index index) const;
218
219   /**
220    * @copydoc Dali::Handle::GetPropertyIndices()
221    */
222   void GetPropertyIndices(Property::IndexContainer& indices) const;
223
224   /**
225    * @copydoc Dali::Handle::RegisterProperty()
226    */
227   Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue);
228
229   /**
230    * @copydoc Dali::Handle::RegisterProperty()
231    */
232   Property::Index RegisterProperty(std::string_view name, Property::Index key, Property::Value propertyValue);
233
234   /**
235    * @copydoc Dali::DevelHandle::SetProperties()
236    */
237   void SetProperties(const Property::Map& properties);
238
239   /**
240    * @copydoc Dali::DevelHandle::GetProperties()
241    */
242   void GetProperties(Property::Map& properties);
243
244   /**
245    * @copydoc Dali::Handle::RegisterProperty(std::string name, Property::Value propertyValue, Property::AccessMode accessMode)
246    */
247   Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue, Property::AccessMode accessMode);
248
249   /**
250    * @brief Implementing method for this override
251    */
252   Property::Index RegisterProperty(std::string_view     name,
253                                    Property::Index      key,
254                                    Property::Value      propertyValue,
255                                    Property::AccessMode accessMode);
256
257   /**
258    * @brief returns true if the custom property exists on this object.
259    *
260    * @note The property may be defined for a type within the type registry, but it isn't explicity
261    * defined in every consequent instantiation. It can be automatically added, e.g. parenting an actor
262    * automatically registers it's parent container's child properties.
263    *
264    * @param[in] handle The handle of the object to test
265    * @param[in] index The property index to look for.
266    * @return true if the property exists on the object, false otherwise.
267    */
268   bool DoesCustomPropertyExist(Property::Index index);
269
270   /**
271    * @copydoc Dali::Handle::AddPropertyNotification()
272    */
273   Dali::PropertyNotification AddPropertyNotification(Property::Index                index,
274                                                      int32_t                        componentIndex,
275                                                      const Dali::PropertyCondition& condition);
276
277   /**
278    * @copydoc Dali::Handle::RemovePropertyNotification()
279    */
280   void RemovePropertyNotification(Dali::PropertyNotification propertyNotification);
281
282   /**
283    * @copydoc Dali::Handle::RemovePropertyNotifications()
284    */
285   void RemovePropertyNotifications();
286
287   /**
288    * Notifies that a property is being animated.
289    * @param[in] animation The animation animating the property.
290    * @param[in] index The index of the property.
291    * @param[in] value The value of the property after the animation.
292    * @param[in] animationType Whether the property value given is the target or a relative value.
293    */
294   void NotifyPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType);
295
296   /******************************** Uniform Mappings ********************************/
297
298   /**
299    * Adds uniform mapping for given property
300    * @param propertyIndex index of the property
301    * @param uniformName name of the uniform (same as property name)
302    */
303   void AddUniformMapping(Property::Index propertyIndex, ConstString uniformName) const;
304
305   /**
306    * Removes uniform mapping for given property
307    * @param uniformName name of the uniform (same as property name)
308    */
309   void RemoveUniformMapping(const std::string& uniformName) const;
310
311   /******************************** Constraints ********************************/
312
313   /**
314    * Apply a constraint to an Object.
315    * @param[in] constraint The constraint to apply.
316    */
317   void ApplyConstraint(ConstraintBase& constraint);
318
319   /**
320    * Remove one constraint from an Object.
321    * @param[in] constraint The constraint to remove.
322    */
323   void RemoveConstraint(ConstraintBase& constraint);
324
325   /**
326    * Remove all constraints from a Object.
327    */
328   void RemoveConstraints();
329
330   /**
331    * @copydoc Dali::Handle::RemoveConstraints( uint32_t )
332    */
333   void RemoveConstraints(uint32_t tag);
334
335   /**
336    * Called by TypeInfo to set the type-info that this object-impl is created by.
337    * @param[in] typeInfo The TypeInfo that creates this object-impl.
338    */
339   void SetTypeInfo(const TypeInfo* typeInfo);
340
341   /**
342    * @return the index from which custom properties start
343    */
344   uint32_t CustomPropertyStartIndex()
345   {
346     return PROPERTY_CUSTOM_START_INDEX;
347   }
348
349   /**
350    * Retrieve the scene-graph object added by this object.
351    * @return reference to the scene-graph object, it will always exist
352    */
353   const SceneGraph::PropertyOwner& GetSceneObject() const;
354
355   /********************  Can be overridden by deriving classes ********************/
356
357   /**
358    * Retrieve an animatable property owned by the scene-graph object.
359    * @pre -1 < index < GetPropertyCount().
360    * @param[in] index The index of the property.
361    * @return A dereferenceable pointer to a property, or NULL if a scene-object does not exist with this property.
362    */
363   virtual const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty(Property::Index index) const;
364
365   /**
366    * Retrieve a constraint input-property owned by the scene-graph object.
367    * @pre -1 < index < GetPropertyCount().
368    * @param[in] index The index of the property.
369    * @return A dereferenceable pointer to an input property, or NULL if a scene-object does not exist with this property.
370    */
371   virtual const PropertyInputImpl* GetSceneObjectInputProperty(Property::Index index) const;
372
373   /**
374    * Query whether the property is a component of a scene-graph property.
375    * @pre -1 < index < GetPropertyCount().
376    * @param[in] index The index of the property.
377    * @return The index or Property::INVALID_COMPONENT_INDEX.
378    */
379   virtual int32_t GetPropertyComponentIndex(Property::Index index) const;
380
381   /**
382    * Query whether playing an animation is possible or not.
383    * @return true if playing an animation is possible.
384    */
385   virtual bool IsAnimationPossible() const
386   {
387     return true;
388   }
389
390   /**
391    * @copydoc Dali::Handle::PropertySetSignal()
392    */
393   Handle::PropertySetSignalType& PropertySetSignal();
394
395 protected:
396   /**
397    * Constructor. Protected so use New to construct an instance of this class
398    *
399    * @param sceneObject the scene graph property owner
400    */
401   Object(const SceneGraph::PropertyOwner* sceneObject);
402
403   /**
404    * A reference counted object may only be deleted by calling Unreference()
405    */
406   ~Object() override;
407
408   /**
409    * Called immediately by derived classes, after the scene-object has been created & passed to the scene-graph.
410    */
411   void OnSceneObjectAdd();
412
413   /**
414    * Called by derived classes, shortly before send a message to remove the scene-object.
415    */
416   void OnSceneObjectRemove();
417
418   /**
419    * For overriding by derived classes to return the parent of this object.
420    */
421   virtual Object* GetParentObject() const
422   {
423     // By default the Object does not have a parent
424     return nullptr;
425   };
426
427   /**
428    * For use in derived classes.
429    * This is called after a property is set.
430    * @param [in] index The index of the property.
431    * @param [in] propertyValue The value of the property.
432    */
433   virtual void OnPropertySet(Property::Index index, const Property::Value& propertyValue)
434   {
435   }
436
437   /**
438    * Retrieves the TypeInfo for this object. Only retrieves it from the type-registry once and then stores a pointer
439    * to it locally there-after. The type info will not change during the life-time of the application.
440    * @return The type-info for this object (Can be NULL)
441    */
442   const TypeInfo* GetTypeInfo() const;
443
444   /**
445    * Helper to find custom property
446    * @param index
447    * @return pointer to the property
448    */
449   CustomPropertyMetadata* FindCustomProperty(Property::Index index) const;
450
451   /**
452    * Helper to find animatable property
453    * @param index
454    * @return pointer to the property
455    */
456   AnimatablePropertyMetadata* FindAnimatableProperty(Property::Index index) const;
457
458   /**
459    * Helper to register a scene-graph property
460    * @param [in] name The name of the property.
461    * @param [in] key The key of the property
462    * @param [in] index The index of the property
463    * @param [in] value The value of the property.
464    * @return The index of the registered property or Property::INVALID_INDEX if registration failed.
465    */
466   Property::Index RegisterSceneGraphProperty(ConstString name, Property::Index key, Property::Index index, Property::Value propertyValue) const;
467
468   /**
469    * Registers animatable scene property
470    * @param typeInfo to check the default value
471    * @param index of the property to register
472    * @param value initial value or nullptr
473    */
474   void RegisterAnimatableProperty(const TypeInfo& typeInfo, Property::Index index, const Property::Value* value) const;
475
476   /**
477    * Check whether the animatable property is registered already, if not then register on.
478    * @param [in] index The index of the property
479    * @param [in] value optional value for the property
480    * @return pointer to the property metadata
481    */
482   AnimatablePropertyMetadata* GetSceneAnimatableProperty(Property::Index index, const Property::Value* value) const;
483
484   /**
485    * Resolve the index and name of child properties if any.
486    */
487   void ResolveChildProperties();
488
489 private: // Default property extensions for derived classes
490   /**
491    * Set the value of a default property.
492    * @pre The property types match i.e. propertyValue.GetType() is equal to GetPropertyType(index).
493    * @param [in] index The index of the property.
494    * @param [in] propertyValue The new value of the property.
495    */
496   virtual void SetDefaultProperty(Property::Index index, const Property::Value& propertyValue);
497
498   /**
499    * Retrieve a default property value.
500    * @param [in] index The index of the property.
501    * @return The property value.
502    */
503   virtual Property::Value GetDefaultProperty(Property::Index index) const;
504
505   /**
506    * Retrieve the latest scene-graph value of a default property.
507    * @param[in] index The index of the property.
508    * @return The latest scene-graph value of a default property.
509    */
510   virtual Property::Value GetDefaultPropertyCurrentValue(Property::Index index) const;
511
512   /**
513    * Notifies that a default property is being animated so the deriving class should update the cached value.
514    * @param[in] animation The animation animating the property.
515    * @param[in] index The index of the property.
516    * @param[in] value The value of the property after the animation.
517    * @param[in] animationType Whether the property value given is the target or a relative value.
518    */
519   virtual void OnNotifyDefaultPropertyAnimation(Animation& animation, Property::Index index, const Property::Value& value, Animation::Type propertyChangeType)
520   {
521   }
522
523 private:
524   // no default, copy or assignment
525   Object()                  = delete;
526   Object(const Object& rhs) = delete;
527   Object& operator=(const Object& rhs) = delete;
528
529   /**
530    * Enable property notifications in scene graph
531    */
532   void EnablePropertyNotifications();
533
534   /**
535    * Enable property notifications in scene graph
536    */
537   void DisablePropertyNotifications();
538
539   /**
540    * Get the latest value of the property on the scene-graph.
541    * @param[in] entry An entry from the property lookup container.
542    * @return The latest value of the property.
543    */
544   Property::Value GetCurrentPropertyValue(const PropertyMetadata& entry) const;
545
546   /**
547    * Set the value of scene graph property.
548    * @param [in] index The index of the property.
549    * @param [in] entry An entry from the property lookup container.
550    * @param [in] value The new value of the property.
551    */
552   virtual void SetSceneGraphProperty(Property::Index index, const PropertyMetadata& entry, const Property::Value& value);
553
554 protected:
555   /**
556    * Get the event thread services object - used for sending messages to the scene graph
557    * Assert if called from the wrong thread.
558    * This is intentionally inline for performance reasons.
559    *
560    * @return The event thread services object
561    */
562   inline EventThreadServices& GetEventThreadServices()
563   {
564     DALI_ASSERT_ALWAYS(EventThreadServices::IsCoreRunning());
565     return mEventThreadServices;
566   }
567
568   /**
569    * Get the event thread services object - used for sending messages to the scene graph
570    * Assert if called from the wrong thread
571    * This is intentionally inline for performance reasons.
572    *
573    * @return The event thread services object
574    */
575   inline const EventThreadServices& GetEventThreadServices() const
576   {
577     DALI_ASSERT_ALWAYS(EventThreadServices::IsCoreRunning());
578     return mEventThreadServices;
579   }
580
581 private:
582   EventThreadServices& mEventThreadServices;
583
584 protected:
585   // mutable because it's lazy initialised and GetSceneObject has to be const so it can be called from const methods
586   // const to prevent accidentally calling setters directly from event thread
587   // protected to allow fast access from derived classes that have their own scene object (no function call overhead)
588   mutable const SceneGraph::PropertyOwner* mUpdateObject; ///< Reference to object to hold the scene graph properties
589
590 private:
591   Dali::Vector<Observer*>                   mObservers;
592   mutable OwnerContainer<PropertyMetadata*> mCustomProperties;     ///< Used for accessing custom Node properties
593   mutable OwnerContainer<PropertyMetadata*> mAnimatableProperties; ///< Used for accessing animatable Node properties
594   mutable const TypeInfo*                   mTypeInfo;             ///< The type-info for this object, mutable so it can be lazy initialized from const method if it is required
595
596   ConstraintContainer* mConstraints; ///< Container of owned -constraints.
597
598   using PropertyNotificationContainer = std::vector<Dali::PropertyNotification>;
599   PropertyNotificationContainer* mPropertyNotifications; ///< Container of owned property notifications.
600
601   Handle::PropertySetSignalType mPropertySetSignal;
602 };
603
604 } // namespace Internal
605
606 // Helpers for public-api forwarding methods
607
608 inline Internal::Object& GetImplementation(Dali::Handle& object)
609 {
610   DALI_ASSERT_ALWAYS(object && "Object handle is empty");
611
612   BaseObject& handle = object.GetBaseObject();
613
614   return static_cast<Internal::Object&>(handle);
615 }
616
617 inline const Internal::Object& GetImplementation(const Dali::Handle& object)
618 {
619   DALI_ASSERT_ALWAYS(object && "Object handle is empty");
620
621   const BaseObject& handle = object.GetBaseObject();
622
623   return static_cast<const Internal::Object&>(handle);
624 }
625
626 } // namespace Dali
627
628 #endif // DALI_INTERNAL_OBJECT_H