Support animatable property registration during type registry 35/36535/11
authorRichard Huang <r.huang@samsung.com>
Mon, 9 Mar 2015 16:08:24 +0000 (16:08 +0000)
committerRichard Huang <r.huang@samsung.com>
Mon, 23 Mar 2015 17:30:29 +0000 (17:30 +0000)
Use AnimatablePropertyRegistration or DALI_ANIMATABLE_PROPERTY_REGISTRATION
to register the animatable property. The animatable propery will be lazy
registered when it is being accessed.

Change-Id: Idcbf5a55a0d288fe8937a63db1fb087fb968124d

18 files changed:
automated-tests/src/dali/utc-Dali-TypeRegistry.cpp
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/common/object-impl.cpp
dali/internal/event/common/object-impl.h
dali/internal/event/common/property-metadata.h [moved from dali/internal/event/common/custom-property.h with 50% similarity]
dali/internal/event/common/type-info-impl.cpp
dali/internal/event/common/type-info-impl.h
dali/internal/event/common/type-registry-impl.cpp
dali/internal/event/common/type-registry-impl.h
dali/internal/event/effects/shader-effect-impl.cpp
dali/internal/event/effects/shader-effect-impl.h
dali/internal/event/events/pan-gesture-detector-impl.cpp
dali/internal/event/object/custom-object-internal.cpp
dali/public-api/object/property-index-ranges.h
dali/public-api/object/type-registry-helper.h
dali/public-api/object/type-registry.cpp
dali/public-api/object/type-registry.h

index 534b00a..8120663 100644 (file)
@@ -733,8 +733,6 @@ int UtcDaliTypeRegistryCustomSignalFailure(void)
   END_TEST;
 }
 
-
-
 int UtcDaliTypeRegistryInitFunctions(void)
 {
   TestApplication application;
@@ -748,8 +746,6 @@ int UtcDaliTypeRegistryInitFunctions(void)
 }
 
 
-
-
 int UtcDaliTypeRegistryNameInitFunctions(void)
 {
   TestApplication application;
@@ -821,13 +817,42 @@ int UtcDaliPropertyRegistration(void)
   typeInfo.GetPropertyIndices( indices );
   DALI_TEST_EQUALS( indices.size(), 1u, TEST_LOCATION );
 
-  // Ensure indices returned from actor and customActor differ by two
+  // Register animatable property
+  std::string animatablePropertyName( "animatable-prop-1" );
+  int animatablePropertyIndex( ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX );
+  Property::Type animatablePropertyType( Property::FLOAT );
+  AnimatablePropertyRegistration animatableProperty1( customType1, animatablePropertyName, animatablePropertyIndex, animatablePropertyType );
+
+  // Check property count after registration
+  DALI_TEST_EQUALS( customPropertyCount + 1u, customActor.GetPropertyCount(), TEST_LOCATION );
+
+  // Set the animatable property value
+  customActor.SetProperty( animatablePropertyIndex, 25.0f );
+
+  // Render and notify
+  application.SendNotification();
+  application.Render();
+
+  // Check the animatable property value
+  DALI_TEST_EQUALS( customActor.GetProperty< float >( animatablePropertyIndex ), 25.0f, TEST_LOCATION );
+
+  // Check the animatable property name
+  DALI_TEST_EQUALS( customActor.GetPropertyName( animatablePropertyIndex ), animatablePropertyName, TEST_LOCATION );
+//  DALI_TEST_EQUALS( typeInfo.GetPropertyName( animatablePropertyIndex ), animatablePropertyName, TEST_LOCATION );
+
+  // Check the animatable property index
+  DALI_TEST_EQUALS( customActor.GetPropertyIndex( animatablePropertyName ), animatablePropertyIndex, TEST_LOCATION );
+
+  // Check the animatable property type
+  DALI_TEST_EQUALS( customActor.GetPropertyType( animatablePropertyIndex ), animatablePropertyType, TEST_LOCATION );
+
+  // Ensure indices returned from actor and customActor differ by three
   Actor actor = Actor::New();
   actor.GetPropertyIndices( indices );
   unsigned int actorIndices = indices.size();
   customActor.GetPropertyIndices( indices );
   unsigned int customActorIndices = indices.size();
-  DALI_TEST_EQUALS( actorIndices + 2u, customActorIndices, TEST_LOCATION ); // Custom property + registered property
+  DALI_TEST_EQUALS( actorIndices + 3u, customActorIndices, TEST_LOCATION ); // Custom property + registered property
   END_TEST;
 }
 
@@ -857,6 +882,28 @@ int UtcDaliPropertyRegistrationIndexOutOfBounds(void)
   {
     DALI_TEST_ASSERT( e, "( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX )", TEST_LOCATION );
   }
+
+  // Attempt to register an animatable property type out-of-bounds index (less than)
+  try
+  {
+    AnimatablePropertyRegistration property1( customType1, "anim-prop-name", ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX - 1, Property::BOOLEAN );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )", TEST_LOCATION );
+  }
+
+  // Attempt to register an animatable property type out-of-bounds index (greater than)
+  try
+  {
+    AnimatablePropertyRegistration property1( customType1, "anim-prop-name", ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX + 1, Property::BOOLEAN );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX )", TEST_LOCATION );
+  }
   END_TEST;
 }
 
@@ -906,6 +953,21 @@ int UtcDaliPropertyRegistrationAddSameIndex(void)
   {
     DALI_TEST_ASSERT( e, "! \"Property index already added", TEST_LOCATION );
   }
