/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if ( index < DEFAULT_PROPERTY_MAX_COUNT )
{
- return GetDefaultPropertyName( index );
+ std::string string;
+
+ const char * propertyName = GetDefaultPropertyName( index );
+ if( propertyName )
+ {
+ string = propertyName;
+ }
+ return string;
}
if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
if ( custom->name == name )
{
- index = count;
+ 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;
+}
+
+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;
}
+Property::Index Object::GetPropertyIndex( Property::Key key ) const
+{
+ Property::Index index = Property::INVALID_INDEX;
+ if( key.type == Property::Key::INDEX )
+ {
+ index = GetPropertyIndex( key.indexKey );
+ }
+ else
+ {
+ index = GetPropertyIndex( key.stringKey );
+ }
+ return index;
+}
+
bool Object::IsPropertyWritable( Property::Index index ) const
{
DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
{
return custom->GetType();
}
+
return Property::NONE;
}
}
else
{
+ // update the cached property value
+ animatableProperty->SetPropertyValue( propertyValue );
+
// set the scene graph property value
SetSceneGraphProperty( index, *animatableProperty, propertyValue );
}
else
{
CustomPropertyMetadata* custom = FindCustomProperty( index );
+
+ if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ if( !custom )
+ {
+ // If the child property is not registered yet, register it.
+ custom = new CustomPropertyMetadata( "", propertyValue, Property::READ_WRITE );
+ mCustomProperties.PushBack( custom );
+ }
+
+ custom->childPropertyIndex = index;
+
+ // Resolve name for the child property
+ Object* parent = GetParentObject();
+ if( parent )
+ {
+ const TypeInfo* parentTypeInfo( parent->GetTypeInfo() );
+ if( parentTypeInfo )
+ {
+ custom->name = parentTypeInfo->GetChildPropertyName( index );
+ }
+ }
+ }
+
if( custom )
{
if( custom->IsAnimatable() )
{
+ // update the cached property value
+ custom->SetPropertyValue( propertyValue );
+
// set the scene graph property value
SetSceneGraphProperty( index, *custom, propertyValue );
}
else if( custom->IsWritable() )
{
- custom->value = propertyValue;
+ // update the cached property value
+ custom->SetPropertyValue( propertyValue );
}
else
{
}
else
{
+ // get the cached animatable property value
+ value = animatableProperty->GetPropertyValue();
+ }
+ }
+ else if(mCustomProperties.Count() > 0)
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if(custom)
+ {
+ // get the cached custom property value
+ value = custom->GetPropertyValue();
+ }
+ else
+ {
+ DALI_LOG_ERROR("Invalid property index\n");
+ }
+ } // if custom
+
+ return value;
+}
+
+Property::Value Object::GetCurrentProperty( Property::Index index ) const
+{
+ DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
+
+ Property::Value value;
+
+ if ( index < DEFAULT_PROPERTY_MAX_COUNT )
+ {
+ value = GetDefaultPropertyCurrentValue( index );
+ }
+ else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ const TypeInfo* typeInfo( GetTypeInfo() );
+ if ( typeInfo )
+ {
+ value = typeInfo->GetProperty( this, index );
+ }
+ else
+ {
+ DALI_LOG_ERROR("Cannot find property index\n");
+ }
+ }
+ else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ // check whether the animatable property is registered already, if not then register one.
+ AnimatablePropertyMetadata* animatableProperty = RegisterAnimatableProperty( index );
+ if(!animatableProperty)
+ {
+ DALI_LOG_ERROR("Cannot find property index\n");
+ }
+ else
+ {
// get the animatable property value
- value = GetPropertyValue( animatableProperty );
+ value = GetCurrentPropertyValue( animatableProperty );
}
}
else if(mCustomProperties.Count() > 0)
if(custom)
{
// get the custom property value
- value = GetPropertyValue( custom );
+ value = GetCurrentPropertyValue( custom );
}
else
{
int i=0;
for ( ; iter != endIter; ++iter, ++i )
{
- indices.PushBack( PROPERTY_CUSTOM_START_INDEX + i );
+ CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>( *iter );
+ if ( custom->childPropertyIndex != Property::INVALID_INDEX )
+ {
+ // If it is a child property, add the child property index
+ indices.PushBack( custom->childPropertyIndex );
+ }
+ else
+ {
+ indices.PushBack( PROPERTY_CUSTOM_START_INDEX + i );
+ }
}
}
}
-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;
case Property::STRING:
case Property::ARRAY:
case Property::MAP:
+ case Property::EXTENTS:
case Property::NONE:
{
DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
const PropertyBase* property = newProperty.Get();
if(index >= PROPERTY_CUSTOM_START_INDEX)
{
- mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
+ DALI_ASSERT_ALWAYS( index <= PROPERTY_CUSTOM_MAX_INDEX && "Too many custom properties have been registered" );
+
+ mCustomProperties.PushBack( new CustomPropertyMetadata( name, key, propertyValue, property ) );
}
else
{
- mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, Property::INVALID_COMPONENT_INDEX, propertyValue.GetType(), property ) ); // base property
+ mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, propertyValue, property ) );
}
// queue a message to add the property
- InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
+ InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty ); // Message takes ownership
// notify the derived class (optional) method in case it needs to do some more work on the new property
// note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
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
{
// Add entry to the property lookup
index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
- mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
+
+ CustomPropertyMetadata* customProperty = new CustomPropertyMetadata( name, propertyValue, accessMode );
+
+ // Resolve index for the child property
+ Object* parent = GetParentObject();
+ if( parent )
+ {
+ const TypeInfo* parentTypeInfo( parent->GetTypeInfo() );
+ if( parentTypeInfo )
+ {
+ Property::Index childPropertyIndex = parentTypeInfo->GetChildPropertyIndex( name );
+ if( childPropertyIndex != Property::INVALID_INDEX )
+ {
+ customProperty->childPropertyIndex = childPropertyIndex;
+ index = childPropertyIndex;
+ }
+ }
+ }
+
+ mCustomProperties.PushBack( customProperty );
}
}
{
if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
{
- DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
+ DALI_ABORT( "Property notification added to event side only property." );
}
else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
{
}
}
+void Object::NotifyPropertyAnimation( Animation& animation, Property::Index index, const Property::Value& value, Animation::Type animationType )
+{
+ if ( index < DEFAULT_PROPERTY_MAX_COUNT )
+ {
+ OnNotifyDefaultPropertyAnimation( animation, index, value, animationType );
+ }
+ else
+ {
+ PropertyMetadata* propertyMetadata = NULL;
+ if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+ {
+ propertyMetadata = FindAnimatableProperty( index );
+ }
+ else
+ {
+ CustomPropertyMetadata* custom = FindCustomProperty( index );
+ if( custom && custom->IsAnimatable() )
+ {
+ propertyMetadata = custom;
+ }
+ }
+
+ if( propertyMetadata )
+ {
+ switch( animationType )
+ {
+ case Animation::TO:
+ case Animation::BETWEEN:
+ {
+ // Update the cached property value
+ propertyMetadata->SetPropertyValue( value );
+ break;
+ }
+ case Animation::BY:
+ {
+ // Adjust the cached property value
+ propertyMetadata->AdjustPropertyValueBy( value );
+ break;
+ }
+ }
+ }
+ }
+}
+
void Object::EnablePropertyNotifications()
{
if( mPropertyNotifications )
if( sceneObject != NULL )
{
- SceneGraph::UniformPropertyMapping* map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
+ OwnerPointer< SceneGraph::UniformPropertyMapping > map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
// Message takes ownership of Uniform map (and will delete it after copy)
- AddUniformMapMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *sceneObject, map);
+ AddUniformMapMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *sceneObject, map );
}
else
{
RemoveUniformMapMessage( GetEventThreadServices(), *sceneObject, uniformName);
}
-Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
+Property::Value Object::GetCurrentPropertyValue( const PropertyMetadata* entry ) const
{
Property::Value value;
if( !entry->IsAnimatable() )
{
- value = entry->value;
+ value = entry->GetPropertyValue();
}
else
{
default:
{
- DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
- break;
+ // unreachable code due to higher level logic
}
} // switch(type)
} // if animatable
CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
{
CustomPropertyMetadata* property( NULL );
- int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
- if( arrayIndex >= 0 )
+ if ( ( index >= CHILD_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= CHILD_PROPERTY_REGISTRATION_MAX_INDEX ) )
{
- if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
+ for ( std::size_t arrayIndex = 0; arrayIndex < mCustomProperties.Count(); arrayIndex++ )
{
- property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
+ CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>( mCustomProperties[ arrayIndex ] );
+ if( custom->childPropertyIndex == index )
+ {
+ property = custom;
+ }
+ }
+ }
+ else
+ {
+ int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
+ if( arrayIndex >= 0 )
+ {
+ if( arrayIndex < static_cast<int>( mCustomProperties.Count() ) ) // we can only access the first 2 billion custom properties
+ {
+ property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
+ }
}
}
return property;
AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
{
- for ( int arrayIndex = 0; arrayIndex < (int)mAnimatableProperties.Count(); arrayIndex++ )
+ const PropertyMetadataLookup::SizeType count = mAnimatableProperties.Count();
+ for ( PropertyMetadataLookup::SizeType arrayIndex = 0; arrayIndex < count; ++arrayIndex )
{
AnimatablePropertyMetadata* property = static_cast<AnimatablePropertyMetadata*>( mAnimatableProperties[ arrayIndex ] );
if( property->index == index )
// 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, typeInfo->GetPropertyDefaultValue( basePropertyIndex ) ) )
{
animatableProperty = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[mAnimatableProperties.Size()-1]);
AddUniformMapping( basePropertyIndex, basePropertyName );
if(animatableProperty)
{
// Create the metadata for the property component.
- mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, typeInfo->GetComponentIndex(index), animatableProperty->GetType(), animatableProperty->GetSceneGraphProperty() ) );
+ mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, typeInfo->GetComponentIndex(index), animatableProperty->value, animatableProperty->GetSceneGraphProperty() ) );
}
}
return animatableProperty;
}
+void Object::ResolveChildProperties()
+{
+ // Resolve index for the child property
+ Object* parent = GetParentObject();
+ if( parent )
+ {
+ const TypeInfo* parentTypeInfo( parent->GetTypeInfo() );
+ if( parentTypeInfo )
+ {
+ // Go through each custom property
+ const PropertyMetadataLookup::SizeType count = mCustomProperties.Count();
+ for ( PropertyMetadataLookup::SizeType arrayIndex = 0; arrayIndex < count; ++arrayIndex )
+ {
+ CustomPropertyMetadata* customProperty = static_cast<CustomPropertyMetadata*>( mCustomProperties[ arrayIndex ] );
+
+ if( customProperty->name == "" )
+ {
+ if( customProperty->childPropertyIndex != Property::INVALID_INDEX )
+ {
+ // Resolve name for any child property with no name
+ customProperty->name = parentTypeInfo->GetChildPropertyName( customProperty->childPropertyIndex );
+ }
+ }
+ else
+ {
+ Property::Index childPropertyIndex = parentTypeInfo->GetChildPropertyIndex( customProperty->name );
+ if( childPropertyIndex != Property::INVALID_INDEX )
+ {
+ // Resolve index for any property with a name that matches the parent's child property name
+ customProperty->childPropertyIndex = childPropertyIndex;
+ }
+ }
+ }
+ }
+ }
+}
+
} // namespace Internal
} // namespace Dali