END_TEST;
}
-int UtcDaliHandleRegisterProperty(void)
+int UtcDaliHandleRegisterProperty01(void)
{
tet_infoline("Positive Test Dali::Handle::RegisterProperty()");
TestApplication application;
END_TEST;
}
+int UtcDaliHandleRegisterProperty02(void)
+{
+ tet_infoline("Positive Test Dali::Handle::RegisterProperty() int key");
+ TestApplication application;
+
+ Stage stage = Stage::GetCurrent();
+
+ Actor actor = Actor::New();
+ stage.Add( actor );
+
+ const unsigned int defaultPropertyCount = actor.GetPropertyCount();
+
+ application.SendNotification();
+ application.Render();
+
+ Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1;
+ Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2;
+
+ const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f);
+ const float withFlake(99.f);
+
+ Property::Index index1 = actor.RegisterProperty( "MyPropertyOne", Vector3::ONE );
+ Property::Index index2 = actor.RegisterProperty( key1, "sideColor", testColor);
+ Property::Index index3 = actor.RegisterProperty( key2, "iceCream", withFlake );
+
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 3, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty< Vector3 >( index1 ), Vector3::ONE, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty< Vector4 >( index2 ), testColor, TEST_LOCATION );
+ DALI_TEST_EQUALS( actor.GetProperty< float >( index3 ), withFlake, TEST_LOCATION );
+
+ // No new property should be registered when we call the below functions
+ Property::Index testIndex2 = actor.RegisterProperty( "iceCream", 2200.f );
+ Property::Index testIndex1 = actor.RegisterProperty( "sideColor", Color::BLACK );
+ application.SendNotification();
+ application.Render();
+
+ DALI_TEST_EQUALS( index2, testIndex1, TEST_LOCATION ); // We should have the same index as per the first registration
+ DALI_TEST_EQUALS( index3, testIndex2, TEST_LOCATION ); // We should have the same index as per the first registration
+ DALI_TEST_EQUALS( actor.GetPropertyCount(), defaultPropertyCount + 3, TEST_LOCATION ); // Property count should be the same
+ DALI_TEST_EQUALS( actor.GetProperty< Vector4 >( index2 ), Color::BLACK, TEST_LOCATION ); // Value should be what we sent on second RegisterProperty call
+ DALI_TEST_EQUALS( actor.GetProperty< float >( index3 ), 2200.f, TEST_LOCATION );
+
+ END_TEST;
+}
+
+
+int UtcDaliHandleGetPropertyIndex02(void)
+{
+ tet_infoline("Positive Test Dali::Handle::GetPropertyIndex() int key");
+ TestApplication application;
+
+ Stage stage = Stage::GetCurrent();
+
+ Actor actor = Actor::New();
+ stage.Add( actor );
+
+ const unsigned int defaultPropertyCount = actor.GetPropertyCount();
+
+ application.SendNotification();
+ application.Render();
+
+ Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1;
+ Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2;
+
+ const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f);
+ const float withFlake(99.f);
+
+ Property::Index index1 = actor.RegisterProperty( "MyPropertyOne", Vector3::ONE );
+ Property::Index index2 = actor.RegisterProperty( key1, "sideColor", testColor);
+ Property::Index index3 = actor.RegisterProperty( "MyPropertyTwo", Vector3::ONE );
+ Property::Index index4 = actor.RegisterProperty( key2, "iceCream", withFlake );
+ Property::Index index5 = actor.RegisterProperty( "MyPropertyThree", Vector3::ONE );
+
+ application.SendNotification();
+ application.Render();
+
+ // Test that we can get the property index from the integer key
+ Property::Index testIndex1 = actor.GetPropertyIndex( key1 );
+ Property::Index testIndex2 = actor.GetPropertyIndex( key2 );
+
+ DALI_TEST_EQUALS( index2, testIndex1, TEST_LOCATION );
+ DALI_TEST_EQUALS( index4, testIndex2, TEST_LOCATION );
+
+ // Test that we keep the same indices on the named properties
+ Property::Index testIndex = actor.GetPropertyIndex("MyPropertyOne");
+ DALI_TEST_EQUALS(testIndex, index1, TEST_LOCATION);
+ testIndex = actor.GetPropertyIndex("MyPropertyTwo");
+ DALI_TEST_EQUALS(testIndex, index3, TEST_LOCATION);
+ testIndex = actor.GetPropertyIndex("MyPropertyThree");
+ DALI_TEST_EQUALS(testIndex, index5, TEST_LOCATION);
+ testIndex = actor.GetPropertyIndex("sideColor");
+ DALI_TEST_EQUALS(testIndex, index2, TEST_LOCATION);
+ testIndex = actor.GetPropertyIndex("iceCream");
+ DALI_TEST_EQUALS(testIndex, index4, TEST_LOCATION);
+
+ DALI_TEST_EQUALS(defaultPropertyCount+5, actor.GetPropertyCount(), TEST_LOCATION);
+ END_TEST;
+}
+
int UtcDaliHandleGetProperty(void)
{
tet_infoline("Positive Test Dali::Handle::GetProperty()");
// Actor
Actor actor = Actor::New();
actor.GetPropertyIndices( indices );
- DALI_TEST_CHECK( indices.Size() );
- DALI_TEST_EQUALS( indices.Size(), actor.GetPropertyCount(), TEST_LOCATION );
+ int numDefaultProperties = indices.Size();
+ DALI_TEST_CHECK( numDefaultProperties > 0 );
+ DALI_TEST_EQUALS( numDefaultProperties, actor.GetPropertyCount(), TEST_LOCATION );
+
+ const Vector4 testColor(0.5f, 0.2f, 0.9f, 1.0f);
+ const float withFlake(99.f);
+
+ Property::Index key1 = CORE_PROPERTY_MAX_INDEX+1;
+ Property::Index key2 = CORE_PROPERTY_MAX_INDEX+2;
+
+ actor.RegisterProperty( "MyPropertyOne", Vector3::ONE );
+ actor.RegisterProperty( key1, "sideColor", testColor);
+ actor.RegisterProperty( "MyPropertyTwo", 1234 );
+ Property::Index index4 = actor.RegisterProperty( key2, "iceCream", withFlake );
+ actor.RegisterProperty( "MyPropertyThree", Vector2(.2f,.7f) );
+
+ actor.GetPropertyIndices( indices );
+
+ DALI_TEST_EQUALS( indices.Size(), numDefaultProperties + 5, TEST_LOCATION );
+ DALI_TEST_EQUALS( indices[indices.Size()-2], index4, TEST_LOCATION );
+
END_TEST;
}
END_TEST;
}
-
return index;
}
+Property::Index Object::GetPropertyIndex( Property::Index key ) const
+{
+ Property::Index index = Property::INVALID_INDEX;
+
+ if( mCustomProperties.Count() > 0 )
+ {
+ Property::Index count = PROPERTY_CUSTOM_START_INDEX;
+ const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
+ for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
+ {
+ CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
+ if( custom->key == key )
+ {
+ if( custom->childPropertyIndex != Property::INVALID_INDEX )
+ {
+ // If it is a child property, return the child property index
+ index = custom->childPropertyIndex;
+ }
+ else
+ {
+ index = count;
+ }
+ break;
+ }
+ }
+ }
+
+ return index;
+}
+
bool Object::IsPropertyWritable( Property::Index index ) const
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
}
}
-Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
+Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index key, Property::Index index, const Property::Value& propertyValue) const
{
// Create a new property
Dali::Internal::OwnerPointer<PropertyBase> newProperty;
{
DALI_ASSERT_ALWAYS( index <= PROPERTY_CUSTOM_MAX_INDEX && "Too many custom properties have been registered" );
- mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
+ mCustomProperties.PushBack( new CustomPropertyMetadata( name, key, propertyValue.GetType(), property ) );
}
else
{
Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue )
{
- return RegisterProperty( name, propertyValue, Property::ANIMATABLE );
+ return RegisterProperty( name, Property::INVALID_KEY, propertyValue, Property::ANIMATABLE );
+}
+
+Property::Index Object::RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue )
+{
+ return RegisterProperty( name, key, propertyValue, Property::ANIMATABLE );
}
Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode )
{
- // If property with the required name already exists, then just set it.
- Property::Index index = GetPropertyIndex( name );
- if( index != Property::INVALID_INDEX )
+ return RegisterProperty( name, Property::INVALID_KEY, propertyValue, accessMode );
+}
+
+Property::Index Object::RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue, Property::AccessMode accessMode )
+{
+ // If property with the required key already exists, then just set it.
+ Property::Index index = Property::INVALID_INDEX;
+ if( key != Property::INVALID_KEY ) // Try integer key first if it's valid
+ {
+ index = GetPropertyIndex( key );
+ }
+ if( index == Property::INVALID_INDEX ) // If it wasn't valid, or doesn't exist, try name
+ {
+ index = GetPropertyIndex( name );
+ }
+
+ if( index != Property::INVALID_INDEX ) // If there was a valid index found by either key, set it.
{
SetProperty( index, propertyValue );
}
{
// Otherwise register the property
- if(Property::ANIMATABLE == accessMode)
+ if( Property::ANIMATABLE == accessMode )
{
- index = RegisterSceneGraphProperty( name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue );
+ index = RegisterSceneGraphProperty( name, key, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue );
AddUniformMapping( index, name );
}
else
// check whether the animatable property is registered already, if not then register one.
AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
- if(!animatableProperty)
+ if( !animatableProperty )
{
const TypeInfo* typeInfo( GetTypeInfo() );
- if (typeInfo)
+ if( typeInfo )
{
Property::Index basePropertyIndex = typeInfo->GetBasePropertyIndex(index);
- if(basePropertyIndex == Property::INVALID_INDEX)
+ if( basePropertyIndex == Property::INVALID_INDEX )
{
// If the property is not a component of a base property, register the whole property itself.
const std::string& propertyName = typeInfo->GetPropertyName(index);
- RegisterSceneGraphProperty(propertyName, index, typeInfo->GetPropertyDefaultValue(index));
+ RegisterSceneGraphProperty(propertyName, Property::INVALID_KEY, index, typeInfo->GetPropertyDefaultValue(index));
AddUniformMapping( index, propertyName );
}
else
{
- // Since the property is a component of a base property, check whether the base property is regsitered.
+ // Since the property is a component of a base property, check whether the base property is registered.
animatableProperty = FindAnimatableProperty( basePropertyIndex );
- if(!animatableProperty)
+ if( !animatableProperty )
{
// If the base property is not registered yet, register the base property first.
const std::string& basePropertyName = typeInfo->GetPropertyName(basePropertyIndex);
- if(Property::INVALID_INDEX != RegisterSceneGraphProperty(basePropertyName, basePropertyIndex, Property::Value(typeInfo->GetPropertyType(basePropertyIndex))))
+
+ if( Property::INVALID_INDEX != RegisterSceneGraphProperty( basePropertyName, Property::INVALID_KEY, basePropertyIndex, Property::Value(typeInfo->GetPropertyType( basePropertyIndex ) ) ) )
{
animatableProperty = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[mAnimatableProperties.Size()-1]);
AddUniformMapping( basePropertyIndex, basePropertyName );
*/
virtual Property::Index GetPropertyIndex( const std::string& name ) const;
+ /**
+ * @copydoc Dali::Handle::GetPropertyIndex()
+ */
+ virtual Property::Index GetPropertyIndex( Property::Index key ) const;
+
/**
* @copydoc Dali::Handle::IsPropertyWritable()
*/
*/
virtual Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue );
+ /**
+ * @copydoc Dali::Handle::RegisterProperty()
+ */
+ virtual Property::Index RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue );
+
/**
* @copydoc Dali::Handle::RegisterProperty(std::string name, Property::Value propertyValue, Property::AccessMode accessMode)
*/
virtual Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode );
+ /**
+ * @brief Implementing method for this override
+ */
+ virtual Property::Index RegisterProperty( const std::string& name, Property::Index key, const Property::Value& propertyValue, Property::AccessMode accessMode );
+
/**
* @copydoc Dali::Handle::AddPropertyNotification()
*/
/**
* Helper to register a scene-graph property
* @param [in] name The name of the property.
+ * @param [in] key The key of the property
* @param [in] index The index of the property
* @param [in] value The value of the property.
* @return The index of the registered property or Property::INVALID_INDEX if registration failed.
*/
- Property::Index RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const;
+ Property::Index RegisterSceneGraphProperty(const std::string& name, Property::Index key, Property::Index index, const Property::Value& propertyValue) const;
/**
* Check whether the animatable property is registered already, if not then register one.
/**
* Constructor for metadata of scene graph based properties
* @param [in] newName The name of the custom property.
+ * @param [in] newKey The key of the custom property.
* @param [in] newType The type ID of the custom property.
* @param [in] newProperty A pointer to the scene-graph owned property.
*/
CustomPropertyMetadata( const std::string& newName,
+ Property::Index newKey,
Property::Type newType,
const SceneGraph::PropertyBase* newProperty)
: name(newName),
+ key(newKey),
childPropertyIndex(Property::INVALID_INDEX),
mAccessMode(Property::ANIMATABLE)
{
Property::Value newValue,
Property::AccessMode accessMode )
: name(newName),
+ key(Property::INVALID_KEY),
childPropertyIndex(Property::INVALID_INDEX),
mAccessMode(accessMode)
{
}
std::string name; ///< The name of the property
+ Property::Index key; ///< The key of the property
Property::Index childPropertyIndex; ///< The index as a child property
private:
return GetImplementation(*this).GetPropertyIndex( name );
}
+Property::Index Handle::GetPropertyIndex( Property::Index key ) const
+{
+ return GetImplementation(*this).GetPropertyIndex( key );
+}
+
bool Handle::IsPropertyWritable( Property::Index index ) const
{
return GetImplementation(*this).IsPropertyWritable( index );
return GetImplementation(*this).RegisterProperty( name, propertyValue );
}
+Property::Index Handle::RegisterProperty( Property::Index key, const std::string& name, const Property::Value& propertyValue )
+{
+ return GetImplementation(*this).RegisterProperty( name, key, propertyValue );
+}
+
Property::Index Handle::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode )
{
return GetImplementation(*this).RegisterProperty( name, propertyValue, accessMode );
*/
Property::Index GetPropertyIndex( const std::string& name ) const;
+ /**
+ * @brief Query the index of a custom property matching the given key.
+ *
+ * Returns the first custom property that matches the given integer key. This is
+ * useful for other classes that know the key but not the name. Requires the property
+ * to have been registered with the associated key.
+ *
+ * @note This key is not the same as the Property enum found in
+ * objects such as Actor (which is a preset index).
+ *
+ * @SINCE_1_2.1
+ * @param [in] key The integer key of the property
+ * @return The index of the property, or Property::INVALID_INDEX if no property exists with the given key.
+ * @note The key is not the same as the returned index, though it has the same type.
+ */
+ Property::Index GetPropertyIndex( Property::Index key ) const;
+
/**
* @brief Query whether a property can be set using SetProperty().
*
*/
Property::Index RegisterProperty( const std::string& name, const Property::Value& propertyValue );
+ /**
+ * @brief Register a new animatable property with an integer key.
+ *
+ * @SINCE_1_2.1
+ * @param [in] key The integer key of the property.
+ * @param [in] name The text key of the property.
+ * @param [in] propertyValue The new value of the property.
+ * @return The index of the property or Property::INVALID_INDEX if registration failed
+ * @pre The object supports dynamic properties i.e. Supports(Handle::DYNAMIC_PROPERTIES) returns true.
+ * Property names and keys are expected to be unique, but this is not enforced.
+ * Property indices are unique to each registered custom property in a given object.
+ * @note Returns Property::INVALID_INDEX if registration failed. This can happen if you try to register
+ * animatable property on an object that does not have scene graph object.
+ * @note The returned property index is not the same as the integer key (though it shares a type)
+ *
+ * This version of RegisterProperty associates both an integer key
+ * and the text key with the property, allowing for lookup of the
+ * property index by either key or name ( which is useful when other
+ * classes know the key but not the name )
+ *
+ * @note Only the following types can be animated:
+ * - Property::BOOLEAN
+ * - Property::FLOAT
+ * - Property::INTEGER
+ * - Property::VECTOR2
+ * - Property::VECTOR3
+ * - Property::VECTOR4
+ * - Property::MATRIX3
+ * - Property::MATRIX
+ * - Property::ROTATION
+ * @note If a property with the desired name already exists, then the value given is just set.
+ */
+ Property::Index RegisterProperty( Property::Index key, const std::string& name, const Property::Value& propertyValue );
+
/**
* @brief Register a new property.
*
namespace Dali
{
-const int Property::INVALID_INDEX = -1;
+const int Property::INVALID_INDEX = -1;
+const int Property::INVALID_KEY = -1;
const int Property::INVALID_COMPONENT_INDEX = -1;
Property::Property(Handle& obj, Property::Index propIndex)
typedef int Index;
static const int INVALID_INDEX; ///< -1 is not a valid property index
+ static const int INVALID_KEY; ///< -1 is not a valid property key
static const int INVALID_COMPONENT_INDEX; ///< -1 is not a valid property index
typedef Dali::Vector< Index > IndexContainer; ///< A vector of property indices @SINCE_1_0.0