+
+  int animatablePropertyIndex = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 100;
+
+  // Add one property with a valid property index
+  AnimatablePropertyRegistration property3( customType1, "anim-prop-name", animatablePropertyIndex, Property::BOOLEAN );
+
+  // Attempt to add another property with the same index
+  try
+  {
+    AnimatablePropertyRegistration property4( customType1, "anim-prop-name-2", animatablePropertyIndex, Property::BOOLEAN );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "! \"Property index already added", TEST_LOCATION );
+  }
   END_TEST;
 }
 
@@ -937,10 +999,14 @@ int UtcDaliPropertyRegistrationPropertyAnimatable(void)
 {
   TestApplication application;
   int propertyIndex = PROPERTY_REGISTRATION_START_INDEX + 400;
+  int animatablePropertyIndex = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 400;
 
   // These properties are not animatable
   PropertyRegistration property1( customType1, "prop-name", propertyIndex, Property::BOOLEAN, &SetProperty, &GetProperty );
 
+  // These properties are animatable
+  AnimatablePropertyRegistration property2( customType1, "anim-prop-name", animatablePropertyIndex, Property::BOOLEAN );
+
   // Create custom-actor
   TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(MyTestCustomActor) );
   DALI_TEST_CHECK( typeInfo );
@@ -951,6 +1017,17 @@ int UtcDaliPropertyRegistrationPropertyAnimatable(void)
 
   // Check if animatable
   DALI_TEST_CHECK( ! customActor.IsPropertyAnimatable( propertyIndex ) );
+  DALI_TEST_CHECK( customActor.IsPropertyAnimatable( animatablePropertyIndex ) );
+
+  // Create another instance of custom-actor
+  BaseHandle handle2 = typeInfo.CreateInstance();
+  DALI_TEST_CHECK( handle2 );
+  Actor customActor2 = Actor::DownCast( handle2 );
+  DALI_TEST_CHECK( customActor2 );
+
+  // Check if animatable
+  DALI_TEST_CHECK( ! customActor2.IsPropertyAnimatable( propertyIndex ) );
+  DALI_TEST_CHECK( customActor2.IsPropertyAnimatable( animatablePropertyIndex ) );
   END_TEST;
 }
 
@@ -958,6 +1035,7 @@ int UtcDaliPropertyRegistrationInvalidGetAndSet(void)
 {
   TestApplication application;
   int propertyIndex = PROPERTY_REGISTRATION_START_INDEX + 2000;
+  int animatablePropertyIndex = ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX + 2000;
 
   // Create custom-actor
   TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(MyTestCustomActor) );
@@ -978,6 +1056,16 @@ int UtcDaliPropertyRegistrationInvalidGetAndSet(void)
     DALI_TEST_ASSERT( e, "! \"Cannot find property index", TEST_LOCATION );
   }
 
