1 #ifndef DALI_INTERNAL_OBJECT_H
2 #define DALI_INTERNAL_OBJECT_H
5 * Copyright (c) 2020 Samsung Electronics Co., Ltd.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <cstdint> // uint32_t
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>
47 class PropertyNotification;
52 class EventThreadServices;
53 class PropertyCondition;
54 class PropertyInputImpl;
64 using ConstraintContainer = std::vector< Dali::Constraint >;
65 using ConstraintIter = ConstraintContainer::iterator;
66 using ConstraintConstIter = ConstraintContainer::const_iterator;
71 KeyRef(const Property::Key& key)
74 if(mType == Property::Key::STRING)
76 mString = ConstString(key.stringKey);
80 mIndex = key.indexKey;
83 KeyRef(ConstString str)
84 : mType(Property::Key::STRING)
88 KeyRef(Property::Index index)
89 : mType(Property::Key::INDEX)
93 Property::Key::Type mType;
94 Property::Index mIndex{Property::INVALID_INDEX};
99 * A base class for objects which optionally provide properties.
100 * The concrete derived class is responsible for implementing the property system methods.
101 * Classes may derive from Dali::BaseObject, until any properties are required.
103 * An object for a property-owning object in the scene-graph.
104 * This provides an interface for observing the addition/removal of scene-objects.
106 * The derived class should either:
107 * a) Create their own scene-graph object and pass it to Object constructor.
108 * b) pass nullptr to Object constructor, in this case Object will create default scene object for property handling
110 class Object : public Dali::BaseObject
114 using Capability = Dali::Handle::Capability;
121 * Called immediately after the object has created & passed ownership of a scene-graph object.
122 * @param[in] object The object object.
124 virtual void SceneObjectAdded(Object& object) = 0;
127 * Called shortly before the object sends a message to remove its scene object.
128 * @param[in] object The object object.
130 virtual void SceneObjectRemoved(Object& object) = 0;
133 * Called shortly before the object itself is destroyed; no further callbacks will be received.
134 * @param[in] object The object object.
136 virtual void ObjectDestroyed(Object& object) = 0;
143 virtual ~Observer() = default;
147 * Creates a new object
149 * @return an smart pointer to the object
151 static IntrusivePtr<Object> New();
154 * Add an observer to the object.
155 * @param[in] observer The observer to add.
157 void AddObserver( Observer& observer );
160 * Remove an observer from the object
161 * @pre The observer has already been added.
162 * @param[in] observer The observer to remove.
164 void RemoveObserver( Observer& observer );
167 * @copydoc Dali::Handle::Supports()
169 bool Supports( Capability capability ) const;
172 * @copydoc Dali::Handle::GetPropertyCount()
174 uint32_t GetPropertyCount() const;
177 * @copydoc Dali::Handle::GetPropertyName()
179 std::string_view GetPropertyName(Property::Index index) const;
182 * @copydoc Dali::Handle::GetPropertyIndex()
184 Property::Index GetPropertyIndex(KeyRef key) const;
187 * @copydoc Dali::Handle::IsPropertyWritable()
189 bool IsPropertyWritable( Property::Index index ) const;
192 * @copydoc Dali::Handle::IsPropertyAnimatable()
194 bool IsPropertyAnimatable( Property::Index index ) const;
197 * @copydoc Dali::Handle::IsPropertyAConstraintInput()
199 bool IsPropertyAConstraintInput( Property::Index index ) const;
202 * @copydoc Dali::Handle::GetPropertyType()
204 Property::Type GetPropertyType( Property::Index index ) const;
207 * @copydoc Dali::Handle::SetProperty()
209 void SetProperty(Property::Index index, Property::Value propertyValue);
212 * @copydoc Dali::Handle::GetProperty()
214 Property::Value GetProperty( Property::Index index ) const;
217 * @brief Retrieves the latest value of the property on the scene-graph.
218 * @param[in] index The index of the property required.
219 * @return The latest value of the property on the scene-graph.
221 Property::Value GetCurrentProperty( Property::Index index ) const;
224 * @copydoc Dali::Handle::GetPropertyIndices()
226 void GetPropertyIndices( Property::IndexContainer& indices ) const;
229 * @copydoc Dali::Handle::RegisterProperty()
231 Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue);
234 * @copydoc Dali::Handle::RegisterProperty()
236 Property::Index RegisterProperty(std::string_view name, Property::Index key, Property::Value propertyValue);
239 * @copydoc Dali::DevelHandle::SetProperties()
241 void SetProperties( const Property::Map& properties );
244 * @copydoc Dali::DevelHandle::GetProperties()
246 void GetProperties( Property::Map& properties );
249 * @copydoc Dali::Handle::RegisterProperty(std::string name, Property::Value propertyValue, Property::AccessMode accessMode)
251 Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue, Property::AccessMode accessMode);
254 * @brief Implementing method for this override
256 Property::Index RegisterProperty(std::string_view name,
258 Property::Value propertyValue,
259 Property::AccessMode accessMode);
262 * @brief returns true if the custom property exists on this object.
264 * @note The property may be defined for a type within the type registry, but it isn't explicity
265 * defined in every consequent instantiation. It can be automatically added, e.g. parenting an actor
266 * automatically registers it's parent container's child properties.
268 * @param[in] handle The handle of the object to test
269 * @param[in] index The property index to look for.
270 * @return true if the property exists on the object, false otherwise.
272 bool DoesCustomPropertyExist( Property::Index index );
275 * @copydoc Dali::Handle::AddPropertyNotification()
277 Dali::PropertyNotification AddPropertyNotification( Property::Index index,
278 int32_t componentIndex,
279 const Dali::PropertyCondition& condition );
282 * @copydoc Dali::Handle::RemovePropertyNotification()
284 void RemovePropertyNotification( Dali::PropertyNotification propertyNotification );
287 * @copydoc Dali::Handle::RemovePropertyNotifications()
289 void RemovePropertyNotifications();
292 * Notifies that a property is being animated.
293 * @param[in] animation The animation animating the property.
294 * @param[in] index The index of the property.
295 * @param[in] value The value of the property after the animation.
296 * @param[in] animationType Whether the property value given is the target or a relative value.
298 void NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType );
300 /******************************** Uniform Mappings ********************************/
303 * Adds uniform mapping for given property
304 * @param propertyIndex index of the property
305 * @param uniformName name of the uniform (same as property name)
307 void AddUniformMapping(Property::Index propertyIndex, ConstString uniformName) const;
310 * Removes uniform mapping for given property
311 * @param uniformName name of the uniform (same as property name)
313 void RemoveUniformMapping( const std::string& uniformName ) const;
315 /******************************** Constraints ********************************/
318 * Apply a constraint to an Object.
319 * @param[in] constraint The constraint to apply.
321 void ApplyConstraint( ConstraintBase& constraint );
324 * Remove one constraint from an Object.
325 * @param[in] constraint The constraint to remove.
327 void RemoveConstraint( ConstraintBase& constraint );
330 * Remove all constraints from a Object.
332 void RemoveConstraints();
335 * @copydoc Dali::Handle::RemoveConstraints( uint32_t )
337 void RemoveConstraints( uint32_t tag );
340 * Called by TypeInfo to set the type-info that this object-impl is created by.
341 * @param[in] typeInfo The TypeInfo that creates this object-impl.
343 void SetTypeInfo( const TypeInfo* typeInfo );
346 * @return the index from which custom properties start
348 uint32_t CustomPropertyStartIndex()
350 return PROPERTY_CUSTOM_START_INDEX;
354 * Retrieve the scene-graph object added by this object.
355 * @return reference to the scene-graph object, it will always exist
357 const SceneGraph::PropertyOwner& GetSceneObject() const;
359 /******************** Can be overridden by deriving classes ********************/
362 * Retrieve an animatable property owned by the scene-graph object.
363 * @pre -1 < index < GetPropertyCount().
364 * @param[in] index The index of the property.
365 * @return A dereferenceable pointer to a property, or NULL if a scene-object does not exist with this property.
367 virtual const SceneGraph::PropertyBase* GetSceneObjectAnimatableProperty( Property::Index index ) const;
370 * Retrieve a constraint input-property owned by the scene-graph object.
371 * @pre -1 < index < GetPropertyCount().
372 * @param[in] index The index of the property.
373 * @return A dereferenceable pointer to an input property, or NULL if a scene-object does not exist with this property.
375 virtual const PropertyInputImpl* GetSceneObjectInputProperty( Property::Index index ) const;
378 * Query whether the property is a component of a scene-graph property.
379 * @pre -1 < index < GetPropertyCount().
380 * @param[in] index The index of the property.
381 * @return The index or Property::INVALID_COMPONENT_INDEX.
383 virtual int32_t GetPropertyComponentIndex( Property::Index index ) const;
386 * Query whether playing an animation is possible or not.
387 * @return true if playing an animation is possible.
389 virtual bool IsAnimationPossible() const
395 * @copydoc Dali::Handle::PropertySetSignal()
397 Handle::PropertySetSignalType& PropertySetSignal();
402 * Constructor. Protected so use New to construct an instance of this class
404 * @param sceneObject the scene graph property owner
406 Object( const SceneGraph::PropertyOwner* sceneObject );
409 * A reference counted object may only be deleted by calling Unreference()
414 * Called immediately by derived classes, after the scene-object has been created & passed to the scene-graph.
416 void OnSceneObjectAdd();
419 * Called by derived classes, shortly before send a message to remove the scene-object.
421 void OnSceneObjectRemove();
424 * For overriding by derived classes to return the parent of this object.
426 virtual Object* GetParentObject() const
428 // By default the Object does not have a parent
433 * For use in derived classes.
434 * This is called after a property is set.
435 * @param [in] index The index of the property.
436 * @param [in] propertyValue The value of the property.
438 virtual void OnPropertySet( Property::Index index, const Property::Value& propertyValue ) {}
441 * Retrieves the TypeInfo for this object. Only retrieves it from the type-registry once and then stores a pointer
442 * to it locally there-after. The type info will not change during the life-time of the application.
443 * @return The type-info for this object (Can be NULL)
445 const TypeInfo* GetTypeInfo() const;
448 * Helper to find custom property
450 * @return pointer to the property
452 CustomPropertyMetadata* FindCustomProperty( Property::Index index ) const;
455 * Helper to find animatable property
457 * @return pointer to the property
459 AnimatablePropertyMetadata* FindAnimatableProperty( Property::Index index ) const;
462 * Helper to register a scene-graph property
463 * @param [in] name The name of the property.
464 * @param [in] key The key of the property
465 * @param [in] index The index of the property
466 * @param [in] value The value of the property.
467 * @return The index of the registered property or Property::INVALID_INDEX if registration failed.
469 Property::Index RegisterSceneGraphProperty(ConstString name, Property::Index key, Property::Index index, Property::Value propertyValue) const;
472 * Registers animatable scene property
473 * @param typeInfo to check the default value
474 * @param index of the property to register
475 * @param value initial value or nullptr
477 void RegisterAnimatableProperty( const TypeInfo& typeInfo, Property::Index index, const Property::Value* value ) const;
480 * Check whether the animatable property is registered already, if not then register on.
481 * @param [in] index The index of the property
482 * @param [in] value optional value for the property
483 * @return pointer to the property metadata
485 AnimatablePropertyMetadata* GetSceneAnimatableProperty( Property::Index index, const Property::Value* value ) const;
488 * Resolve the index and name of child properties if any.
490 void ResolveChildProperties();
492 private: // Default property extensions for derived classes
495 * Set the value of a default property.
496 * @pre The property types match i.e. propertyValue.GetType() is equal to GetPropertyType(index).
497 * @param [in] index The index of the property.
498 * @param [in] propertyValue The new value of the property.
500 virtual void SetDefaultProperty( Property::Index index, const Property::Value& propertyValue );
503 * Retrieve a default property value.
504 * @param [in] index The index of the property.
505 * @return The property value.
507 virtual Property::Value GetDefaultProperty( Property::Index index ) const;
510 * Retrieve the latest scene-graph value of a default property.
511 * @param[in] index The index of the property.
512 * @return The latest scene-graph value of a default property.
514 virtual Property::Value GetDefaultPropertyCurrentValue( Property::Index index ) const;
517 * Notifies that a default property is being animated so the deriving class should update the cached value.
518 * @param[in] animation The animation animating the property.
519 * @param[in] index The index of the property.
520 * @param[in] value The value of the property after the animation.
521 * @param[in] animationType Whether the property value given is the target or a relative value.
523 virtual void OnNotifyDefaultPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type propertyChangeType )
528 // no default, copy or assignment
530 Object(const Object& rhs) = delete;
531 Object& operator=(const Object& rhs) = delete;
534 * Enable property notifications in scene graph
536 void EnablePropertyNotifications();
539 * Enable property notifications in scene graph
541 void DisablePropertyNotifications();
544 * Get the latest value of the property on the scene-graph.
545 * @param[in] entry An entry from the property lookup container.
546 * @return The latest value of the property.
548 Property::Value GetCurrentPropertyValue( const PropertyMetadata& entry ) const;
551 * Set the value of scene graph property.
552 * @param [in] index The index of the property.
553 * @param [in] entry An entry from the property lookup container.
554 * @param [in] value The new value of the property.
556 virtual void SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value );
560 * Get the event thread services object - used for sending messages to the scene graph
561 * Assert if called from the wrong thread.
562 * This is intentionally inline for performance reasons.
564 * @return The event thread services object
566 inline EventThreadServices& GetEventThreadServices()
568 DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() );
569 return mEventThreadServices;
573 * Get the event thread services object - used for sending messages to the scene graph
574 * Assert if called from the wrong thread
575 * This is intentionally inline for performance reasons.
577 * @return The event thread services object
579 inline const EventThreadServices& GetEventThreadServices() const
581 DALI_ASSERT_ALWAYS( EventThreadServices::IsCoreRunning() );
582 return mEventThreadServices;
587 EventThreadServices& mEventThreadServices;
591 // mutable because it's lazy initialised and GetSceneObject has to be const so it can be called from const methods
592 // const to prevent accidentally calling setters directly from event thread
593 // protected to allow fast access from derived classes that have their own scene object (no function call overhead)
594 mutable const SceneGraph::PropertyOwner* mUpdateObject; ///< Reference to object to hold the scene graph properties
598 Dali::Vector<Observer*> mObservers;
599 mutable OwnerContainer<PropertyMetadata*> mCustomProperties; ///< Used for accessing custom Node properties
600 mutable OwnerContainer<PropertyMetadata*> mAnimatableProperties; ///< Used for accessing animatable Node properties
601 mutable const TypeInfo* mTypeInfo; ///< The type-info for this object, mutable so it can be lazy initialized from const method if it is required
603 ConstraintContainer* mConstraints; ///< Container of owned -constraints.
605 using PropertyNotificationContainer = std::vector< Dali::PropertyNotification >;
606 PropertyNotificationContainer* mPropertyNotifications; ///< Container of owned property notifications.
608 Handle::PropertySetSignalType mPropertySetSignal;
611 } // namespace Internal
613 // Helpers for public-api forwarding methods
615 inline Internal::Object& GetImplementation(Dali::Handle& object)
617 DALI_ASSERT_ALWAYS( object && "Object handle is empty" );
619 BaseObject& handle = object.GetBaseObject();
621 return static_cast<Internal::Object&>(handle);
624 inline const Internal::Object& GetImplementation(const Dali::Handle& object)
626 DALI_ASSERT_ALWAYS( object && "Object handle is empty" );
628 const BaseObject& handle = object.GetBaseObject();
630 return static_cast<const Internal::Object&>(handle);
635 #endif // DALI_INTERNAL_OBJECT_H