5 * Copyright (c) 2022 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
26 #include <dali/public-api/common/dali-common.h>
27 #include <dali/public-api/object/base-handle.h>
28 #include <dali/public-api/object/indirect-value.h>
29 #include <dali/public-api/object/property-key.h>
30 #include <dali/public-api/object/property-notification-declarations.h>
31 #include <dali/public-api/object/property-types.h>
32 #include <dali/public-api/object/property-value.h>
33 #include <dali/public-api/object/ref-object.h>
34 #include <dali/public-api/signals/dali-signal.h>
39 * @addtogroup dali_core_object
44 class PropertyNotification;
45 class PropertyCondition;
47 namespace Internal DALI_INTERNAL
53 * @brief Dali::Handle is a handle to an internal property owning Dali object that can have constraints applied to it.
56 class DALI_CORE_API Handle : public BaseHandle
60 * @brief Enumeration for Handle's capabilities that can be queried using Handle::Supports().
66 * @brief Some objects support dynamic property creation at run-time.
68 * New properties are registered by calling RegisterProperty() with an unused property name.
71 DYNAMIC_PROPERTIES = 0x01,
75 * @brief PropertySetSignal function prototype for signal handler. Called when a property is set on this object.
77 using PropertySetSignalType = Signal<void(Handle& handle, Property::Index index, const Property::Value& value)>;
81 * @brief This constructor is used by Dali New() methods.
84 * @param[in] handle A pointer to a newly allocated Dali resource
86 Handle(Dali::Internal::Object* handle);
89 * @brief This constructor provides an uninitialized Dali::Handle.
91 * This should be initialized with a Dali New() method before use.
92 * Methods called on an uninitialized Dali::Handle will assert.
94 * Handle handle; // uninitialized
95 * handle.SomeMethod(); // unsafe! This will assert
97 * handle = SomeClass::New(); // now initialized
98 * handle.SomeMethod(); // safe
105 * @brief Creates a new object.
108 * @return A handle to a newly allocated object
113 * @brief Template to create a derived handle and set properties on it.
115 * Marked as DALI_NO_EXPORT_API to prevent internal usage exporting symbols.
117 * @tparam T The derived class to create
118 * @param[in] properties The properties to set
120 template<typename Type>
121 static DALI_NO_EXPORT_API Type New(const Property::Map& properties)
123 Type handle = Type::New();
124 handle.SetProperties(properties);
129 * @brief Dali::Handle is intended as a base class.
131 * This is non-virtual since derived Handle types must not contain data or virtual methods.
137 * @brief This copy constructor is required for (smart) pointer semantics.
140 * @param[in] handle A reference to the copied handle
142 Handle(const Handle& handle);
145 * @brief This assignment operator is required for (smart) pointer semantics.
148 * @param[in] rhs A reference to the copied handle
149 * @return A reference to this
151 Handle& operator=(const Handle& rhs);
154 * @brief Move constructor.
157 * @param[in] rhs A reference to the moved handle
159 Handle(Handle&& rhs) noexcept;
162 * @brief Move assignment operator.
165 * @param[in] rhs A reference to the moved handle
166 * @return A reference to this handle
168 Handle& operator=(Handle&& rhs) noexcept;
171 * @brief Downcasts to a handle.
173 * If not, the returned handle is left uninitialized.
175 * @param[in] handle to An object
176 * @return handle or an uninitialized handle
178 static Handle DownCast(BaseHandle handle);
181 * @brief Queries whether an handle supports a given capability.
184 * @param[in] capability The queried capability
185 * @return True if the capability is supported
187 bool Supports(Capability capability) const;
192 * @brief Queries how many properties are provided by an handle.
194 * This may vary between instances of a class, if dynamic properties are supported.
196 * @return The number of properties
198 uint32_t GetPropertyCount() const;
201 * @brief Queries the name of a property.
204 * @param[in] index The index of the property
205 * @return The name of the property
207 std::string GetPropertyName(Property::Index index) const;
210 * @brief Query the index of a property using the given key.
213 * @param[in] key The key of the property to search for. (The name or integer key provided to
214 * RegisterProperty()).
215 * @return the matching property index of the key, or Property::INVALID_INDEX if no
216 * property matches the given key.
218 Property::Index GetPropertyIndex(Property::Key key) const;
221 * @brief Queries whether a property can be set using SetProperty().
224 * @param[in] index The index of the property
225 * @return True if the property is writable
226 * @pre Property::INVALID_INDEX < index.
228 bool IsPropertyWritable(Property::Index index) const;
231 * @brief Queries whether a writable property can be the target of an animation or constraint.
234 * @param[in] index The index of the property
235 * @return True if the property is animatable
237 bool IsPropertyAnimatable(Property::Index index) const;
240 * @brief Queries whether a property can be used as in input to a constraint.
243 * @param[in] index The index of the property
244 * @return True if the property can be used as a constraint input
246 bool IsPropertyAConstraintInput(Property::Index index) const;
249 * @brief Queries the type of a property.
252 * @param[in] index The index of the property
253 * @return The type of the property
255 Property::Type GetPropertyType(Property::Index index) const;
258 * @brief Sets the value of an existing property.
260 * Property should be write-able. Setting a read-only property is a no-op.
262 * @param[in] index The index of the property
263 * @param[in] propertyValue The new value of the property
264 * @pre The property types match i.e. propertyValue.GetType() is equal to GetPropertyType(index).
266 void SetProperty(Property::Index index, Property::Value propertyValue);
269 * @brief Reserves a number of custom properties
271 * Saves automatic re-allocation of vectors for properties when we know in advance how many there
274 * @param[in] propertyCount The total number of initial properties.
276 void ReserveCustomProperties(int propertyCount);
279 * @brief Registers a new animatable property.
282 * @param[in] name The name of the property
283 * @param[in] propertyValue The new value of the property
284 * @return The index of the property or Property::INVALID_INDEX if registration failed
285 * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
286 * Property names are expected to be unique, but this is not enforced.
287 * Property indices are unique to each registered custom property in a given object.
288 * returns Property::INVALID_INDEX if registration failed. This can happen if you try to register
289 * animatable property on an object that does not have scene graph object.
290 * @note Only the following types can be animated:
291 * - Property::BOOLEAN
293 * - Property::INTEGER
294 * - Property::VECTOR2
295 * - Property::VECTOR3
296 * - Property::VECTOR4
297 * - Property::MATRIX3
299 * - Property::ROTATION
300 * @note If a property with the desired name already exists, then the value given is just set.
302 Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue);
305 * @brief Registers a new animatable property.
308 * @param[in] name The name of the property
309 * @param[in] propertyValue The new value of the property
310 * @return The index of the property or Property::INVALID_INDEX if registration failed
311 * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
312 * Property names are expected to be unique, but this is DEFINITELY not enforced. It is up to the
313 * caller to enforce uniqueness.
315 * Property indices are unique to each registered custom property in a given object.
316 * returns Property::INVALID_INDEX if registration failed. This can happen if you try to register
317 * animatable property on an object that does not have scene graph object.
318 * @note Only the following types can be animated:
319 * - Property::BOOLEAN
321 * - Property::INTEGER
322 * - Property::VECTOR2
323 * - Property::VECTOR3
324 * - Property::VECTOR4
325 * - Property::MATRIX3
327 * - Property::ROTATION
328 * @note If a property with the desired name already exists, then this creates a secondary
329 * entry to a different scene graph property; Access by index works as expected, but uniform
330 * values will use the last registered version, not the existing version, so things may break.
332 Property::Index RegisterUniqueProperty(std::string_view name, Property::Value propertyValue);
335 * @brief Register a new animatable property with an integer key.
338 * @param[in] key The integer key of the property.
339 * @param[in] name The text key of the property.
340 * @param[in] propertyValue The new value of the property.
342 * @return The index of the property or Property::INVALID_INDEX if registration failed
344 * @pre The object supports dynamic properties
345 * i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true. Property names and keys
346 * are expected to be unique, but this is not enforced. Property indices are unique
347 * to each registered custom property in a given object.
350 * @note Returns Property::INVALID_INDEX if registration failed. This can happen if
351 * you try to register animatable property on an object that does not have scene graph
354 * @note The returned property index is not the same as the integer key (though it
357 * This version of RegisterProperty associates both an integer key and the text key
358 * with the property, allowing for lookup of the property index by either key or name
359 * ( which is useful when other classes know the key but not the name )
361 * @note Only the following types can be animated:
362 * - Property::BOOLEAN
364 * - Property::INTEGER
365 * - Property::VECTOR2
366 * - Property::VECTOR3
367 * - Property::VECTOR4
368 * - Property::MATRIX3
370 * - Property::ROTATION
371 * @note If a property with the desired name already exists, then the value given is just set.
373 Property::Index RegisterProperty(Property::Index key,
374 std::string_view name,
375 Property::Value propertyValue);
378 * @brief Register a new animatable property with an integer key.
381 * @param[in] key The integer key of the property.
382 * @param[in] name The text key of the property.
383 * @param[in] propertyValue The new value of the property.
385 * @return The index of the property or Property::INVALID_INDEX if registration failed
386 * It is up to the caller to guarantee that the property is unique. This allows many
387 * checks to be skipped.
389 * @pre The object supports dynamic properties
390 * i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true. Property names and keys
391 * are expected to be unique, and are therefore just added without any checks.
392 * Property indices are unique to each registered custom property in a given object.
394 * @note Returns Property::INVALID_INDEX if registration failed. This can happen if
395 * you try to register animatable property on an object that does not have scene graph
398 * @note The returned property index is not the same as the integer key (though it
401 * This version of RegisterProperty associates both an integer key and the text key
402 * with the property, allowing for lookup of the property index by either key or name
403 * ( which is useful when other classes know the key but not the name )
405 * @note Only the following types can be animated:
406 * - Property::BOOLEAN
408 * - Property::INTEGER
409 * - Property::VECTOR2
410 * - Property::VECTOR3
411 * - Property::VECTOR4
412 * - Property::MATRIX3
414 * - Property::ROTATION
416 * @note If a property with the desired name already exists, then this will create a second entry with
417 * the same name, and may cause problems. It is up to the caller to prevent this happening. Possible side
418 * effects are: lookup by name always finds the first such property, not the second; whereas, writing
419 * uniform value to shader will use the second, not the first;
420 * Using the returned Property::Index for future reference will always access the correct property.
422 Property::Index RegisterUniqueProperty(Property::Index key,
423 std::string_view name,
424 Property::Value propertyValue);
427 * @brief Registers a new property.
429 * Properties can be set as non animatable using property attributes.
431 * @param[in] name The name of the property
432 * @param[in] propertyValue The new value of the property
433 * @param[in] accessMode The property access mode (writable, animatable etc)
434 * @return The index of the property
435 * @pre The handle supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
436 * @pre name is unused i.e. GetPropertyIndex(name) returns PropertyIndex::INVALID.
437 * @note Only the following types can be animated:
438 * - Property::BOOLEAN
440 * - Property::INTEGER
441 * - Property::VECTOR2
442 * - Property::VECTOR3
443 * - Property::VECTOR4
444 * - Property::MATRIX3
446 * - Property::ROTATION
447 * @note If a property with the desired name already exists, then the value given is just set.
449 Property::Index RegisterProperty(std::string_view name, Property::Value propertyValue, Property::AccessMode accessMode);
452 * @brief Retrieves a property value.
455 * @param[in] index The index of the property
456 * @return The property value
457 * @note This returns the value set by SetProperty() or the animation target value if it is being animated.
458 * @note To get the current value on the scene-graph, use GetCurrentProperty().
460 Property::Value GetProperty(Property::Index index) const;
463 * @brief Convenience function for obtaining a property of a known type.
466 * @param[in] index The index of the property
467 * @return The property value
468 * @pre The property types match i.e. PropertyTypes::Get<T>() is equal to GetPropertyType(index).
472 T GetProperty(Property::Index index) const
474 Property::Value value = GetProperty(index);
476 return T(value.Get<T>());
480 * @brief Retrieves the latest value of the property from the scene-graph.
483 * @param[in] index The index of the property
484 * @return The property value
485 * @note This returns the value of the property in the last rendered frame so can be different to that
486 * set by SetProperty() if the set-message has not been processed by the scene-graph yet.
487 * @note To retrieve the value set by SetProperty(), use GetProperty().
489 Property::Value GetCurrentProperty(Property::Index index) const;
492 * @brief Convenience function for obtaining the current value of a property of a known type.
495 * @param[in] index The index of the property
496 * @return The property value
497 * @pre The property types match i.e. PropertyTypes::Get<T>() is equal to GetPropertyType(index).
498 * @see GetCurrentProperty()
501 T GetCurrentProperty(Property::Index index) const
503 Property::Value value = GetCurrentProperty(index);
505 return T(value.Get<T>());
509 * @brief Sets all the properties in the given property map.
512 * @param[in] properties The properties to set
514 void SetProperties(const Property::Map& properties);
517 * @brief Retrieves all the properties and the values for this object
520 * @param[out] properties A map which is populated with the index-value pairs
522 * @note The properties map will be cleared by this method first.
524 void GetProperties(Property::Map& properties);
527 * @brief Retrieves all the property indices for this object (including custom properties).
530 * @param[out] indices A container of property indices for this object
531 * @note The added container is cleared.
533 void GetPropertyIndices(Property::IndexContainer& indices) const;
536 * @brief Determine if the custom property index exists on this object without throwing a Dali::Exception.
539 * @note This does not check default properties.
540 * @param[in] index The index of the property to test for
542 bool DoesCustomPropertyExist(Property::Index index);
545 * @brief Adds a property notification to this object.
548 * @param[in] index The index of the property
549 * @param[in] condition The notification will be triggered when this condition is satisfied
550 * @return A handle to the newly created PropertyNotification
552 PropertyNotification AddPropertyNotification(Property::Index index,
553 const PropertyCondition& condition);
556 * @brief Adds a property notification to this object.
559 * @param[in] index The index of the property
560 * @param[in] componentIndex Index to the component of a complex property such as a Vector
561 * @param[in] condition The notification will be triggered when this condition is satisfied
562 * @return A handle to the newly created PropertyNotification
564 PropertyNotification AddPropertyNotification(Property::Index index,
566 const PropertyCondition& condition);
569 * @brief Removes a property notification from this object.
572 * @param[in] propertyNotification The propertyNotification to be removed
574 void RemovePropertyNotification(Dali::PropertyNotification propertyNotification);
577 * @brief Removes all property notifications from this object.
580 void RemovePropertyNotifications();
585 * @brief Removes all constraints from an Object.
588 * @pre The object has been initialized.
590 void RemoveConstraints();
593 * @brief Removes all the constraint from the Object with a matching tag.
596 * @param[in] tag The tag of the constraints which will be removed
597 * @pre The Object has been initialized.
599 void RemoveConstraints(uint32_t tag);
602 * @brief Index operator, using integer lookup.
604 * Returns an object that can be assigned to or cast from, enabling
605 * the indexed property to be either read or written.
607 * @param[in] index The index of the property to access.
608 * @return indirect value. Should have shorter scope than the handle
610 IndirectValue operator[](Property::Index index);
613 * @brief Index operator, using name lookup.
615 * Returns an object that can be assigned to or cast from, enabling
616 * the named property to be either read or written.
618 * @param[in] name The name of the property to access.
619 * @return indirect value. Should have shorter scope than the handle
621 IndirectValue operator[](const std::string& name);
625 * @brief Get a signal when a property is set on this object through the API (i.e. not when animating)
628 * @return The signal to attach a connection to.
630 PropertySetSignalType& PropertySetSignal();
634 * @brief This namespace provides a convenient function to create an object with a custom "weight" property.
637 namespace WeightObject
639 DALI_CORE_API extern const Property::Index WEIGHT; ///< name "weight", type FLOAT
642 * @brief Convenience function to create an object with a custom "weight" property.
645 * @return A handle to a newly allocated object
647 DALI_CORE_API Handle New();
649 } // namespace WeightObject
656 #endif // DALI_HANDLE_H