+  try
+  {
+    customActor.SetProperty( animatablePropertyIndex, true );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
+
   // Try to get an index that hasn't been added
   try
   {
@@ -988,11 +1076,20 @@ int UtcDaliPropertyRegistrationInvalidGetAndSet(void)
   {
     DALI_TEST_ASSERT( e, "! \"Cannot find property index", TEST_LOCATION );
   }
+
+  try
+  {
+    (void) customActor.GetProperty< bool >( animatablePropertyIndex );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
   END_TEST;
 }
 
 
-
 int UtcDaliLongPressGestureDetectorTypeRegistry(void)
 {
   TestApplication application;
index 0bbe1d3..427b749 100644 (file)
@@ -2569,7 +2569,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
 }
 
 // TODO: This method needs to be removed
-void Actor::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
+void Actor::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
 {
   OnPropertySet(index, value);
 
@@ -2993,7 +2993,7 @@ const PropertyBase* Actor::GetSceneObjectAnimatableProperty( Property::Index ind
 
   if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
   {
-    CustomProperty* custom = FindCustomProperty( index );
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
 
     property = custom->GetSceneGraphProperty();
@@ -3098,7 +3098,7 @@ const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index ind
 
   if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
   {
-    CustomProperty* custom = FindCustomProperty( index );
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
     property = custom->GetSceneGraphProperty();
   }
index d6a17db..6cf654c 100644 (file)
@@ -1193,7 +1193,7 @@ public: // Default property extensions from Object
   /**
    * @copydoc Dali::Internal::Object::SetSceneGraphProperty()
    */
-  virtual void SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value );
+  virtual void SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value );
 
   /**
    * @copydoc Dali::Internal::Object::GetDefaultProperty()
index e435c7b..b404f60 100644 (file)
@@ -173,7 +173,8 @@ std::string Object::GetPropertyName( Property::Index index ) const
     return GetDefaultPropertyName( index );
   }
 
-  if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+  if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+    || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
   {
     const TypeInfo* typeInfo( GetTypeInfo() );
     if ( typeInfo )
@@ -186,7 +187,7 @@ std::string Object::GetPropertyName( Property::Index index ) const
     }
   }
 
-  CustomProperty* custom = FindCustomProperty( index );
+  CustomPropertyMetadata* custom = FindCustomProperty( index );
   if( custom )
   {
     return custom->name;
@@ -198,22 +199,35 @@ Property::Index Object::GetPropertyIndex(const std::string& name) const
 {
   Property::Index index = GetDefaultPropertyIndex( name );
 
-  if ( index == Property::INVALID_INDEX )
+  if(index == Property::INVALID_INDEX)
   {
     const TypeInfo* typeInfo( GetTypeInfo() );
     if ( typeInfo )
     {
       index = typeInfo->GetPropertyIndex( name );
+      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 = FindAnimatableProperty( index );
+        if(!animatableProperty)
+        {
+          const TypeInfo* typeInfo( GetTypeInfo() );
+          if (typeInfo)
+          {
+            index = RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index)));
+          }
+        }
+      }
     }
   }
 
-  if( ( index == Property::INVALID_INDEX )&&( mCustomProperties.Count() > 0 ) )
+  if( (index == Property::INVALID_INDEX)&&( mCustomProperties.Count() > 0 ) )
   {
     Property::Index count = PROPERTY_CUSTOM_START_INDEX;
-    const CustomPropertyLookup::ConstIterator end = mCustomProperties.End();
-    for( CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
+    const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
+    for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
     {
-      CustomProperty* custom = *iter;
+      CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
       if ( custom->name == name )
       {
         index = count;
@@ -229,77 +243,104 @@ bool Object::IsPropertyWritable( Property::Index index ) const
 {
   DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
 
+  bool writable = false;
+
   if ( index < DEFAULT_PROPERTY_MAX_COUNT )
   {
-    return IsDefaultPropertyWritable( index );
+    writable = IsDefaultPropertyWritable( index );
   }
-
-  if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+  else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
     const TypeInfo* typeInfo( GetTypeInfo() );
     if ( typeInfo )
     {
-      return typeInfo->IsPropertyWritable( index );
+      writable = typeInfo->IsPropertyWritable( index );
     }
     else
     {
       DALI_ASSERT_ALWAYS( ! "Invalid property index" );
     }
   }
-
-  CustomProperty* custom = FindCustomProperty( index );
-  if( custom )
+  else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
-    return custom->IsWritable();
+    // Type Registry scene-graph properties are writable.
+    writable = true;
   }
-  return false;
+  else
+  {
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
+    if( custom )
+    {
+      writable = custom->IsWritable();
+    }
+  }
+
+  return writable;
 }
 
 bool Object::IsPropertyAnimatable( Property::Index index ) const
 {
   DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
 
+  bool animatable = false;
+
   if ( index < DEFAULT_PROPERTY_MAX_COUNT )
   {
-    return IsDefaultPropertyAnimatable( index );
+    animatable = IsDefaultPropertyAnimatable( index );
   }
-
-  if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+  else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
     // Type Registry event-thread only properties are not animatable.
-    return false;
+    animatable = false;
   }
-
-  CustomProperty* custom = FindCustomProperty( index );
-  if( custom )
+  else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+  {
+    // Type Registry scene-graph properties are animatable.
+    animatable = true;
+  }
+  else
   {
-    return custom->IsAnimatable();
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
+    if( custom )
+    {
+      animatable = custom->IsAnimatable();
+    }
   }
-  return false;
+
+  return animatable;
 }
 
 bool Object::IsPropertyAConstraintInput( Property::Index index ) const
 {
   DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
 
+  bool isConstraintInput = false;
+
   if ( index < DEFAULT_PROPERTY_MAX_COUNT )
   {
-    return IsDefaultPropertyAConstraintInput( index );
+    isConstraintInput = IsDefaultPropertyAConstraintInput( index );
   }
-
-  if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+  else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
     // Type Registry event-thread only properties cannot be used as an input to a constraint.
-    return false;
+    isConstraintInput = false;
   }
-
-  CustomProperty* custom = FindCustomProperty( index );
-  if( custom )
+  else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
-    // ... custom properties can be used as input to a constraint.
-    return true;
+    // scene graph properties can be used as input to a constraint.
+    isConstraintInput = true;
   }
-  return false;
+  else
+  {
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
+    if( custom )
+    {
+      // ... custom properties can be used as input to a constraint.
+      isConstraintInput = true;
+    }
+  }
+
+  return isConstraintInput;
 }
 
 Property::Type Object::GetPropertyType( Property::Index index ) const
@@ -311,7 +352,8 @@ Property::Type Object::GetPropertyType( Property::Index index ) const
     return GetDefaultPropertyType( index );
   }
 
-  if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+  if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
+    || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
   {
     const TypeInfo* typeInfo( GetTypeInfo() );
     if ( typeInfo )
@@ -324,7 +366,7 @@ Property::Type Object::GetPropertyType( Property::Index index ) const
     }
   }
 
-  CustomProperty* custom = FindCustomProperty( index );
+  CustomPropertyMetadata* custom = FindCustomProperty( index );
   if( custom )
   {
     return custom->type;
@@ -349,24 +391,52 @@ void Object::SetProperty( Property::Index index, const Property::Value& property
     }
     else
     {
-      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+      DALI_LOG_ERROR("Cannot find property index\n");
     }
   }
-  else
+  else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
-    CustomProperty* custom = FindCustomProperty( index );
-    DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
-    if( custom->IsAnimatable() )
+    // check whether the animatable property is registered already, if not then register one.
+    AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
+    if(!animatableProperty)
+    {
+      const TypeInfo* typeInfo( GetTypeInfo() );
+      if (typeInfo && Property::INVALID_INDEX == RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, propertyValue))
+      {
+        DALI_LOG_ERROR("Cannot register property\n");
+      }
+      else
+      {
+        DALI_LOG_ERROR("Cannot find property index\n");
+      }
+    }
+    else
     {
       // set the scene graph property value
-      SetSceneGraphProperty( index, *custom, propertyValue );
+      SetSceneGraphProperty( index, *animatableProperty, propertyValue );
+    }
+  }
+  else
+  {
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
+    if( custom )
+    {
+      if( custom->IsAnimatable() )
+      {
+        // set the scene graph property value
+        SetSceneGraphProperty( index, *custom, propertyValue );
+      }
+      else if( custom->IsWritable() )
+      {
+        custom->value = propertyValue;
+        OnPropertySet(index, propertyValue);
+      }
+      // trying to set value on read only property is no-op
     }
-    else if( custom->IsWritable() )
+    else
     {
-      custom->value = propertyValue;
-      OnPropertySet(index, propertyValue);
+      DALI_LOG_ERROR("Invalid property index\n");
     }
-    // trying to set value on read only property is no-op
   }
 }
 
@@ -389,113 +459,50 @@ Property::Value Object::GetProperty(Property::Index index) const
     }
     else
     {
-      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+      DALI_LOG_ERROR("Cannot find property index\n");
     }
   }
-  else if( mCustomProperties.Count() > 0 )
+  else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
   {
-    CustomProperty* custom = FindCustomProperty( index );
-    DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
-
-    if( !custom->IsAnimatable() )
-    {
-      value = custom->value;
-    }
-    else
+    // check whether the animatable property is registered already, if not then register one.
+    AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
+    if(!animatableProperty)
     {
-      BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
-
-      switch ( custom->type )
+      const TypeInfo* typeInfo( GetTypeInfo() );
+      if (typeInfo)
       {
-        case Property::BOOLEAN:
-        {
-          const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::FLOAT:
-        {
-          const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::INTEGER:
+        if(Property::INVALID_INDEX != RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index))))
         {
-          const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
+          value = Property::Value(typeInfo->GetPropertyType(index)); // Return an initialized property value according to the type
         }
-
-        case Property::VECTOR2:
+        else
         {
-          const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
+          DALI_LOG_ERROR("Cannot register property\n");
         }
-
-        case Property::VECTOR3:
-        {
-          const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::VECTOR4:
-        {
-          const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::MATRIX:
-        {
-          const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::MATRIX3:
-        {
-          const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        case Property::ROTATION:
-        {
-          const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( custom->GetSceneGraphProperty() );
-          DALI_ASSERT_DEBUG( NULL != property );
-
-          value = (*property)[ bufferIndex ];
-          break;
-        }
-
-        default:
-        {
-          DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
-          break;
-        }
-      } // switch(type)
-    } // if animatable
-
+      }
+      else
+      {
+        DALI_LOG_ERROR("Cannot find property index\n");
+      }
+    }
+    else
+    {
+      // get the animatable property value
+      value = GetPropertyValue( animatableProperty );
+    }
+  }
+  else if(mCustomProperties.Count() > 0)
+  {
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
+    if(custom)
+    {
+      // get the custom property value
+      value = GetPropertyValue( custom );
+    }
+    else
+    {
+      DALI_LOG_ERROR("Invalid property index\n");
+    }
   } // if custom
 
   return value;
@@ -520,8 +527,8 @@ void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
   {
     indices.reserve( indices.size() + mCustomProperties.Count() );
 
-    CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin();
-    const CustomPropertyLookup::ConstIterator endIter = mCustomProperties.End();
+    PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin();
+    const PropertyMetadataLookup::ConstIterator endIter = mCustomProperties.End();
     int i=0;
     for ( ; iter != endIter; ++iter, ++i )
     {
@@ -530,7 +537,7 @@ void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
   }
 }
 
-Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
+Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
 {
   // Create a new property
   Dali::Internal::OwnerPointer<PropertyBase> newProperty;
@@ -612,28 +619,39 @@ Property::Index Object::RegisterProperty( const std::string& name, const Propert
 
   // get the scene property owner from derived class
   const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
-  Property::Index index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
   // we can only pass properties to scene graph side if there is a scene object
   if( scenePropertyOwner )
   {
     // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
     const PropertyBase* property = newProperty.Get();
-    mCustomProperties.PushBack( new CustomProperty( name, propertyValue.GetType(), property ) );
+    if(index >= PROPERTY_CUSTOM_START_INDEX)
+    {
+      mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
+    }
+    else
+    {
+      mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( propertyValue.GetType(), property ) );
+    }
 
     // queue a message to add the property
-    InstallCustomPropertyMessage( GetEventThreadServices(), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
+    InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty.Release() ); // 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
     NotifyScenePropertyInstalled( *property, name, index );
+
+    return index;
   }
   else
   {
     // property was orphaned and killed so return invalid index
-    index = Property::INVALID_INDEX;
+    return Property::INVALID_INDEX;
   }
+}
 
-  return index;
+Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
+{
+  return RegisterSceneGraphProperty(name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue);
 }
 
 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
@@ -648,7 +666,7 @@ Property::Index Object::RegisterProperty( const std::string& name, const Propert
   {
     // Add entry to the property lookup
     index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
-    mCustomProperties.PushBack( new CustomProperty( name, propertyValue, accessMode ) );
+    mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
   }
 
   return index;
@@ -666,7 +684,7 @@ Dali::PropertyNotification Object::AddPropertyNotification(Property::Index index
     }
     else if ( mCustomProperties.Count() > 0 )
     {
-      CustomProperty* custom = FindCustomProperty( index );
+      CustomPropertyMetadata* custom = FindCustomProperty( index );
       DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
       DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
     }
@@ -791,7 +809,115 @@ ActiveConstraintBase* Object::DoApplyConstraint( Constraint& constraint, Dali::H
   return activeConstraintImpl;
 }
 
-void Object::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
+Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
+{
+  Property::Value value;
+
+  DALI_ASSERT_ALWAYS( entry && "Invalid property metadata" );
+
+  if( !entry->IsAnimatable() )
+  {
+    value = entry->value;
+  }
+  else
+  {
+    BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
+
+    switch ( entry->type )
+    {
+      case Property::BOOLEAN:
+      {
+        const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::FLOAT:
+      {
+        const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::INTEGER:
+      {
+        const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::VECTOR2:
+      {
+        const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::VECTOR3:
+      {
+        const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::VECTOR4:
+      {
+        const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::MATRIX:
+      {
+        const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::MATRIX3:
+      {
+        const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      case Property::ROTATION:
+      {
+        const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->GetSceneGraphProperty() );
+        DALI_ASSERT_DEBUG( NULL != property );
+
+        value = (*property)[ bufferIndex ];
+        break;
+      }
+
+      default:
+      {
+        DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
+        break;
+      }
+    } // switch(type)
+  } // if animatable
+
+  return value;
+}
+
+void Object::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
 {
   switch ( entry.type )
   {
@@ -1012,15 +1138,29 @@ Object::~Object()
   delete mPropertyNotifications;
 }
 
-CustomProperty* Object::FindCustomProperty( Property::Index index ) const
+CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
 {
-  CustomProperty* property( NULL );
+  CustomPropertyMetadata* property( NULL );
   int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
   if( arrayIndex >= 0 )
   {
     if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
     {
-      property = mCustomProperties[ arrayIndex ];
+      property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
+    }
+  }
+  return property;
+}
+
+AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
+{
+  AnimatablePropertyMetadata* property( NULL );
+  int arrayIndex = index - ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX;
+  if( arrayIndex >= 0 )
+  {
+    if( arrayIndex < (int)mAnimatableProperties.Count() )
+    {
+      property = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[ arrayIndex ]);
     }
   }
   return property;
index fc2598d..bb09d8c 100644 (file)
@@ -29,9 +29,9 @@
 #include <dali/public-api/object/property-input.h>
 #include <dali/public-api/object/property-notification.h>
 #include <dali/internal/common/owner-container.h>
-#include <dali/internal/event/common/custom-property.h>
 #include <dali/internal/event/common/event-thread-services.h>
 #include <dali/internal/event/common/property-input-impl.h>
+#include <dali/internal/event/common/property-metadata.h>
 #include <dali/internal/update/common/property-base.h>
 
 namespace Dali
@@ -325,7 +325,14 @@ protected:
    * @param index
    * @return pointer to the property
    */
-  CustomProperty* FindCustomProperty( Property::Index index ) const;
+  CustomPropertyMetadata* FindCustomProperty( Property::Index index ) const;
+
+  /**
+   * Helper to find animatable property
+   * @param index
+   * @return pointer to the property
+   */
+  AnimatablePropertyMetadata* FindAnimatableProperty( Property::Index index ) const;
 
 private: // Default property extensions for derived classes
 
@@ -418,7 +425,7 @@ private: // Default property extensions for derived classes
    * @param [in] name The name allocated to this custom property.
    * @param [in] index The index allocated to this custom property.
    */
-  virtual void NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
+  virtual void NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index ) const
   { }
 
 private:
@@ -453,12 +460,28 @@ private:
   void RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph );
 
   /**
+   * Get the value of the property.
+   * @param [in] entry An entry from the property lookup container.
+   * @return The new value of the property.
+   */
+  Property::Value GetPropertyValue( const PropertyMetadata* entry ) const;
+
+  /**
    * Set the value of scene graph property.
    * @param [in] index The index of the property.
-   * @param [in] entry An entry from the CustomPropertyLookup.
+   * @param [in] entry An entry from the property lookup container.
    * @param [in] value The new value of the property.
    */
-  virtual void SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value );
+  virtual void SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value );
+
+  /**
+   * Helper to register a scene-graph property
+   * @param [in] name The name 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;
 
 protected:
   /**
@@ -492,8 +515,9 @@ private:
 
 private:
 
-  typedef OwnerContainer<CustomProperty*> CustomPropertyLookup;
-  CustomPropertyLookup mCustomProperties; ///< Used for accessing custom Node properties
+  typedef OwnerContainer<PropertyMetadata*> PropertyMetadataLookup;
+  mutable PropertyMetadataLookup mCustomProperties; ///< Used for accessing custom Node properties
+  mutable PropertyMetadataLookup mAnimatableProperties; ///< Used for accessing animatable Node properties
   mutable TypeInfo const *  mTypeInfo; ///< The type-info for this object, mutable so it can be lazy initialized from const method if it is required
 
   Dali::Vector<Observer*> mObservers;
@@ -1,5 +1,5 @@
-#ifndef __DALI_INTERNAL_SCENE_GRAPH_CUSTOM_PROPERTY_H__
-#define __DALI_INTERNAL_SCENE_GRAPH_CUSTOM_PROPERTY_H__
+#ifndef __DALI_INTERNAL_PROPERTY_METADATA_H__
+#define __DALI_INTERNAL_PROPERTY_METADATA_H__
 
 /*
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
@@ -38,7 +38,7 @@ class PropertyBase;
 }
 
 /**
- * An entry in a scene-graph property lookup.
+ * An entry in a property metadata lookup.
  * The type field should be queried, before accessing the scene-graph property:
  *
  * @code
@@ -52,45 +52,48 @@ class PropertyBase;
  * @endcode
  *
  */
-class CustomProperty
+class PropertyMetadata
 {
 public:
 
   /**
-   * Constructor for scene graph based properties
-   * @param [in] newName The name 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.
+   * Constructor for an uninitalized property metadata
    */
-  CustomProperty( const std::string& newName,
-                  Property::Type newType,
-                  const SceneGraph::PropertyBase* newProperty)
-  : name(newName),
-    type(newType),
+  PropertyMetadata()
+  : type(Property::NONE),
+    value(),
+    mProperty(NULL)
+  {
+  }
+
+  /**
+   * Constructor for property metadata
+   * @param [in] newProperty A pointer to the property metadata.
+   */
+  PropertyMetadata(const SceneGraph::PropertyBase* newProperty)
+  : type(Property::NONE),
     value(), // value is held by newProperty
-    mProperty(newProperty),
-    mAccessMode(Property::ANIMATABLE)
+    mProperty(newProperty)
   {
     DALI_ASSERT_DEBUG(mProperty && "Uninitialized scenegraph property") ;
   }
 
   /**
-   * Constructor for event side only properties
-   * @param [in] newName The name of the custom property.
-   * @param [in] newIndex The index 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.
+   * Constructor for property metadata
+   * @param [in] newValue The value of the scene-graph owned property.
    */
-  CustomProperty( const std::string& newName,
-                  Property::Value newValue,
-                  Property::AccessMode accessMode )
-  : name(newName),
-    type(newValue.GetType()),
+  PropertyMetadata(Property::Value newValue)
+  : type(newValue.GetType()),
     value(newValue),
-    mProperty(NULL),
-    mAccessMode(accessMode)
+    mProperty(NULL)
+  {
+  }
+
+  /**
+   * Destructor for property metadata
+   */
+  virtual ~PropertyMetadata()
   {
-    DALI_ASSERT_DEBUG(accessMode != Property::ANIMATABLE && "Animatable must have scenegraph property") ;
   }
 
   /**
@@ -104,10 +107,7 @@ public:
   /**
    * @return true if the property can be written to
    */
-  bool IsWritable(void) const
-  {
-    return (mAccessMode == Property::ANIMATABLE) || (mAccessMode == Property::READ_WRITE) ;
-  }
+  virtual bool IsWritable(void) const = 0;
 
   /**
    * @return the scene graph property
@@ -118,19 +118,121 @@ public:
     return mProperty;
   }
 
-  std::string name;       ///< The name of the property
   Property::Type type;    ///< The type of the property
   Property::Value value;  ///< The property value for a non animatable and custom property
 
+protected:
+
+  // Not implemented
+  PropertyMetadata( const PropertyMetadata& );
+  PropertyMetadata& operator=( const PropertyMetadata& );
+
+  const SceneGraph::PropertyBase* mProperty; ///< A pointer to a scene-graph property; should not be modified from actor-thread.
+};
+
+
+/**
+ * An entry in an animatable property metadata lookup.
+ * The type field should be queried, before accessing the animatable property:
+ */
+class AnimatablePropertyMetadata : public PropertyMetadata
+{
+public:
+
+  /**
+   * Constructor for metadata of animatable property
+   * @param [in] newProperty A pointer to the scene-graph owned property.
+   */
+  AnimatablePropertyMetadata( Property::Type newType,
+                        const SceneGraph::PropertyBase* newProperty )
+  {
+    type = newType;
+    mProperty = newProperty;
+    DALI_ASSERT_DEBUG(mProperty && "Uninitialized scenegraph property") ;
+  }
+
+  /**
+   * Constructor for metadata of animatable property
+   * @param [in] newValue The value of the scene-graph owned property.
+   */
+  AnimatablePropertyMetadata( Property::Value newValue )
+  {
+    type = newValue.GetType();
+    value = newValue;
+  }
+
+  /**
+   * @return true if the property can be written to
+   */
+  virtual bool IsWritable(void) const
+  {
+    return true ;
+  }
+
+private:
+
+  // Not implemented
+  AnimatablePropertyMetadata();
+  AnimatablePropertyMetadata( const AnimatablePropertyMetadata& );
+  AnimatablePropertyMetadata& operator=( const AnimatablePropertyMetadata& );
+};
+
+class CustomPropertyMetadata : public PropertyMetadata
+{
+public:
+
+  /**
+   * Constructor for metadata of scene graph based properties
+   * @param [in] newName The name 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::Type newType,
+                  const SceneGraph::PropertyBase* newProperty)
+  : name(newName),
+    mAccessMode(Property::ANIMATABLE)
+  {
+    type = newType;
+    mProperty = newProperty;
+    DALI_ASSERT_DEBUG(mProperty && "Uninitialized scenegraph property") ;
+  }
+
+  /**
+   * Constructor for metadata of event side only properties
+   * @param [in] newName The name of the custom property.
+   * @param [in] newValue The value of the custom property.
+   * @param [in] accessMode The access mode of the custom property (writable, animatable etc).
+   */
+  CustomPropertyMetadata( const std::string& newName,
+                  Property::Value newValue,
+                  Property::AccessMode accessMode )
+  : name(newName),
+    mAccessMode(accessMode)
+  {
+    type = newValue.GetType();
+    value = newValue;
+    DALI_ASSERT_DEBUG(accessMode != Property::ANIMATABLE && "Animatable must have scenegraph property") ;
+  }
+
+  /**
+   * @return true if the property can be written to
+   */
+  virtual bool IsWritable(void) const
+  {
+    return (mAccessMode == Property::ANIMATABLE) || (mAccessMode == Property::READ_WRITE) ;
+  }
+
+  std::string name;       ///< The name of the property
+
 private:
 
   // Not implemented
-  CustomProperty();
-  CustomProperty( const CustomProperty& );
-  CustomProperty& operator=( const CustomProperty& );
+  CustomPropertyMetadata();
+  CustomPropertyMetadata( const CustomPropertyMetadata& );
+  CustomPropertyMetadata& operator=( const CustomPropertyMetadata& );
 
 private:
-  const SceneGraph::PropertyBase* mProperty; ///< A pointer to a scene-graph property; should not be modified from actor-thread.
   Property::AccessMode mAccessMode; ///< The mode of the property
 };
 
@@ -138,4 +240,4 @@ private:
 
 } // namespace Dali
 
-#endif // __DALI_INTERNAL_SCENE_GRAPH_CUSTOM_PROPERTY_H__
+#endif // __DALI_INTERNAL_PROPERTY_METADATA_H__
index 91e50cf..6f2b62f 100644 (file)
@@ -347,6 +347,21 @@ void TypeInfo::AddProperty( const std::string& name, Property::Index index, Prop
   }
 }
 
+void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
+{
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                        PairFinder< Property::Index, RegisteredPropertyPair>(index) );
+
+  if ( iter == mRegisteredProperties.end() )
+  {
+    mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name ) ) );
+  }
+  else
+  {
+    DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
+  }
+}
+
 unsigned int TypeInfo::GetPropertyCount() const
 {
   unsigned int count( mRegisteredProperties.size() );
@@ -395,7 +410,14 @@ bool TypeInfo::IsPropertyWritable( Property::Index index ) const
 
   if ( iter != mRegisteredProperties.end() )
   {
-    writable = iter->second.setFunc ? true : false;
+    if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
+    {
+      writable = true; // animatable property is writable
+    }
+    else
+    {
+      writable = iter->second.setFunc ? true : false;
+    }
   }
   else
   {
index 8233007..b6545a0 100644 (file)
@@ -124,6 +124,14 @@ public:
   void AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc );
 
   /**
+   * Adds an animatable property to the type.
+   * @param[in] name The name of the property.
+   * @param[in] index The index of the property
+   * @param[in] type The Property::Type.
+   */
+  void AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type );
+
+  /**
    * Do an action on base object
    * @param [in] object The base object to act upon
    * @param [in] actionName The name of the desired action
index 0cb2d68..23e6cc3 100644 (file)
@@ -211,6 +211,22 @@ bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::st
   return false;
 }
 
+bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
+{
+  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
+
+  if( iter != mRegistryLut.end() )
+  {
+    DALI_ASSERT_DEBUG(iter->second);
+
+    GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
+
+    return true;
+  }
+
+  return false;
+}
+
 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
 {
   bool done = false;
index 72e07f7..ce5d64e 100644 (file)
@@ -111,6 +111,16 @@ public:
    */
   bool RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc );
 
+  /**
+   * Register a scene graph only property with a type
+   * @param [in] registered TypeRegistration object used to register the type
+   * @param [in] name Property name
+   * @param [in] index Property index
+   * @param [in] type Property type
+   * @return true if registered
+   */
+  bool RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type );
+
   /*
    * @copydoc Dali::Internal::TypeInfo::DoActionTo
    * Walks all base types until it finds a doer.
index 18ba680..8879918 100644 (file)
@@ -577,7 +577,7 @@ Property::Value ShaderEffect::GetDefaultProperty(Property::Index /*index*/) cons
   return Property::Value();
 }
 
-void ShaderEffect::NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index )
+void ShaderEffect::NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index ) const
 {
   // Warning - the property is added to the Shader object in the Update thread and the meta-data is added in the Render thread (through a secondary message)
 
@@ -594,9 +594,9 @@ const SceneGraph::PropertyOwner* ShaderEffect::GetSceneObject() const
 
 const PropertyBase* ShaderEffect::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  CustomProperty* custom = FindCustomProperty( index );
-  DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
-  return custom->GetSceneGraphProperty();
+  PropertyMetadata* property = index >= PROPERTY_CUSTOM_START_INDEX ? static_cast<PropertyMetadata*>(FindCustomProperty( index )) : static_cast<PropertyMetadata*>(FindAnimatableProperty( index ));
+  DALI_ASSERT_ALWAYS( property && "Property index is invalid" );
+  return property->GetSceneGraphProperty();
 }
 
 const PropertyInputImpl* ShaderEffect::GetSceneObjectInputProperty( Property::Index index ) const
index d69ced1..4394eb7 100644 (file)
@@ -187,7 +187,7 @@ public: // Default property extensions from Object
   /**
    * @copydoc Dali::Internal::Object::NotifyScenePropertyInstalled()
    */
-  virtual void NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index );
+  virtual void NotifyScenePropertyInstalled( const SceneGraph::PropertyBase& newProperty, const std::string& name, unsigned int index ) const;
 
   /**
    * @copydoc Dali::Internal::Object::GetSceneObject()
index da0ba35..487da4e 100644 (file)
@@ -533,7 +533,7 @@ const PropertyInputImpl* PanGestureDetector::GetSceneObjectInputProperty( Proper
 
   if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
   {
-    CustomProperty* custom = FindCustomProperty( index );
+    CustomPropertyMetadata* custom = FindCustomProperty( index );
     DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
     property = custom->GetSceneGraphProperty();
   }
index cfacb37..bc19b73 100644 (file)
@@ -48,7 +48,7 @@ const SceneGraph::PropertyOwner* CustomObject::GetSceneObject() const
 
 const PropertyBase* CustomObject::GetSceneObjectAnimatableProperty( Property::Index index ) const
 {
-  CustomProperty* custom = FindCustomProperty( index );
+  CustomPropertyMetadata* custom = FindCustomProperty( index );
   DALI_ASSERT_ALWAYS( custom && "Property index is invalid" );
   return custom->GetSceneGraphProperty();
 }
index faabd6f..8c3509e 100644 (file)
@@ -47,6 +47,10 @@ enum PropertyRanges
   DEFAULT_PROPERTY_MAX_COUNT                    = PROPERTY_REGISTRATION_START_INDEX,           ///< Default Property Range: 0 to 9999999
 
   PROPERTY_REGISTRATION_MAX_INDEX               = 19999999,   ///< The maximum index supported when registering a property
+
+  ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX  = 20000000,   ///< The index when registering an animatable property should start from this number.
+  ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX    = 29999999,   ///< The maximum index supported when registering an animatable property
+
   PROPERTY_CUSTOM_START_INDEX                   = 50000000,   ///< The index at which custom properties start
 };
 
index 15fc090..e2b8ac6 100644 (file)
@@ -43,6 +43,10 @@ namespace Internal
   PropertyRegistration DALI_TOKEN_PASTE( property, count ) ( typeRegistrationObject, text, Toolkit::objectType::Property::enumIndex, Property::valueType, &objectType::SetProperty, &objectType::GetProperty ); \
   DALI_COMPILE_TIME_ASSERT( ( Toolkit::objectType::Property::enumIndex - Toolkit::objectType::PROPERTY_START_INDEX ) == count );
 
+#define DALI_ANIMATABLE_PROPERTY_REGISTRATION_INTERNAL( count, typeRegistrationObject, objectType, text, valueType, enumIndex) \
+  AnimatablePropertyRegistration DALI_TOKEN_PASTE( property, count ) ( typeRegistrationObject, text, Toolkit::objectType::AnimatableProperty::enumIndex, Property::valueType ); \
+  DALI_COMPILE_TIME_ASSERT( ( Toolkit::objectType::AnimatableProperty::enumIndex - Toolkit::objectType::ANIMATABLE_PROPERTY_START_INDEX ) == count );
+
 #define DALI_SIGNAL_REGISTRATION_INTERNAL( count, typeRegistrationObject, objectType, text, textVariable ) \
   const char* const textVariable = text; \
   SignalConnectorType DALI_TOKEN_PASTE( signalConnector, count ) ( typeRegistrationObject, text, &Toolkit::Internal::objectType::DoConnectSignal );
@@ -62,6 +66,9 @@ namespace Internal
 #define DALI_PROPERTY_REGISTRATION( objectType, text, valueType, enumIndex ) \
   DALI_PROPERTY_REGISTRATION_INTERNAL( __COUNTER__, typeRegistration, objectType, text, valueType, enumIndex )
 
+#define DALI_ANIMATABLE_PROPERTY_REGISTRATION( objectType, text, valueType, enumIndex ) \
+  DALI_ANIMATABLE_PROPERTY_REGISTRATION_INTERNAL( __COUNTER__, typeRegistration, objectType, text, valueType, enumIndex )
+
 #define DALI_SIGNAL_REGISTRATION( objectType, text, textVariable ) \
   DALI_SIGNAL_REGISTRATION_INTERNAL( __COUNTER__, typeRegistration, objectType, text, textVariable )
 
index 93286fb..af04a4b 100644 (file)
@@ -130,4 +130,11 @@ PropertyRegistration::PropertyRegistration( TypeRegistration& registered, const
   Internal::TypeRegistry::Get()->RegisterProperty( registered, name, index, type, setFunc, getFunc );
 }
 
+AnimatablePropertyRegistration::AnimatablePropertyRegistration( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
+{
+  DALI_ASSERT_ALWAYS( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) );
+
+  Internal::TypeRegistry::Get()->RegisterAnimatableProperty( registered, name, index, type );
+}
+
 } // namespace Dali
index 3c05cd7..561231b 100644 (file)
@@ -279,6 +279,30 @@ public:
                         TypeInfo::SetPropertyFunction setFunc, TypeInfo::GetPropertyFunction getFunc );
 };
 
+/**
+ * @brief Register an animatable property for the given type.
+ */
+class DALI_IMPORT_API AnimatablePropertyRegistration
+{
+public:
+
+  /**
+   * @brief This constructor registers the animatable property with the registered type.
+   *
+   * This constructor is for scene-graph only properties where the
+   * value of the property can be retrieved and set via specified
+   * functions.
+   *
+   * @param [in] registered The TypeRegistration object
+   * @param [in] name The name of the property
+   * @param [in] index The property index. Must be a value between ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX and ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX inclusive.
+   * @param [in] type The property value type.
+   *
+   * @pre "registered" must be registered with the TypeRegistry.
+   */
+  AnimatablePropertyRegistration( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type );
+};
+
 } // namespace Dali
 
 #endif // header