(Properties) Added ability to add non-animatable event-thread only properties via...
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Tue, 18 Feb 2014 17:27:45 +0000 (17:27 +0000)
committerPaul Wisbey <p.wisbey@samsung.com>
Mon, 3 Mar 2014 18:34:53 +0000 (18:34 +0000)
[Issue#]   N/A
[Problem]  1) Toolkit in particular, but objects in general have several properties which do not
              require any instance on the update-thread. This was partly why the OnPropertySet()
              virtual method was added to CustomActor but this is intrinsically broken as the same
              property could be set indirectly from the OnPropertySet() method which could cause
              an unwanted loop.
           2) Additionally, due to the change of property numbers where there are numerical gaps
              between base and derived class properties, it has become quite difficult to retrieve
              all properties for a certain class/object.
[Cause]    N/A
[Solution] 1) A property registration system has been introduced which allows properties to be
              dynamically added to a class on library load time (using the type-registry).
              Upon registration, a getter and setter is specified.
              Number ranges are used for property indices to distinguish between property types:
               - Default Properties range from 0 to 10000000.
               - Currently, event-only properties use 10000000 to 19999999.
               - Custom properties are anything equal to or greater than 50000000.
           2) Added a method to Object which retrieves a container of all the indices that an
              object has. Only the indices are required as the name, type etc. can be retrieved by
              using existing methods (if the index is known).

Change-Id: Icd477996465a4fb291f446feffa65ce2eb8c9120

64 files changed:
automated-tests/dali-test-suite/actors/utc-Dali-CameraActor.cpp
automated-tests/dali-test-suite/actors/utc-Dali-Handle.cpp
automated-tests/dali-test-suite/actors/utc-Dali-ImageActor.cpp
automated-tests/dali-test-suite/actors/utc-Dali-Layer.cpp
automated-tests/dali-test-suite/actors/utc-Dali-LightActor.cpp
automated-tests/dali-test-suite/actors/utc-Dali-MeshActor.cpp
automated-tests/dali-test-suite/actors/utc-Dali-TextActor.cpp
automated-tests/dali-test-suite/animation/utc-Dali-ActiveConstraint.cpp
automated-tests/dali-test-suite/animation/utc-Dali-Constraint.cpp
automated-tests/dali-test-suite/effects/utc-Dali-ShaderEffect.cpp
automated-tests/dali-test-suite/events/utc-Dali-PanGestureDetector.cpp
automated-tests/dali-test-suite/geometry/utc-Dali-AnimatableMesh.cpp
automated-tests/dali-test-suite/property-notification/utc-Dali-PropertyNotification.cpp
automated-tests/dali-test-suite/render-tasks/utc-Dali-RenderTask.cpp
automated-tests/dali-test-suite/type-registry/utc-Dali-TypeRegistry.cpp
capi/dali/public-api/dali-core-capi-internal.h
capi/dali/public-api/file.list
capi/dali/public-api/geometry/animatable-mesh.h
capi/dali/public-api/object/base-handle.h
capi/dali/public-api/object/base-object.h
capi/dali/public-api/object/handle.h
capi/dali/public-api/object/property.h
dali/internal/event/actors/actor-impl.cpp
dali/internal/event/actors/actor-impl.h
dali/internal/event/actors/camera-actor-impl.cpp
dali/internal/event/actors/camera-actor-impl.h
dali/internal/event/actors/image-actor-impl.cpp
dali/internal/event/actors/image-actor-impl.h
dali/internal/event/actors/layer-impl.cpp
dali/internal/event/actors/layer-impl.h
dali/internal/event/actors/light-actor-impl.cpp
dali/internal/event/actors/light-actor-impl.h
dali/internal/event/actors/text-actor-impl.cpp
dali/internal/event/actors/text-actor-impl.h
dali/internal/event/animation/active-constraint-base.cpp
dali/internal/event/animation/active-constraint-base.h
dali/internal/event/animation/active-constraint-impl.h
dali/internal/event/common/object-impl.h
dali/internal/event/common/property-index-ranges.h
dali/internal/event/common/proxy-object.cpp
dali/internal/event/common/proxy-object.h
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/gesture-detector-impl.cpp
dali/internal/event/events/gesture-detector-impl.h
dali/internal/event/events/pan-gesture-detector-impl.cpp
dali/internal/event/events/pan-gesture-detector-impl.h
dali/internal/event/modeling/animatable-mesh-impl.cpp
dali/internal/event/modeling/animatable-mesh-impl.h
dali/internal/event/render-tasks/render-task-impl.cpp
dali/internal/event/render-tasks/render-task-impl.h
dali/public-api/dali-core.h
dali/public-api/file.list
dali/public-api/object/base-handle.cpp
dali/public-api/object/base-object.cpp
dali/public-api/object/handle.cpp
dali/public-api/object/type-info.cpp
dali/public-api/object/type-info.h [moved from capi/dali/public-api/object/type-info.h with 71% similarity]
dali/public-api/object/type-registry.cpp
dali/public-api/object/type-registry.h [moved from capi/dali/public-api/object/type-registry.h with 74% similarity]

index 5af3f45..98a4ac1 100644 (file)
@@ -70,6 +70,7 @@ TEST_FUNCTION( UtcDaliCameraActorSetOrthographicProjection02, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliCameraActorSetOrthographicProjection03, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliCameraActorReadProjectionMatrix,        POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliCameraActorAnimatedProperties,          POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliCameraActorPropertyIndices,             POSITIVE_TC_IDX );
 
 
 namespace
@@ -846,3 +847,15 @@ static void UtcDaliCameraActorAnimatedProperties()
 
   DALI_TEST_EQUALS( actor.GetCurrentPosition(), Vector3(100.0f, 200.0f, 300.0f), TEST_LOCATION);
 }
+
+void UtcDaliCameraActorPropertyIndices()
+{
+  TestApplication application;
+  CameraActor camera = Stage::GetCurrent().GetRenderTaskList().GetTask(0u).GetCameraActor();
+
+  Actor basicActor = Actor::New();
+  Property::IndexContainer indices;
+  camera.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() > basicActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( indices.size(), camera.GetPropertyCount(), TEST_LOCATION );
+}
index 85a3d64..34b8467 100644 (file)
@@ -62,6 +62,7 @@ TEST_FUNCTION( UtcDaliHandleGetProperty,              POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliHandleDownCast,                 POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliHandleCreateProperty,           POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliHandleGetPropertyGet,           POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliHandleGetPropertyIndices,       POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -293,6 +294,11 @@ void UtcDaliHandleIsPropertyAnimatable()
   DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( Actor::WORLD_POSITION_X ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( Actor::WORLD_POSITION_Y ) );
   DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( Actor::WORLD_POSITION_Z ) );
+
+  // Type registered properties are not animatable
+  DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( PropertyRegistration::START_INDEX ) ); // START
+  DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( PropertyRegistration::START_INDEX + ( ( PropertyRegistration::MAX_INDEX - PropertyRegistration::START_INDEX ) * 0.5 ) ) ); // MIDDLE
+  DALI_TEST_CHECK( false == actor.IsPropertyAnimatable( PropertyRegistration::MAX_INDEX ) ); // MAX
 }
 
 void UtcDaliHandleGetPropertyType()
@@ -909,3 +915,15 @@ void UtcDaliHandleGetPropertyGet()
   DALI_TEST_CHECK( map[0].first == "key" );
 
 }
+
+void UtcDaliHandleGetPropertyIndices()
+{
+  TestApplication application;
+  Property::IndexContainer indices;
+
+  // Actor
+  Actor actor = Actor::New();
+  actor.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), actor.GetPropertyCount(), TEST_LOCATION );
+}
index 2c36424..dcb5f9f 100644 (file)
@@ -76,7 +76,7 @@ TEST_FUNCTION( UtcDaliImageSetFadeInDuration,         POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliImageActorNewNull,              POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliImageActorNewNullWithArea,      POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliImageActorSetImage,             POSITIVE_TC_IDX );
-
+TEST_FUNCTION( UtcDaliImageActorPropertyIndices,      POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -960,3 +960,15 @@ static void UtcDaliImageActorSetImage()
 
   DALI_TEST_CHECK(!actor.GetImage());
 }
+
+void UtcDaliImageActorPropertyIndices()
+{
+  TestApplication application;
+  Actor basicActor = Actor::New();
+  ImageActor imageActor = ImageActor::New();
+
+  Property::IndexContainer indices;
+  imageActor.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() > basicActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( indices.size(), imageActor.GetPropertyCount(), TEST_LOCATION );
+}
index a5ca854..629bec5 100644 (file)
@@ -64,6 +64,7 @@ TEST_FUNCTION( UtcDaliLayerMoveAbove, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliLayerMoveBelow, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliLayerDefaultProperties, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliLayerSetDepthTestDisabled, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLayerPropertyIndices, POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -518,3 +519,15 @@ static void UtcDaliLayerCreateDestroy()
   DALI_TEST_CHECK( layer );
   delete layer;
 }
+
+void UtcDaliLayerPropertyIndices()
+{
+  TestApplication application;
+  Actor basicActor = Actor::New();
+  Layer layer = Layer::New();
+
+  Property::IndexContainer indices;
+  layer.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() > basicActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( indices.size(), layer.GetPropertyCount(), TEST_LOCATION );
+}
index 22ada3a..0651ec1 100644 (file)
@@ -35,39 +35,29 @@ extern "C" {
   void (*tet_cleanup)() = Cleanup;
 }
 
-static void UtcDaliLightActorConstructorVoid();
-static void UtcDaliLightActorConstructorRefObject();
-static void UtcDaliLightActorDestructor();
-static void UtcDaliLightActorNew();
-static void UtcDaliLightActorDownCast();
-static void UtcDaliLightActorDownCast2();
-static void UtcDaliLightActorSetGetLight();
-static void UtcDaliLightActorSetGetActive();
-static void UtcDaliLightActorMeshTest();
-static void UtcDaliLightActorDefaultProperties();
-
 enum {
   POSITIVE_TC_IDX = 0x01,
   NEGATIVE_TC_IDX,
 };
 
-// Add test functionality for all APIs in the class (Positive and Negative)
+#define MAX_NUMBER_OF_TESTS 10000
 extern "C" {
-  struct tet_testlist tet_testlist[] = {
-    { UtcDaliLightActorConstructorVoid,           POSITIVE_TC_IDX },
-    { UtcDaliLightActorConstructorRefObject,      POSITIVE_TC_IDX },
-    { UtcDaliLightActorDestructor,                POSITIVE_TC_IDX },
-    { UtcDaliLightActorNew,                       POSITIVE_TC_IDX },
-    { UtcDaliLightActorDownCast,                  POSITIVE_TC_IDX },
-    { UtcDaliLightActorDownCast2,                 NEGATIVE_TC_IDX },
-    { UtcDaliLightActorSetGetLight,               POSITIVE_TC_IDX },
-    { UtcDaliLightActorSetGetActive,              POSITIVE_TC_IDX },
-    { UtcDaliLightActorMeshTest,                  POSITIVE_TC_IDX },
-    { UtcDaliLightActorDefaultProperties,         POSITIVE_TC_IDX },
-    { NULL, 0 }
-  };
+  struct tet_testlist tet_testlist[MAX_NUMBER_OF_TESTS];
 }
 
+// Add test functionality for all APIs in the class (Positive and Negative)
+TEST_FUNCTION( UtcDaliLightActorConstructorVoid,           POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorConstructorRefObject,      POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorDestructor,                POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorNew,                       POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorDownCast,                  POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorDownCast2,                 NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorSetGetLight,               POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorSetGetActive,              POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorMeshTest,                  POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorDefaultProperties,         POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliLightActorPropertyIndices,           POSITIVE_TC_IDX );
+
 // Called only once before first test is run.
 static void Startup()
 {
@@ -342,3 +332,15 @@ static void UtcDaliLightActorDefaultProperties()
   DALI_TEST_CHECK(v.Get<Vector3>() == col);
 
 }
+
+void UtcDaliLightActorPropertyIndices()
+{
+  TestApplication application;
+  Actor basicActor = Actor::New();
+  LightActor light = LightActor::New();
+
+  Property::IndexContainer indices;
+  light.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() > basicActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( indices.size(), light.GetPropertyCount(), TEST_LOCATION );
+}
index bad6963..481cda2 100644 (file)
@@ -79,6 +79,7 @@ TEST_FUNCTION( UtcDaliMeshActorBlend07,                   POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliMeshActorBlend08,                   POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliMeshActorBlend09,                   POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliMeshActorBoneUpdate01,              POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliMeshActorIndices,                   POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -913,3 +914,16 @@ static void UtcDaliMeshActorBoneUpdate01()
   DALI_TEST_CHECK( bugWorldMatrix != calcWorldMatrix );
 
 }
+
+void UtcDaliMeshActorIndices()
+{
+  TestApplication application;
+  Actor basicActor = Actor::New();
+  Mesh mesh = NewMesh();
+  MeshActor meshActor = MeshActor::New(mesh);
+
+  Property::IndexContainer indices;
+  meshActor.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() == basicActor.GetPropertyCount() ); // Mesh Actor does not have any properties
+  DALI_TEST_EQUALS( indices.size(), meshActor.GetPropertyCount(), TEST_LOCATION );
+}
index dd7e67a..3b6a4af 100644 (file)
@@ -102,6 +102,8 @@ TEST_FUNCTION( UtcDaliTextActorSynchronousGlyphLoading,   POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliTextActorAutomaticSizeSet,          POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliTextActorAutomaticSizeSetAnimation, POSITIVE_TC_IDX );
 
+TEST_FUNCTION( UtcDaliTextActorPropertyIndices,           POSITIVE_TC_IDX );
+
 // Called only once before first test is run.
 static void Startup()
 {
@@ -840,3 +842,15 @@ static void UtcDaliTextActorAutomaticSizeSetAnimation()
   Vector3 naturalSize = defaultFont.MeasureText( moreText );
   DALI_TEST_EQUALS( naturalSize.GetVectorXY(), actor.GetCurrentSize().GetVectorXY(), TEST_LOCATION );
 }
+
+void UtcDaliTextActorPropertyIndices()
+{
+  TestApplication application;
+  Actor basicActor = Actor::New();
+  TextActor textActor = TextActor::New("Text");
+
+  Property::IndexContainer indices;
+  textActor.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( indices.size() > basicActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( indices.size(), textActor.GetPropertyCount(), TEST_LOCATION );
+}
index da30b35..ef32a48 100644 (file)
@@ -57,6 +57,7 @@ TEST_FUNCTION( UtcDaliConstraintGetCurrentWeight,           POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliConstraintSignalApplied,              POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliConstraintRemove,                     POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliConstraintCallback,                   POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliConstraintProperties,                 POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -331,3 +332,77 @@ static void UtcDaliConstraintCallback()
 
   DALI_TEST_CHECK( constraintSignalled );
 }
+
+void UtcDaliConstraintProperties()
+{
+  TestApplication application;
+
+  Constraint constraint = Constraint::New<Vector3>( Actor::SIZE, TestConstraintVector3() );
+  Actor actor = Actor::New();
+  ActiveConstraint active = actor.ApplyConstraint( constraint );
+
+  Property::IndexContainer indices;
+  active.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), active.GetPropertyCount(), TEST_LOCATION );
+
+  // Valid property
+  DALI_TEST_EQUALS( active.GetPropertyName( 0 ), "weight", TEST_LOCATION );
+  DALI_TEST_EQUALS( active.GetPropertyIndex( "weight" ), 0, TEST_LOCATION );
+  DALI_TEST_CHECK( active.IsPropertyWritable( 0 ) );
+  DALI_TEST_CHECK( active.IsPropertyAnimatable( 0 ) );
+  DALI_TEST_EQUALS( active.GetPropertyType( 0 ), Property::FLOAT, TEST_LOCATION );
+  DALI_TEST_CHECK( active.GetCurrentWeight() != 21312.0f );
+  active.SetProperty( 0, 21312.0f );
+  DALI_TEST_EQUALS( active.GetCurrentWeight(), 21312.0f, TEST_LOCATION );
+  DALI_TEST_EQUALS( active.GetProperty< float >( 0 ), 21312.0f, TEST_LOCATION );
+
+  // Invalid Property
+  try
+  {
+    active.GetPropertyName( PropertyRegistration::START_INDEX );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Property index is invalid", TEST_LOCATION );
+  }
+  DALI_TEST_EQUALS( active.GetPropertyIndex( "invalid-property-name"), Property::INVALID_INDEX, TEST_LOCATION );
+  try
+  {
+    active.IsPropertyWritable( PropertyRegistration::START_INDEX );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
+  DALI_TEST_CHECK( ! active.IsPropertyAnimatable( PropertyRegistration::START_INDEX ) );
+  try
+  {
+    active.GetPropertyType( PropertyRegistration::START_INDEX );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
+  try
+  {
+    active.SetProperty( PropertyRegistration::START_INDEX, true );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
+  try
+  {
+    active.GetProperty< bool >( PropertyRegistration::START_INDEX );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Cannot find property index", TEST_LOCATION );
+  }
+}
index 0f2dced..1d6027e 100644 (file)
@@ -85,6 +85,7 @@ TEST_FUNCTION( UtcDaliConstraintInputWorldPosition,            POSITIVE_TC_IDX )
 TEST_FUNCTION( UtcDaliConstraintInputWorldRotation,            POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliConstraintInputWorldScale,               POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliConstraintInputWorldColor,               POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliConstraintInvalidInputProperty,          POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliBuiltinConstraintParentSize,             POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliBuiltinConstraintParentSizeRelative,     POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliBuiltinConstraintScaleToFitConstraint,   POSITIVE_TC_IDX );
@@ -97,7 +98,7 @@ TEST_FUNCTION( UtcDaliBuiltinConstraintDivideConstraint,       POSITIVE_TC_IDX )
 TEST_FUNCTION( UtcDaliBuiltinConstraintEqualToConstraint,      POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliBuiltinConstraintRelativeToConstraint,   POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliBuiltinConstraintInverseOfConstraint,    POSITIVE_TC_IDX );
-TEST_FUNCTION( UtcDaliBuiltinConstraintFunctions, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliBuiltinConstraintFunctions,              POSITIVE_TC_IDX );
 
 struct EqualToQuaternion
 {
@@ -3256,6 +3257,26 @@ static void UtcDaliConstraintInputWorldColor()
   DALI_TEST_EQUALS( child.GetCurrentWorldColor(), previousColor, TEST_LOCATION );
 }
 
+void UtcDaliConstraintInvalidInputProperty()
+{
+  TestApplication application;
+  Actor actor = Actor::New();
+  Constraint constraint = Constraint::New<Vector3>( Actor::POSITION, LocalSource( PropertyRegistration::START_INDEX ), MultiplyConstraint() );
+
+  Stage::GetCurrent().Add( actor );
+
+  // Cannot use type registered properties as input to constraints
+  try
+  {
+    actor.ApplyConstraint( constraint );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT( e, "( source.propertyIndex < DEFAULT_PROPERTY_MAX_COUNT ) || ( source.propertyIndex >= CUSTOM_PROPERTY_START )", TEST_LOCATION );
+  }
+}
+
 static void UtcDaliBuiltinConstraintParentSize()
 {
   TestApplication application;
index c189109..792ee48 100644 (file)
@@ -103,6 +103,8 @@ TEST_FUNCTION( UtcDaliShaderEffectFromProperties01, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliShaderEffectFromProperties02, NEGATIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliShaderEffectFromProperties03, NEGATIVE_TC_IDX );
 
+TEST_FUNCTION( UtcDaliShaderEffectPropertyIndices, POSITIVE_TC_IDX );
+
 // Called only once before first test is run.
 static void Startup()
 {
@@ -1174,3 +1176,14 @@ static void UtcDaliShaderEffectFromProperties03()
     tet_printf("Assertion %s failed at %s\n", e.mCondition.c_str(), e.mLocation.c_str());
   }
 }
+
+void UtcDaliShaderEffectPropertyIndices()
+{
+  TestApplication application;
+  ShaderEffect effect = ShaderEffect::New( VertexSource, FragmentSource );
+
+  Property::IndexContainer indices;
+  effect.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), effect.GetPropertyCount(), TEST_LOCATION );
+}
index 7b23f40..e505319 100644 (file)
@@ -82,6 +82,7 @@ TEST_FUNCTION( UtcDaliPanGestureDirectionHandling, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliPanGestureDirectionProcessing, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliPanGestureSetProperties, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliPanGestureSetPropertiesAlreadyPanning, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPanGesturePropertyIndices, POSITIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -2065,3 +2066,14 @@ void UtcDaliPanGestureSetPropertiesAlreadyPanning()
   DALI_TEST_EQUALS( constraintData.localPosition,  currentPosition, 0.1f, TEST_LOCATION );
   constraintData.Reset();
 }
+
+void UtcDaliPanGesturePropertyIndices()
+{
+  TestApplication application;
+  PanGestureDetector detector = PanGestureDetector::New();
+
+  Property::IndexContainer indices;
+  detector.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), detector.GetPropertyCount(), TEST_LOCATION );
+}
index acb9d28..968eb4d 100644 (file)
@@ -63,6 +63,8 @@ TEST_FUNCTION( UtcDaliAnimatableMeshOperatorArray01, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliAnimatableMeshOperatorArray02, NEGATIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliAnimatableMeshAnimateVertex01, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliAnimatableVertexSettersAndGetters, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliAnimatableMeshProperties, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliAnimatableMeshExceedVertices, NEGATIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -444,3 +446,32 @@ static void UtcDaliAnimatableVertexSettersAndGetters()
   DALI_TEST_EQUALS(mesh[2].GetCurrentColor(), Color::BLACK, TEST_LOCATION);
   DALI_TEST_EQUALS(mesh[3].GetCurrentTextureCoords(), uvs, TEST_LOCATION);
 }
+
+void UtcDaliAnimatableMeshProperties()
+{
+  TestApplication application;
+  AnimatableMesh mesh = CreateMesh();
+
+  Property::IndexContainer indices;
+  mesh.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), mesh.GetPropertyCount(), TEST_LOCATION );
+}
+
+void UtcDaliAnimatableMeshExceedVertices()
+{
+  TestApplication application;
+
+  AnimatableMesh::Faces faces;
+  CreateFaces(faces, 10);
+
+  try
+  {
+    AnimatableMesh mesh = AnimatableMesh::New(3333334, faces);
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "( numVertices * 3 ) < DEFAULT_PROPERTY_MAX_COUNT", TEST_LOCATION );
+  }
+}
index f5096aa..c1ffd40 100644 (file)
@@ -48,57 +48,38 @@ extern "C" {
   void (*tet_cleanup)() = Cleanup;
 }
 
-static void UtcDaliPropertyNotificationDownCast();
-static void UtcDaliPropertyNotificationDownCastNegative();
-static void UtcDaliAddPropertyNotification();
-static void UtcDaliAddPropertyNotificationCallback();
-static void UtcDaliPropertyNotificationGetCondition();
-static void UtcDaliPropertyNotificationGetConditionConst();
-static void UtcDaliPropertyNotificationGetTarget();
-static void UtcDaliPropertyNotificationGetProperty();
-static void UtcDaliPropertyNotificationGetNotifyMode();
-static void UtcDaliPropertyNotificationGreaterThan();
-static void UtcDaliPropertyNotificationLessThan();
-static void UtcDaliPropertyNotificationInside();
-static void UtcDaliPropertyNotificationOutside();
-static void UtcDaliPropertyNotificationVectorComponentGreaterThan();
-static void UtcDaliPropertyNotificationVectorComponentLessThan();
-static void UtcDaliPropertyNotificationVectorComponentInside();
-static void UtcDaliPropertyNotificationVectorComponentOutside();
-static void UtcDaliPropertyConditionGetArguments();
-static void UtcDaliPropertyConditionGetArgumentsConst();
-
 enum {
   POSITIVE_TC_IDX = 0x01,
   NEGATIVE_TC_IDX,
 };
 
-// Add test functionality for all APIs in the class (Positive and Negative)
+#define MAX_NUMBER_OF_TESTS 10000
 extern "C" {
-  struct tet_testlist tet_testlist[] = {
-    { UtcDaliPropertyNotificationDownCast, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationDownCastNegative, POSITIVE_TC_IDX },
-    { UtcDaliAddPropertyNotification, POSITIVE_TC_IDX },
-    { UtcDaliAddPropertyNotificationCallback, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGetCondition, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGetConditionConst, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGetTarget, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGetProperty, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGetNotifyMode, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationGreaterThan, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationLessThan, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationInside, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationOutside, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationVectorComponentGreaterThan, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationVectorComponentLessThan, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationVectorComponentInside, POSITIVE_TC_IDX },
-    { UtcDaliPropertyNotificationVectorComponentOutside, POSITIVE_TC_IDX },
-    { UtcDaliPropertyConditionGetArguments, POSITIVE_TC_IDX },
-    { UtcDaliPropertyConditionGetArgumentsConst, POSITIVE_TC_IDX },
-    { NULL, 0 }
-  };
+  struct tet_testlist tet_testlist[MAX_NUMBER_OF_TESTS];
 }
 
+// Add test functionality for all APIs in the class (Positive and Negative)
+TEST_FUNCTION( UtcDaliPropertyNotificationDownCast, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationDownCastNegative, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliAddPropertyNotification, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliAddPropertyNotificationCallback, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliAddPropertyNotificationTypeProperty, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGetCondition, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGetConditionConst, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGetTarget, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGetProperty, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGetNotifyMode, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationGreaterThan, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationLessThan, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationInside, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationOutside, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationVectorComponentGreaterThan, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationVectorComponentLessThan, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationVectorComponentInside, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyNotificationVectorComponentOutside, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyConditionGetArguments, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyConditionGetArgumentsConst, POSITIVE_TC_IDX );
+
 class TestClass : public ConnectionTracker
 {
 public:
@@ -302,6 +283,23 @@ static void UtcDaliAddPropertyNotificationCallback()
   delete object;
 }
 
+void UtcDaliAddPropertyNotificationTypeProperty()
+{
+  TestApplication application;
+
+  Actor actor = Actor::New();
+
+  // Currently, Type registry properties cannot be animated
+  try
+  {
+    actor.AddPropertyNotification( PropertyRegistration::START_INDEX, GreaterThanCondition( 100.0f ) );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "false && \"Property notification added to non animatable property", TEST_LOCATION );
+  }
+}
+
 static void UtcDaliPropertyNotificationGetCondition()
 {
   TestApplication application;
index fb99a4f..0b8c8b6 100644 (file)
@@ -96,6 +96,7 @@ TEST_FUNCTION( UtcDaliRenderTaskOnceNoSync06,                       POSITIVE_TC_
 TEST_FUNCTION( UtcDaliRenderTaskOnceNoSync07,                       POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliRenderTaskOnceNoSync08,                       POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliRenderTaskOnceChain01,                        POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliRenderTaskProperties,                         POSITIVE_TC_IDX );
 
 // TODO - work out how to reload images in test harness
 
@@ -2756,3 +2757,15 @@ static void UtcDaliRenderTaskOnceChain01()
   DALI_TEST_CHECK( secondFinished == false );
 
 }
+
+void UtcDaliRenderTaskProperties()
+{
+  TestApplication application;
+
+  RenderTask task = Stage::GetCurrent().GetRenderTaskList().CreateTask();
+
+  Property::IndexContainer indices;
+  task.GetPropertyIndices( indices );
+  DALI_TEST_CHECK( ! indices.empty() );
+  DALI_TEST_EQUALS( indices.size(), task.GetPropertyCount(), TEST_LOCATION );
+}
index 8c7b6b9..87553cb 100644 (file)
@@ -51,6 +51,13 @@ TEST_FUNCTION( UtcDaliTypeRegistryCustomActor, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliTypeRegistryCustomSignalFailure, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliTypeRegistryInitFunctions, POSITIVE_TC_IDX );
 TEST_FUNCTION( UtcDaliTypeRegistryNameInitFunctions, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistration, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationIndexOutOfBounds, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationFunctions, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationAddSameIndex, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationPropertyWritable, POSITIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationPropertyAnimatable, NEGATIVE_TC_IDX );
+TEST_FUNCTION( UtcDaliPropertyRegistrationInvalidGetAndSet, NEGATIVE_TC_IDX );
 
 // Called only once before first test is run.
 static void Startup()
@@ -621,3 +628,232 @@ static void UtcDaliTypeRegistryNameInitFunctions()
   TypeInfo type = TypeRegistry::Get().GetTypeInfo( scriptedName );
   DALI_TEST_CHECK( type );
 }
+
+// Property Registration
+bool setPropertyCalled = false;
+bool getPropertyCalled = false;
+void SetProperty( BaseObject* object, Property::Index propertyIndex, const Property::Value& value )
+{
+  setPropertyCalled = true;
+}
+Property::Value GetProperty( BaseObject* object, Property::Index propertyIndex )
+{
+  getPropertyCalled = true;
+  return Property::Value( true );
+}
+
+void UtcDaliPropertyRegistration()
+{
+  TestApplication application;
+  TypeRegistry typeRegistry = TypeRegistry::Get();
+
+  // Check property count before property registration
+  TypeInfo typeInfo = typeRegistry.GetTypeInfo( typeid(MyTestCustomActor) );
+  DALI_TEST_CHECK( typeInfo );
+  BaseHandle handle = typeInfo.CreateInstance();
+  DALI_TEST_CHECK( handle );
+  Actor customActor = Actor::DownCast( handle );
+  DALI_TEST_CHECK( customActor );
+  unsigned int initialPropertyCount( customActor.GetPropertyCount() );
+
+  std::string propertyName( "prop-1" );
+  int propertyIndex( PropertyRegistration::START_INDEX );
+  Property::Type propertyType( Property::BOOLEAN );
+  PropertyRegistration property1( customType1, propertyName, propertyIndex, propertyType, &SetProperty, &GetProperty );
+
+  // Check property count after registration
+  unsigned int postRegistrationPropertyCount( customActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( initialPropertyCount + 1u, postRegistrationPropertyCount, TEST_LOCATION );
+
+  // Add custom property and check property count
+  customActor.RegisterProperty( "custom-prop-1", true );
+  unsigned int customPropertyCount( customActor.GetPropertyCount() );
+  DALI_TEST_EQUALS( postRegistrationPropertyCount + 1u, customPropertyCount, TEST_LOCATION );
+
+  // Set the property, ensure SetProperty called
+  DALI_TEST_CHECK( !setPropertyCalled );
+  customActor.SetProperty( propertyIndex, false );
+  DALI_TEST_CHECK( setPropertyCalled );
+
+  // Get the property, ensure GetProperty called
+  DALI_TEST_CHECK( !getPropertyCalled );
+  (void)customActor.GetProperty< bool >( propertyIndex );
+  DALI_TEST_CHECK( getPropertyCalled );
+
+  // Check the property name
+  DALI_TEST_EQUALS( customActor.GetPropertyName( propertyIndex ), propertyName, TEST_LOCATION );
+  DALI_TEST_EQUALS( typeInfo.GetPropertyName( propertyIndex ), propertyName, TEST_LOCATION );
+
+  // Check the property index
+  DALI_TEST_EQUALS( customActor.GetPropertyIndex( propertyName ), propertyIndex, TEST_LOCATION );
+
+  // Check the property type
+  DALI_TEST_EQUALS( customActor.GetPropertyType( propertyIndex ), propertyType, TEST_LOCATION );
+
+  // Check property count of type-info is 1
+  Property::IndexContainer indices;
+  typeInfo.GetPropertyIndices( indices );
+  DALI_TEST_EQUALS( indices.size(), 1u, TEST_LOCATION );
+
+  // Ensure indices returned from actor and customActor differ by two
+  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
+}
+
+void UtcDaliPropertyRegistrationIndexOutOfBounds()
+{
+  TestApplication application;
+  TypeRegistry typeRegistry = TypeRegistry::Get();
+
+  // Attempt to register a property type out-of-bounds index (less than)
+  try
+  {
+    PropertyRegistration property1( customType1, "prop-name", PropertyRegistration::START_INDEX - 1, Property::BOOLEAN, &SetProperty, &GetProperty );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "( index >= START_INDEX ) && ( index <= MAX_INDEX )", TEST_LOCATION );
+  }
+
+  // Attempt to register a property type out-of-bounds index (greater than)
+  try
+  {
+    PropertyRegistration property1( customType1, "prop-name", PropertyRegistration::MAX_INDEX + 1, Property::BOOLEAN, &SetProperty, &GetProperty );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "( index >= START_INDEX ) && ( index <= MAX_INDEX )", TEST_LOCATION );
+  }
+}
+
+void UtcDaliPropertyRegistrationFunctions()
+{
+  TestApplication application;
+  int propertyIndex = PropertyRegistration::START_INDEX + 10;
+
+  // Attempt to register a property without a setter
+  try
+  {
+    PropertyRegistration property1( customType1, "prop-name", propertyIndex++, Property::BOOLEAN, NULL, &GetProperty );
+    tet_result( TET_PASS );
+  }
+  catch ( DaliException& e )
+  {
+    tet_result( TET_FAIL );
+  }
+
+  // Attempt to register a property without a getter
+  try
+  {
+    PropertyRegistration property1( customType1, "prop-name", propertyIndex++, Property::BOOLEAN, NULL, NULL );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"GetProperty", TEST_LOCATION );
+  }
+}
+
+void UtcDaliPropertyRegistrationAddSameIndex()
+{
+  TestApplication application;
+  int propertyIndex = PropertyRegistration::START_INDEX + 100;
+
+  // Add one property with a valid property index
+  PropertyRegistration property1( customType1, "prop-name", propertyIndex, Property::BOOLEAN, &SetProperty, &GetProperty );
+
+  // Attempt to add another property with the same index
+  try
+  {
+    PropertyRegistration property2( customType1, "prop-name-2", propertyIndex, Property::BOOLEAN, &SetProperty, &GetProperty );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "! \"Property index already added", TEST_LOCATION );
+  }
+}
+
+void UtcDaliPropertyRegistrationPropertyWritable()
+{
+  TestApplication application;
+  int propertyIndex1 = PropertyRegistration::START_INDEX + 200;
+  int propertyIndex2 = PropertyRegistration::START_INDEX + 201;
+
+  // Add two properties, one with SetProperty, one without
+  PropertyRegistration property1( customType1, "prop-name-readwrite", propertyIndex1, Property::BOOLEAN, &SetProperty, &GetProperty );
+  PropertyRegistration property2( customType1, "prop-name-readonly",  propertyIndex2, Property::BOOLEAN, NULL, &GetProperty );
+
+  // Create custom-actor
+  TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(MyTestCustomActor) );
+  DALI_TEST_CHECK( typeInfo );
+  BaseHandle handle = typeInfo.CreateInstance();
+  DALI_TEST_CHECK( handle );
+  Actor customActor = Actor::DownCast( handle );
+  DALI_TEST_CHECK( customActor );
+
+  // Check whether properties are writable
+  DALI_TEST_CHECK(   customActor.IsPropertyWritable( propertyIndex1 ) );
+  DALI_TEST_CHECK( ! customActor.IsPropertyWritable( propertyIndex2 ) );
+}
+
+void UtcDaliPropertyRegistrationPropertyAnimatable()
+{
+  TestApplication application;
+  int propertyIndex = PropertyRegistration::START_INDEX + 400;
+
+  // These properties are not animatable
+  PropertyRegistration property1( customType1, "prop-name", propertyIndex, Property::BOOLEAN, &SetProperty, &GetProperty );
+
+  // Create custom-actor
+  TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(MyTestCustomActor) );
+  DALI_TEST_CHECK( typeInfo );
+  BaseHandle handle = typeInfo.CreateInstance();
+  DALI_TEST_CHECK( handle );
+  Actor customActor = Actor::DownCast( handle );
+  DALI_TEST_CHECK( customActor );
+
+  // Check if animatable
+  DALI_TEST_CHECK( ! customActor.IsPropertyAnimatable( propertyIndex ) );
+}
+
+void UtcDaliPropertyRegistrationInvalidGetAndSet()
+{
+  TestApplication application;
+  int propertyIndex = PropertyRegistration::START_INDEX + 2000;
+
+  // Create custom-actor
+  TypeInfo typeInfo = TypeRegistry::Get().GetTypeInfo( typeid(MyTestCustomActor) );
+  DALI_TEST_CHECK( typeInfo );
+  BaseHandle handle = typeInfo.CreateInstance();
+  DALI_TEST_CHECK( handle );
+  Actor customActor = Actor::DownCast( handle );
+  DALI_TEST_CHECK( customActor );
+
+  // Try to set an index that hasn't been added
+  try
+  {
+    customActor.SetProperty( propertyIndex, true );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "false && \"Property index not found", TEST_LOCATION );
+  }
+
+  // Try to get an index that hasn't been added
+  try
+  {
+    (void) customActor.GetProperty< bool >( propertyIndex );
+    tet_result( TET_FAIL );
+  }
+  catch ( DaliException& e )
+  {
+    DALI_TEST_ASSERT_CONDITION_STARTS_WITH_SUBSTRING( e, "false && \"Property index not found", TEST_LOCATION );
+  }
+}
index 89409e2..a850b3c 100644 (file)
 #include <dali/public-api/object/property-value.h>
 #include <dali/public-api/object/property.h>
 #include <dali/public-api/object/ref-object.h>
-#include <dali/public-api/object/type-info.h>
-#include <dali/public-api/object/type-registry.h>
 
 #include <dali/public-api/render-tasks/render-task-list.h>
 #include <dali/public-api/render-tasks/render-task.h>
index cf7180f..0d99c9c 100644 (file)
@@ -96,9 +96,7 @@ capi_devel_object_header_files =  \
   $(capi_devel_src_dir)/object/property-types.h \
   $(capi_devel_src_dir)/object/property-value.h \
   $(capi_devel_src_dir)/object/property.h \
-  $(capi_devel_src_dir)/object/ref-object.h \
-  $(capi_devel_src_dir)/object/type-info.h \
-  $(capi_devel_src_dir)/object/type-registry.h
+  $(capi_devel_src_dir)/object/ref-object.h
 
 capi_devel_render_tasks_header_files = \
   $(capi_devel_src_dir)/render-tasks/render-task.h \
index ddae3ac..4d000cc 100644 (file)
@@ -65,6 +65,7 @@ public:
    * @param[in] numVertices The number of vertices in the mesh
    * @param[in] faceIndices A set of vertex indices, 3 per face.
    * @return an initialized handle to the animatable mesh
+   * @note The maximum number of supported vertices is 3333333.
    */
   static AnimatableMesh New( unsigned int numVertices,
                              const Faces& faceIndices );
@@ -78,6 +79,7 @@ public:
    * @param[in] faceIndices A set of vertex indices, 3 per face.
    * @param[in] material Material used to render mesh
    * @return an initialized handle to the animatable mesh
+   * @note The maximum number of supported vertices is 3333333.
    */
   static AnimatableMesh New( unsigned int numVertices,
                              const Faces& faceIndices,
index 23f9e50..4d17b9a 100644 (file)
@@ -137,7 +137,7 @@ public:
    * Returns the type name for the Handle.
    * @return The type name.
    */
-  std::string GetTypeName();
+  const std::string& GetTypeName() const;
 
 public:
 
index 5aff446..95d1a03 100644 (file)
@@ -62,7 +62,7 @@ public:
   /**
    * @copydoc Dali::BaseHandle::GetTypeName
    */
-  std::string GetTypeName();
+  const std::string& GetTypeName() const;
 
 public: // Not intended for application developers
 
index 8945ce5..b7e11da 100644 (file)
@@ -224,6 +224,13 @@ public:
   }
 
   /**
+   * Retrieve all the property indices for this object (including custom properties).
+   * @param[out] indices A container of property indices for this object.
+   * @note the added container is cleared
+   */
+  void GetPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * Add a property notification to this object.
    * @pre Property::INVALID_INDEX < index < GetPropertyCount().
    * @param [in] index The index of the property.
index 63fdcaa..a91d20c 100644 (file)
@@ -47,6 +47,8 @@ struct Property
 
   static const int INVALID_INDEX; ///< -1 is not a valid property index
 
+  typedef std::vector< Index > IndexContainer; ///< A vector of property indices
+
   /**
    * A value-type representing a property value.
    */
index bd6cc3f..a421069 100644 (file)
@@ -2323,9 +2323,19 @@ unsigned int Actor::GetDefaultPropertyCount() const
   return DEFAULT_PROPERTY_COUNT;
 }
 
+void Actor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( DEFAULT_PROPERTY_COUNT );
+
+  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
+  {
+    indices.push_back( i );
+  }
+}
+
 const std::string& Actor::GetDefaultPropertyName( Property::Index index ) const
 {
-  if( static_cast< unsigned int >( index ) < GetDefaultPropertyCount() )
+  if( index < DEFAULT_PROPERTY_COUNT )
   {
     return DEFAULT_PROPERTY_NAMES[index];
   }
@@ -2388,7 +2398,7 @@ bool Actor::IsDefaultPropertyAnimatable(Property::Index index) const
 
 Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
 {
-  if( static_cast< unsigned int >( index ) < GetDefaultPropertyCount() )
+  if( index < DEFAULT_PROPERTY_COUNT )
   {
     return DEFAULT_PROPERTY_TYPES[index];
   }
@@ -2401,7 +2411,6 @@ Property::Type Actor::GetDefaultPropertyType(Property::Index index) const
 
 void Actor::SetDefaultProperty( Property::Index index, const Property::Value& property )
 {
-  // ProxyObject guarantees the property is writable and index is in range
   switch ( index )
   {
     case Dali::Actor::PARENT_ORIGIN:
@@ -2582,8 +2591,7 @@ void Actor::SetDefaultProperty( Property::Index index, const Property::Value& pr
 
 void Actor::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
 {
-  // ProxyObject guarantees the index is in range
-
+  // TODO: This should be deprecated
   OnPropertySet(index, value);
 
   if(entry.IsAnimatable())
@@ -2671,7 +2679,6 @@ Property::Value Actor::GetDefaultProperty(Property::Index index) const
 {
   Property::Value value;
 
-  // ProxyObject guarantees that index is within range
   switch ( index )
   {
     case Dali::Actor::PARENT_ORIGIN:
@@ -3033,7 +3040,7 @@ const PropertyInputImpl* Actor::GetSceneObjectInputProperty( Property::Index ind
     return property;
   }
 
-  if ( static_cast<unsigned int>(index) >= DEFAULT_PROPERTY_MAX_COUNT )
+  if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
   {
     CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
 
index 2b5557a..e503303 100644 (file)
@@ -1094,6 +1094,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index 54ab61b..1936388 100644 (file)
@@ -419,9 +419,22 @@ unsigned int CameraActor::GetDefaultPropertyCount() const
   return Actor::GetDefaultPropertyCount() + DEFAULT_CAMERA_ACTOR_PROPERTY_COUNT;
 }
 
+void CameraActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
+
+  indices.reserve( indices.size() + DEFAULT_CAMERA_ACTOR_PROPERTY_COUNT );
+
+  int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_CAMERA_ACTOR_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 bool CameraActor::IsDefaultPropertyWritable( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     return Actor::IsDefaultPropertyWritable(index);
   }
@@ -442,7 +455,7 @@ bool CameraActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 {
   bool animatable = false; // Our properties are not animatable.
 
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
   {
     animatable = Actor::IsDefaultPropertyAnimatable(index);
   }
@@ -451,27 +464,46 @@ bool CameraActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 
 Property::Type CameraActor::GetDefaultPropertyType( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     return Actor::GetDefaultPropertyType(index);
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_CAMERA_ACTOR_PROPERTY_TYPES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_CAMERA_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_CAMERA_ACTOR_PROPERTY_TYPES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      return Property::NONE;
+    }
   }
 }
 
 const std::string& CameraActor::GetDefaultPropertyName( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     return Actor::GetDefaultPropertyName(index);
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_CAMERA_ACTOR_PROPERTY_NAMES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_CAMERA_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_CAMERA_ACTOR_PROPERTY_NAMES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      static const std::string INVALID_PROPERTY_NAME;
+      return INVALID_PROPERTY_NAME;
+    }
   }
 }
 
@@ -498,9 +530,7 @@ Property::Index CameraActor::GetDefaultPropertyIndex(const std::string& name) co
 
 void CameraActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
-
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     Actor::SetDefaultProperty(index, propertyValue);
   }
@@ -616,7 +646,7 @@ void CameraActor::SetDefaultProperty( Property::Index index, const Property::Val
 Property::Value CameraActor::GetDefaultProperty( Property::Index index ) const
 {
   Property::Value ret;
-  if(static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     ret = Actor::GetDefaultProperty(index);
   }
@@ -746,7 +776,7 @@ const SceneGraph::PropertyBase* CameraActor::GetSceneObjectAnimatableProperty( P
   }
 
   // let actor handle animatable properties, we have no animatable properties
-  if( static_cast<unsigned int>(index) < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
+  if( index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT )
   {
     property = Actor::GetSceneObjectAnimatableProperty(index);
   }
index 2213930..449c4ef 100644 (file)
@@ -187,6 +187,11 @@ public: // properties
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * copydoc Dali::Internal::ProxyObject
    */
   virtual bool IsDefaultPropertyAnimatable( Property::Index index ) const;
index 7e9080d..3843c7e 100644 (file)
 namespace Dali
 {
 
-const Property::Index ImageActor::PIXEL_AREA           = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT;
-const Property::Index ImageActor::FADE_IN              = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 1;
-const Property::Index ImageActor::FADE_IN_DURATION     = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 2;
-const Property::Index ImageActor::STYLE                = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 3;
-const Property::Index ImageActor::BORDER               = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 4;
-const Property::Index ImageActor::IMAGE                = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 5;
+const Property::Index ImageActor::PIXEL_AREA           = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+const Property::Index ImageActor::FADE_IN              = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 1;
+const Property::Index ImageActor::FADE_IN_DURATION     = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 2;
+const Property::Index ImageActor::STYLE                = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 3;
+const Property::Index ImageActor::BORDER               = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 4;
+const Property::Index ImageActor::IMAGE                = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 5;
 
 namespace Internal
 {
@@ -130,7 +130,7 @@ void ImageActor::OnInitialize()
   if(ImageActor::mFirstInstance)
   {
     mDefaultImageActorPropertyLookup = new DefaultPropertyLookup();
-    const int start = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT;
+    const int start = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
     for ( int i = 0; i < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT; ++i )
     {
       (*mDefaultImageActorPropertyLookup)[DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[i]] = i + start;
@@ -427,9 +427,22 @@ unsigned int ImageActor::GetDefaultPropertyCount() const
   return RenderableActor::GetDefaultPropertyCount() + DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT;
 }
 
+void ImageActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
+
+  indices.reserve( indices.size() + DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT );
+
+  int index = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::IsDefaultPropertyWritable(index);
   }
@@ -441,7 +454,7 @@ bool ImageActor::IsDefaultPropertyWritable( Property::Index index ) const
 
 bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::IsDefaultPropertyAnimatable(index);
   }
@@ -453,27 +466,46 @@ bool ImageActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 
 Property::Type ImageActor::GetDefaultPropertyType( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::GetDefaultPropertyType(index);
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_IMAGE_ACTOR_PROPERTY_TYPES[index - RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_IMAGE_ACTOR_PROPERTY_TYPES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      return Property::NONE;
+    }
   }
 }
 
 const std::string& ImageActor::GetDefaultPropertyName( Property::Index index ) const
 {
-  if(static_cast<unsigned int>(index) < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::GetDefaultPropertyName(index);
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[index - RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_IMAGE_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_IMAGE_ACTOR_PROPERTY_NAMES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      static const std::string INVALID_PROPERTY_NAME;
+      return INVALID_PROPERTY_NAME;
+    }
   }
 }
 
@@ -500,9 +532,7 @@ Property::Index ImageActor::GetDefaultPropertyIndex(const std::string& name) con
 
 void ImageActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
-
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     RenderableActor::SetDefaultProperty(index, propertyValue);
   }
@@ -561,7 +591,7 @@ void ImageActor::SetDefaultProperty( Property::Index index, const Property::Valu
 Property::Value ImageActor::GetDefaultProperty( Property::Index index ) const
 {
   Property::Value ret;
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     ret = RenderableActor::GetDefaultProperty(index);
   }
index 80b90af..b37d88f 100644 (file)
@@ -187,6 +187,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index 5cc9dc8..52e10e4 100644 (file)
@@ -316,6 +316,18 @@ unsigned int Layer::GetDefaultPropertyCount() const
   return Actor::GetDefaultPropertyCount() + DEFAULT_LAYER_PROPERTY_COUNT;
 }
 
+void Layer::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
+  indices.reserve( indices.size() + DEFAULT_LAYER_PROPERTY_COUNT );
+
+  int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_LAYER_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 bool Layer::IsDefaultPropertyWritable( Property::Index index ) const
 {
   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
@@ -348,8 +360,17 @@ Property::Type Layer::GetDefaultPropertyType( Property::Index index ) const
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_LAYER_PROPERTY_TYPES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_LAYER_PROPERTY_TYPES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      return Property::NONE;
+    }
   }
 }
 
@@ -362,8 +383,18 @@ const std::string& Layer::GetDefaultPropertyName( Property::Index index ) const
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_LAYER_PROPERTY_NAMES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_LAYER_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_LAYER_PROPERTY_NAMES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      static const std::string INVALID_PROPERTY_NAME;
+      return INVALID_PROPERTY_NAME;
+    }
   }
 }
 
@@ -390,8 +421,6 @@ Property::Index Layer::GetDefaultPropertyIndex(const std::string& name) const
 
 void Layer::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
-
   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     Actor::SetDefaultProperty(index, propertyValue);
index c8c9bdf..e2b7baa 100644 (file)
@@ -169,6 +169,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index 396c932..7a549f9 100644 (file)
@@ -206,6 +206,19 @@ unsigned int LightActor::GetDefaultPropertyCount() const
   return Actor::GetDefaultPropertyCount() + DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT;
 }
 
+void LightActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  Actor::GetDefaultPropertyIndices( indices ); // Actor class properties
+
+  indices.reserve( indices.size() + DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT );
+
+  int index = DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 bool LightActor::IsDefaultPropertyWritable( Property::Index index ) const
 {
   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
@@ -238,8 +251,17 @@ Property::Type LightActor::GetDefaultPropertyType( Property::Index index ) const
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_LIGHT_ACTOR_PROPERTY_TYPES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_LIGHT_ACTOR_PROPERTY_TYPES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      return Property::NONE;
+    }
   }
 }
 
@@ -251,8 +273,18 @@ const std::string& LightActor::GetDefaultPropertyName( Property::Index index ) c
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_LIGHT_ACTOR_PROPERTY_NAMES[index - DEFAULT_ACTOR_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_LIGHT_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_LIGHT_ACTOR_PROPERTY_NAMES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      static const std::string INVALID_PROPERTY_NAME;
+      return INVALID_PROPERTY_NAME;
+    }
   }
 }
 
@@ -279,8 +311,6 @@ Property::Index LightActor::GetDefaultPropertyIndex(const std::string& name) con
 
 void LightActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
-
   if(index < DEFAULT_ACTOR_PROPERTY_MAX_COUNT)
   {
     Actor::SetDefaultProperty(index, propertyValue) ;
index 232c0eb..fa3e14e 100644 (file)
@@ -74,6 +74,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index f1ce664..465f3c3 100644 (file)
 namespace Dali
 {
 
-const Property::Index TextActor::TEXT                       = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT;
-const Property::Index TextActor::FONT                       = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 1;
-const Property::Index TextActor::FONT_STYLE                 = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 2;
-const Property::Index TextActor::OUTLINE_ENABLE             = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 3;
-const Property::Index TextActor::OUTLINE_COLOR              = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 4;
-const Property::Index TextActor::OUTLINE_THICKNESS_WIDTH    = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 5;
-const Property::Index TextActor::SMOOTH_EDGE                = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 6;
-const Property::Index TextActor::GLOW_ENABLE                = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 7;
-const Property::Index TextActor::GLOW_COLOR                 = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 8;
-const Property::Index TextActor::GLOW_INTENSITY             = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 9;
-const Property::Index TextActor::SHADOW_ENABLE              = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 10;
-const Property::Index TextActor::SHADOW_COLOR               = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 11;
-const Property::Index TextActor::SHADOW_OFFSET              = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 12;
-const Property::Index TextActor::ITALICS_ANGLE              = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 13;
-const Property::Index TextActor::UNDERLINE                  = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 14;
-const Property::Index TextActor::WEIGHT                     = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 15;
-const Property::Index TextActor::FONT_DETECTION_AUTOMATIC   = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 16;
-const Property::Index TextActor::GRADIENT_COLOR             = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 17;
-const Property::Index TextActor::GRADIENT_START_POINT       = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 18;
-const Property::Index TextActor::GRADIENT_END_POINT         = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 19;
-const Property::Index TextActor::SHADOW_SIZE                = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 20;
-const Property::Index TextActor::TEXT_COLOR                 = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT + 21;
+const Property::Index TextActor::TEXT                       = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+const Property::Index TextActor::FONT                       = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 1;
+const Property::Index TextActor::FONT_STYLE                 = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 2;
+const Property::Index TextActor::OUTLINE_ENABLE             = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 3;
+const Property::Index TextActor::OUTLINE_COLOR              = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 4;
+const Property::Index TextActor::OUTLINE_THICKNESS_WIDTH    = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 5;
+const Property::Index TextActor::SMOOTH_EDGE                = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 6;
+const Property::Index TextActor::GLOW_ENABLE                = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 7;
+const Property::Index TextActor::GLOW_COLOR                 = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 8;
+const Property::Index TextActor::GLOW_INTENSITY             = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 9;
+const Property::Index TextActor::SHADOW_ENABLE              = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 10;
+const Property::Index TextActor::SHADOW_COLOR               = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 11;
+const Property::Index TextActor::SHADOW_OFFSET              = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 12;
+const Property::Index TextActor::ITALICS_ANGLE              = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 13;
+const Property::Index TextActor::UNDERLINE                  = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 14;
+const Property::Index TextActor::WEIGHT                     = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 15;
+const Property::Index TextActor::FONT_DETECTION_AUTOMATIC   = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 16;
+const Property::Index TextActor::GRADIENT_COLOR             = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 17;
+const Property::Index TextActor::GRADIENT_START_POINT       = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 18;
+const Property::Index TextActor::GRADIENT_END_POINT         = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 19;
+const Property::Index TextActor::SHADOW_SIZE                = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 20;
+const Property::Index TextActor::TEXT_COLOR                 = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT + 21;
 
 namespace
 {
@@ -194,7 +194,7 @@ void TextActor::OnInitialize()
   if(TextActor::mFirstInstance)
   {
     mDefaultTextActorPropertyLookup = new DefaultPropertyLookup();
-    const int start = RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT;
+    const int start = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
     for ( int i = 0; i < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT; ++i )
     {
       (*mDefaultTextActorPropertyLookup)[DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[i]] = i + start;
@@ -654,16 +654,39 @@ unsigned int TextActor::GetDefaultPropertyCount() const
   return RenderableActor::GetDefaultPropertyCount() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT;
 }
 
+void TextActor::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  RenderableActor::GetDefaultPropertyIndices( indices ); // RenderableActor class properties
+
+  indices.reserve( indices.size() + DEFAULT_TEXT_ACTOR_PROPERTY_COUNT );
+
+  int index = DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 const std::string& TextActor::GetDefaultPropertyName( Property::Index index ) const
 {
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::GetDefaultPropertyName(index) ;
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[index - RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_TEXT_ACTOR_PROPERTY_NAMES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      static const std::string INVALID_PROPERTY_NAME;
+      return INVALID_PROPERTY_NAME;
+    }
   }
 }
 
@@ -690,7 +713,7 @@ Property::Index TextActor::GetDefaultPropertyIndex(const std::string& name) cons
 
 bool TextActor::IsDefaultPropertyWritable( Property::Index index ) const
 {
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::IsDefaultPropertyWritable(index) ;
   }
@@ -702,7 +725,7 @@ bool TextActor::IsDefaultPropertyWritable( Property::Index index ) const
 
 bool TextActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 {
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::IsDefaultPropertyAnimatable(index) ;
   }
@@ -714,22 +737,29 @@ bool TextActor::IsDefaultPropertyAnimatable( Property::Index index ) const
 
 Property::Type TextActor::GetDefaultPropertyType( Property::Index index ) const
 {
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     return RenderableActor::GetDefaultPropertyType(index) ;
   }
   else
   {
-    // ProxyObject guarantees that index is within range
-    return DEFAULT_TEXT_ACTOR_PROPERTY_TYPES[index - RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT];
+    index -= DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT;
+
+    if ( ( index >= 0 ) && ( index < DEFAULT_TEXT_ACTOR_PROPERTY_COUNT ) )
+    {
+      return DEFAULT_TEXT_ACTOR_PROPERTY_TYPES[index];
+    }
+    else
+    {
+      // index out-of-bounds
+      return Property::NONE;
+    }
   }
 }
 
 void TextActor::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
-
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     RenderableActor::SetDefaultProperty(index, propertyValue) ;
   }
@@ -898,7 +928,7 @@ void TextActor::SetDefaultProperty( Property::Index index, const Property::Value
 Property::Value TextActor::GetDefaultProperty( Property::Index index ) const
 {
   Property::Value ret ;
-  if(index < RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT)
+  if(index < DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT)
   {
     ret = RenderableActor::GetDefaultProperty(index) ;
   }
index 2157170..92f6746 100644 (file)
@@ -332,6 +332,11 @@ private: // ProxyObject default non-animatable properties
   virtual unsigned int GetDefaultPropertyCount() const ;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * copydoc Dali::Internal::ProxyObject
    */
   virtual const std::string& GetDefaultPropertyName( Property::Index index ) const ;
index 65a71aa..bb67c2d 100644 (file)
@@ -273,10 +273,28 @@ unsigned int ActiveConstraintBase::GetDefaultPropertyCount() const
   return DEFAULT_PROPERTY_COUNT;
 }
 
+void ActiveConstraintBase::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( DEFAULT_PROPERTY_COUNT );
+
+  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
+  {
+    indices.push_back( i );
+  }
+}
+
 const std::string& ActiveConstraintBase::GetDefaultPropertyName( Property::Index index ) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_NAMES[index];
+  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
+  {
+    return DEFAULT_PROPERTY_NAMES[index];
+  }
+  else
+  {
+    // index out of range..return empty string
+    static const std::string INVALID_PROPERTY_NAME;
+    return INVALID_PROPERTY_NAME;
+  }
 }
 
 Property::Index ActiveConstraintBase::GetDefaultPropertyIndex( const std::string& name ) const
@@ -304,13 +322,19 @@ bool ActiveConstraintBase::IsDefaultPropertyAnimatable( Property::Index index )
 
 Property::Type ActiveConstraintBase::GetDefaultPropertyType( Property::Index index ) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_TYPES[index];
+  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
+  {
+    return DEFAULT_PROPERTY_TYPES[index];
+  }
+  else
+  {
+    // Index out-of-range
+    return Property::NONE;
+  }
 }
 
 void ActiveConstraintBase::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
   switch ( index )
   {
     case Dali::ActiveConstraint::WEIGHT:
@@ -336,7 +360,6 @@ Property::Value ActiveConstraintBase::GetDefaultProperty( Property::Index index
 {
   Property::Value value;
 
-  // ProxyObject guarantees that index is within range
   switch ( index )
   {
     case Dali::ActiveConstraint::WEIGHT:
index e20b749..f1ca5ec 100644 (file)
@@ -180,6 +180,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName( Property::Index index ) const;
index 8e66473..0334e35 100644 (file)
@@ -25,6 +25,7 @@
 #include <dali/internal/common/event-to-update.h>
 #include <dali/internal/common/message.h>
 #include <dali/internal/event/common/proxy-object.h>
+#include <dali/internal/event/common/property-index-ranges.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/animation/active-constraint-base.h>
@@ -329,6 +330,9 @@ private:
     {
       Source& source = *iter;
 
+      // Type registry properties cannot be used as inputs
+      DALI_ASSERT_ALWAYS( ( source.propertyIndex < DEFAULT_PROPERTY_MAX_COUNT ) || ( source.propertyIndex >= CUSTOM_PROPERTY_START ) );
+
       PropertyInputImpl* inputProperty( NULL );
       int componentIndex( INVALID_PROPERTY_COMPONENT_INDEX );
 
index d20342d..53947f9 100644 (file)
@@ -90,6 +90,11 @@ public:
   virtual Property::Value GetProperty(Property::Index index) const = 0;
 
   /**
+   * @copydoc Dali::Handle::GetPropertyIndices()
+   */
+  virtual void GetPropertyIndices( Property::IndexContainer& indices ) const = 0;
+
+  /**
    * @copydoc Dali::Handle::RegisterProperty()
    */
   virtual Property::Index RegisterProperty(std::string name, const Property::Value& propertyValue) = 0;
index 28b3669..963a5fe 100644 (file)
@@ -17,6 +17,8 @@
 // limitations under the License.
 //
 
+#include <dali/public-api/object/type-registry.h>
+
 namespace Dali
 {
 
@@ -27,12 +29,14 @@ namespace Internal
  * Specifies the allowed ranges for different class types to cater for future allocation
  */
 
-#define DEFAULT_PROPERTY_MAX_COUNT                  10000 ///< Default Property Range:    0 to 9999
+#define DEFAULT_PROPERTY_MAX_COUNT                  PropertyRegistration::START_INDEX ///< Default Property Range:     0 to 9999999
+
+#define DEFAULT_ACTOR_PROPERTY_MAX_COUNT            10000                             ///< Actor Range:                0 to    9999
+#define DEFAULT_RENDERABLE_ACTOR_PROPERTY_MAX_COUNT 20000                             ///< Renderable Actor Range: 10000 to   19999
 
-#define DEFAULT_ACTOR_PROPERTY_MAX_COUNT            1000  ///< Actor Range:               0 to 999
-#define RENDERABLE_ACTOR_DEFAULT_PROPERTY_MAX_COUNT 2000  ///< Renderable Actor Range: 1000 to 1999
+#define DEFAULT_GESTURE_DETECTOR_PROPERTY_MAX_COUNT 10000                             ///< GestureDetector Range:      0 to    9999
 
-#define DEFAULT_GESTURE_DETECTOR_PROPERTY_MAX_COUNT 1000  ///< GestureDetector Range:     0 to 999
+#define CUSTOM_PROPERTY_START                       50000000                          ///< Custom Property Range: 50000000 onwards
 
 } // namespace Internal
 
index 20fb1ba..e8f3ccf 100644 (file)
@@ -21,6 +21,7 @@
 #include <algorithm>
 
 // INTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/update/common/animatable-property.h>
 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
@@ -29,6 +30,7 @@
 #include <dali/internal/event/animation/constraint-impl.h>
 #include <dali/internal/event/common/property-notification-impl.h>
 #include <dali/internal/event/common/property-index-ranges.h>
+#include <dali/internal/event/common/type-registry-impl.h>
 
 using Dali::Internal::SceneGraph::AnimatableProperty;
 using Dali::Internal::SceneGraph::PropertyBase;
@@ -46,12 +48,17 @@ typedef Dali::Vector<ProxyObject::Observer*>::Iterator ObserverIter;
 typedef Dali::Vector<ProxyObject::Observer*>::ConstIterator ConstObserverIter;
 
 static std::string EMPTY_PROPERTY_NAME;
+
+#if defined(DEBUG_ENABLED)
+Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PROXY_OBJECT" );
+#endif
 } // unnamed namespace
 
 const int INVALID_PROPERTY_COMPONENT_INDEX = -1;
 
 ProxyObject::ProxyObject()
-: mNextCustomPropertyIndex( 0u ),
+: mTypeInfo( NULL ),
+  mNextCustomPropertyIndex( 0u ),
   mCustomProperties( NULL ),
   mConstraints( NULL ),
   mRemovedConstraints( NULL ),
@@ -120,10 +127,28 @@ bool ProxyObject::Supports( Capability capability ) const
 unsigned int ProxyObject::GetPropertyCount() const
 {
   unsigned int count = GetDefaultPropertyCount();
+
+  DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
+
+  TypeInfo* typeInfo( GetTypeInfo() );
+  if ( typeInfo )
+  {
+    unsigned int manual( typeInfo->GetPropertyCount() );
+    count += manual;
+
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties:  %d\n", manual );
+  }
+
   if( mCustomProperties )
   {
-    count += mCustomProperties->size();
+    unsigned int custom( mCustomProperties->size() );
+    count += custom;
+
+    DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties:  %d\n", custom );
   }
+
+  DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties:   %d\n", count );
+
   return count;
 }
 
@@ -136,6 +161,19 @@ const std::string& ProxyObject::GetPropertyName( Property::Index index ) const
     return GetDefaultPropertyName( index );
   }
 
+  if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      return typeInfo->GetPropertyName( index );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
+    }
+  }
+
   if( mCustomProperties )
   {
     CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
@@ -152,18 +190,24 @@ Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
 
   index = GetDefaultPropertyIndex( name );
 
-  if (Property::INVALID_INDEX == index)
+  if ( index == Property::INVALID_INDEX )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      index = typeInfo->GetPropertyIndex( name );
+    }
+  }
+
+  if( index == Property::INVALID_INDEX && mCustomProperties )
   {
-    if( mCustomProperties )
+    // This is slow, but we're not (supposed to be) using property names frequently
+    for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
     {
-      // This is slow, but we're not (supposed to be) using property names frequently
-      for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
+      if (iter->second.name == name)
       {
-        if (iter->second.name == name)
-        {
-          index = iter->first;
-          break;
-        }
+        index = iter->first;
+        break;
       }
     }
   }
@@ -180,6 +224,19 @@ bool ProxyObject::IsPropertyWritable( Property::Index index ) const
     return IsDefaultPropertyWritable( index );
   }
 
+  if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      return typeInfo->IsPropertyWritable( index );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+    }
+  }
+
   if( mCustomProperties)
   {
     // Check that the index is valid
@@ -200,6 +257,12 @@ bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
     return IsDefaultPropertyAnimatable( index );
   }
 
+  if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    // Type Registry event-thread only properties are not animatable.
+    return false;
+  }
+
   if( mCustomProperties )
   {
     // Check custom property
@@ -220,6 +283,19 @@ Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
     return GetDefaultPropertyType( index );
   }
 
+  if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      return typeInfo->GetPropertyType( index );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+    }
+  }
+
   if( mCustomProperties )
   {
     CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
@@ -240,6 +316,18 @@ void ProxyObject::SetProperty( Property::Index index, const Property::Value& pro
 
     SetDefaultProperty( index, propertyValue );
   }
+  else if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      typeInfo->SetProperty( this, index, propertyValue );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+    }
+  }
   else if( mCustomProperties )
   {
     CustomPropertyLookup::iterator entry = mCustomProperties->find( index );
@@ -266,6 +354,18 @@ Property::Value ProxyObject::GetProperty(Property::Index index) const
   {
     value = GetDefaultProperty( index );
   }
+  else if ( ( index >= PropertyRegistration::START_INDEX ) && ( index <= PropertyRegistration::MAX_INDEX ) )
+  {
+    TypeInfo* typeInfo( GetTypeInfo() );
+    if ( typeInfo )
+    {
+      value = typeInfo->GetProperty( this, index );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
+    }
+  }
   else if( mCustomProperties )
   {
     CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
@@ -366,6 +466,33 @@ Property::Value ProxyObject::GetProperty(Property::Index index) const
   return value;
 }
 
+void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.clear();
+
+  // Default Properties
+  GetDefaultPropertyIndices( indices );
+
+  // Manual Properties
+  TypeInfo* typeInfo( GetTypeInfo() );
+  if ( typeInfo )
+  {
+    typeInfo->GetPropertyIndices( indices );
+  }
+
+  // Custom Properties
+  if ( mCustomProperties )
+  {
+    indices.reserve( indices.size() + mCustomProperties->size() );
+
+    const CustomPropertyLookup::const_iterator endIter = mCustomProperties->end();
+    for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); iter != endIter; ++iter )
+    {
+      indices.push_back( iter->first );
+    }
+  }
+}
+
 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue)
 {
   // Assert that property name is unused
@@ -435,7 +562,7 @@ Property::Index ProxyObject::RegisterProperty( std::string name, const Property:
   // Default properties start from index zero
   if ( 0u == mNextCustomPropertyIndex )
   {
-    mNextCustomPropertyIndex = DEFAULT_PROPERTY_MAX_COUNT;
+    mNextCustomPropertyIndex = CUSTOM_PROPERTY_START;
   }
 
   // Add entry to the property lookup
@@ -465,7 +592,7 @@ Property::Index ProxyObject::RegisterProperty( std::string name, const Property:
     // Default properties start from index zero
     if ( 0u == mNextCustomPropertyIndex )
     {
-      mNextCustomPropertyIndex = DEFAULT_PROPERTY_MAX_COUNT;
+      mNextCustomPropertyIndex = CUSTOM_PROPERTY_START;
     }
 
     // Add entry to the property lookup
@@ -480,12 +607,19 @@ Dali::PropertyNotification ProxyObject::AddPropertyNotification(Property::Index
                                                                 int componentIndex,
                                                                 const Dali::PropertyCondition& condition)
 {
-  if ( ( index >= DEFAULT_PROPERTY_MAX_COUNT )&&( mCustomProperties ) )
+  if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
   {
-    CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
-    DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
+    if ( index <= PropertyRegistration::MAX_INDEX )
+    {
+      DALI_ASSERT_ALWAYS( false && "Property notification added to non animatable property." );
+    }
+    else if ( mCustomProperties )
+    {
+      CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
+      DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
 
-    DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "Property notification added to non animatable property (currently not suppported )");
+      DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "Property notification added to non animatable property (currently not suppported )");
+    }
   }
 
   Dali::Handle self(this);
@@ -627,6 +761,23 @@ CustomPropertyLookup& ProxyObject::GetCustomPropertyLookup() const
   return *mCustomProperties;
 }
 
+TypeInfo* ProxyObject::GetTypeInfo() const
+{
+  if ( !mTypeInfo )
+  {
+    // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
+    // especially as the type-info does not change during the life-time of an application
+
+    Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
+    if ( typeInfoHandle )
+    {
+      mTypeInfo = &GetImplementation( typeInfoHandle );
+    }
+  }
+
+  return mTypeInfo;
+}
+
 void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
 {
   if( mConstraints )
index ef29a2c..95f37a1 100644 (file)
@@ -44,6 +44,7 @@ class Stage;
 class PropertyInputImpl;
 class ProxyObject;
 class Constraint;
+class TypeInfo;
 
 namespace SceneGraph
 {
@@ -204,6 +205,11 @@ public: // Property system interface from Internal::Object
   virtual Property::Value GetProperty(Property::Index index) const;
 
   /**
+   * @copydoc Dali::Handle::GetPropertyIndices()
+   */
+  virtual void GetPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::Object::RegisterProperty()
    */
   virtual Property::Index RegisterProperty(std::string name, const Property::Value& propertyValue);
@@ -312,6 +318,13 @@ private: // Default property extensions for derived classes
   virtual unsigned int GetDefaultPropertyCount() const = 0;
 
   /**
+   * Retrieve all the indices that are associated with the default properties supported by the derived class.
+   * @return A container of default property indices.
+   * @note The deriving class must not modify the existing elements in the container.
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const = 0;
+
+  /**
    * Query how many default properties the derived class supports.
    * @pre Property::INVALID_INDEX < index < GetDefaultPropertyCount().
    * @return The number of default properties.
@@ -392,8 +405,17 @@ protected:
    */
   CustomPropertyLookup& GetCustomPropertyLookup() const;
 
+  /**
+   * Retrieves the TypeInfo for this object. Only retrieves it from the type-registry once and then stores a pointer
+   * to it locally there-after. The type info will not change during the life-time of the application.
+   * @return The type-info for this object (Can be NULL)
+   */
+  TypeInfo* GetTypeInfo() const;
+
 private:
 
+  mutable TypeInfo* mTypeInfo; ///< The type-info for this object, mutable so it can be lazy initialized from const method if it is required
+
   Property::Index mNextCustomPropertyIndex; ///< The ID of the next custom property to be registered
 
   mutable CustomPropertyLookup* mCustomProperties; ///< Used for accessing custom Node properties, mutable so it can be lazy initialized from const function
index f423ae9..d600629 100644 (file)
 // EXTERNAL INCLUDES
 #include <algorithm> // std::find_if
 #include <string>
-#include <dali/public-api/object/type-registry.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/debug.h>
+#include <dali/internal/event/common/type-registry-impl.h>
 
 using std::find_if;
 
@@ -31,23 +31,44 @@ namespace
 {
 
 /*
- * Functor to find by name for vector of pairs
+ * Functor to find by given type for vector of pairs
  */
-template <typename T>
-struct PairNameListFinder
+template <typename S, typename T>
+struct PairFinder
 {
-  PairNameListFinder(const std::string &find)
+  PairFinder(const S& find)
   : mFind(find)
   {
   }
 
-  bool operator()(T &p)
+  bool operator()(const T& p) const
   {
     return p.first == mFind;
   }
 
 private:
 
+  const S& mFind;
+};
+
+/**
+ * Functor to find a matching property name
+ */
+template <typename T>
+struct PropertyNameFinder
+{
+  PropertyNameFinder( const std::string& find )
+  : mFind( find )
+  {
+  }
+
+  bool operator()(const T &p) const
+  {
+    return p.second.name == mFind;
+  }
+
+private:
+
   const std::string& mFind;
 };
 
@@ -85,7 +106,7 @@ bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, con
 {
   bool done = false;
 
-  ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairNameListFinder<ActionPair>(actionName));
+  ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
 
   if( iter != mActions.end() )
   {
@@ -118,7 +139,7 @@ bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* co
   bool connected( false );
 
   ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
-                                                 PairNameListFinder<ConnectionPairV2>(signalName) );
+                                                 PairFinder<std::string, ConnectionPairV2>(signalName) );
 
   if( iter != mSignalConnectors.end() )
   {
@@ -191,6 +212,49 @@ Dali::TypeInfo::NameContainer TypeInfo::GetSignals()
   return ret;
 }
 
+void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
+{
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  if ( base )
+  {
+    const TypeInfo& baseImpl( GetImplementation( base ) );
+    baseImpl.GetPropertyIndices( indices );
+  }
+
+  if ( ! mRegisteredProperties.empty() )
+  {
+    indices.reserve( indices.size() + mRegisteredProperties.size() );
+
+    const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
+    for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
+    {
+      indices.push_back( iter->first );
+    }
+  }
+}
+
+const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
+{
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    return iter->second.name;
+  }
+
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  if ( base )
+  {
+    return GetImplementation(base).GetPropertyName( index );
+  }
+
+  // Property not found, return reference to invalid property string.
+  static const std::string EMPTY_PROPERTY_NAME;
+  DALI_LOG_WARNING( "Property index (%d) invalid", index );
+  return EMPTY_PROPERTY_NAME;
+}
+
 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
 {
   if( NULL == function)
@@ -200,7 +264,7 @@ void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo:
   else
   {
     ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
-                                                  PairNameListFinder<ActionPair>(actionName));
+                                                  PairFinder<std::string, ActionPair>(actionName));
 
     if( iter == mActions.end() )
     {
@@ -222,7 +286,7 @@ void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeIn
   else
   {
     ConnectorContainerV2::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
-                                                   PairNameListFinder<ConnectionPairV2>(signalName) );
+                                                   PairFinder<std::string, ConnectionPairV2>(signalName) );
 
     if( iter == mSignalConnectors.end() )
     {
@@ -235,6 +299,203 @@ void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeIn
   }
 }
 
+void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
+{
+  // The setter can be empty as a property can be read-only.
+
+  if ( NULL == getFunc )
+  {
+    DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
+  }
+  else
+  {
+    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, setFunc, getFunc, name ) ) );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
+    }
+  }
+}
+
+unsigned int TypeInfo::GetPropertyCount() const
+{
+  unsigned int count( mRegisteredProperties.size() );
+
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  while ( base )
+  {
+    const TypeInfo& baseImpl( GetImplementation(base) );
+    count += baseImpl.mRegisteredProperties.size();
+    base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
+  }
+
+  return count;
+}
+
+Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
+{
+  Property::Index index = Property::INVALID_INDEX;
+
+  // Slow but should not be done that often
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PropertyNameFinder< RegisteredPropertyPair >( name ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    index = iter->first;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      index = GetImplementation(base).GetPropertyIndex( name );
+    }
+  }
+
+  return index;
+}
+
+bool TypeInfo::IsPropertyWritable( Property::Index index ) const
+{
+  bool writable( false );
+
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    writable = iter->second.setFunc ? true : false;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      writable = GetImplementation(base).IsPropertyWritable( index );
+    }
+  }
+
+  return writable;
+}
+
+Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
+{
+  Property::Type type( Property::NONE );
+
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+
+  if ( iter != mRegisteredProperties.end() )
+  {
+    type = iter->second.type;
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      type = GetImplementation(base).GetPropertyType( index );
+    }
+  }
+
+  return type;
+}
+
+void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value )
+{
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                    PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+  if ( iter != mRegisteredProperties.end() )
+  {
+    DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
+    iter->second.setFunc( object, index, value );
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      GetImplementation(base).SetProperty( object, index, value );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( false && "Property index not found" );
+    }
+  }
+}
+
+void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value )
+{
+  RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                    PropertyNameFinder< RegisteredPropertyPair >( name ) );
+  if ( iter != mRegisteredProperties.end() )
+  {
+    DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
+    iter->second.setFunc( object, iter->first, value );
+  }
+  else
+  {
+    Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+    if ( base )
+    {
+      GetImplementation(base).SetProperty( object, name, value );
+    }
+    else
+    {
+      DALI_ASSERT_ALWAYS( false && "Property name not found" );
+    }
+  }
+}
+
+Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index )
+{
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
+  if( iter != mRegisteredProperties.end() )
+  {
+    // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
+    return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
+  }
+
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  if ( base )
+  {
+    return GetImplementation( base ).GetProperty( object, index );
+  }
+
+  DALI_ASSERT_ALWAYS( false && "Property index not found" );
+
+  return Property::Value();
+}
+
+Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name )
+{
+  RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
+                                                          PropertyNameFinder< RegisteredPropertyPair >( name ) );
+  if( iter != mRegisteredProperties.end() )
+  {
+    // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
+    return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
+  }
+
+  Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
+  if ( base )
+  {
+    return GetImplementation( base ).GetProperty( object, name );
+  }
+
+  DALI_ASSERT_ALWAYS( false && "Property name not found" );
+
+  return Property::Value();
+}
+
 } // namespace Internal
 
 } // namespace Dali
index 13212b7..b857009 100644 (file)
@@ -84,6 +84,17 @@ public:
    */
   Dali::TypeInfo::NameContainer GetSignals();
 
+  /**
+   * Adds the property indices to the container specified.
+   * @param[in/out] indices The container where the property indices are added.
+   */
+  void GetPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
+   * @copydoc Dali::TypeInfo::GetPropertyName() const
+   */
+  const std::string& GetPropertyName( Property::Index index ) const;
+
   /*
    * Add an action function
    */
@@ -97,6 +108,16 @@ public:
   void AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunctionV2 function );
 
   /**
+   * Adds an event-thread only 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.
+   * @param[in] setFunc The function to call to set the property (Can be NULL).
+   * @param[in] getFunc The function to call to retrieve the value of the property.
+   */
+  void AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc );
+
+  /**
    * Do an action on base object
    * @param [in] object The base object to act upon
    * @param [in] actionName The name of the desired action
@@ -116,19 +137,105 @@ public:
    */
   bool ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor );
 
+  /**
+   * Retrieve the property count for this type.
+   * @return The total number of properties.
+   */
+  unsigned int GetPropertyCount() const;
+
+  /**
+   * Given a property name, retrieve the index.
+   * @param[in] name The name of the property.
+   * @return The index associated with that name.
+   */
+  Property::Index GetPropertyIndex( const std::string& name ) const;
+
+  /**
+   * Checks if there is a setter for the property. If there is then it is writable.
+   * @param[in] index The property index.
+   * @return True, if writable, false otherwise.
+   */
+  bool IsPropertyWritable( Property::Index index ) const;
+
+  /**
+   * Retrieve the Property::Type of the property at the given index.
+   * @param[in] index The property index.
+   * @return The Property::Type at that index.
+   */
+  Property::Type GetPropertyType( Property::Index index ) const;
+
+  /**
+   * Sets the value of a property at the index specified for the given object.
+   * @param[in] object The object whose property is to be set.
+   * @param[in] index The property index.
+   * @param[in] value The value to set.
+   */
+  void SetProperty( BaseObject *object, Property::Index index, const Property::Value& value );
+
+  /**
+   * Sets the value of a property with the name specified for the given object.
+   * @param[in] object The object whose property is to be set.
+   * @param[in] name The property name.
+   * @param[in] value The value to set.
+   */
+  void SetProperty( BaseObject *object, const std::string& name, const Property::Value& value );
+
+  /**
+   * Retrieves the value of a property at the index specified for the given object.
+   * @param[in] object The object whose property is to be queried.
+   * @param[in] index The property index.
+   * @return The current value of the property.
+   */
+  Property::Value GetProperty( const BaseObject *object, Property::Index index );
+
+  /**
+   * Retrieves the value of a property with the name specified for the given object.
+   * @param[in] object The object whose property is to be queried.
+   * @param[in] name The property name.
+   * @return The current value of the property.
+   */
+  Property::Value GetProperty( const BaseObject *object, const std::string& name );
+
 private:
 
+  struct RegisteredProperty
+  {
+    RegisteredProperty()
+    : type( Property::NONE ),
+      setFunc( NULL ),
+      getFunc( NULL ),
+      name()
+    {
+    }
+
+    RegisteredProperty( Property::Type propType, Dali::TypeInfo::SetPropertyFunction set, Dali::TypeInfo::GetPropertyFunction get, const std::string& propName )
+    : type( propType ),
+      setFunc( set ),
+      getFunc( get ),
+      name( propName )
+    {
+    }
+
+    Property::Type type;
+    Dali::TypeInfo::SetPropertyFunction setFunc;
+    Dali::TypeInfo::GetPropertyFunction getFunc;
+    std::string name;
+  };
+
   typedef std::pair<std::string, Dali::TypeInfo::SignalConnectorFunctionV2 > ConnectionPairV2;
   typedef std::pair<std::string, Dali::TypeInfo::ActionFunction > ActionPair;
+  typedef std::pair<Property::Index, RegisteredProperty> RegisteredPropertyPair;
 
   typedef std::vector< ActionPair > ActionContainer;
   typedef std::vector< ConnectionPairV2 > ConnectorContainerV2;
+  typedef std::vector< RegisteredPropertyPair > RegisteredPropertyContainer;
 
   std::string mTypeName;
   std::string mBaseTypeName;
   Dali::TypeInfo::CreateFunction mCreate;
   ActionContainer mActions;
   ConnectorContainerV2 mSignalConnectors;
+  RegisteredPropertyContainer mRegisteredProperties;
 };
 
 } // namespace Internal
index 58d4731..cd1e9c9 100644 (file)
@@ -240,6 +240,22 @@ bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::stri
   }
 }
 
+bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
+{
+  RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
+
+  if( iter != mRegistryLut.end() )
+  {
+    DALI_ASSERT_DEBUG(iter->second);
+
+    GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
+
+    return true;
+  }
+
+  return false;
+}
+
 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
 {
   bool done = false;
@@ -284,12 +300,12 @@ bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface
   return connected;
 }
 
-Dali::TypeInfo TypeRegistry::GetTypeInfo(Dali::BaseObject * const pBaseObject)
+Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
 {
   Dali::TypeInfo type;
 
   // test for custom actor which has another indirection to get to the type hiearchy we're after
-  Dali::Internal::CustomActor * const pCustom = dynamic_cast<Dali::Internal::CustomActor*>(pBaseObject);
+  const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
 
   if(pCustom)
   {
index d75fc91..7a13b73 100644 (file)
@@ -98,6 +98,18 @@ public:
    */
   bool RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f);
 
+  /**
+   * Register an event-thread 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
+   * @param [in] setFunc The function to set the property (Can be NULL).
+   * @param [in] getFunc The function to get the value of a property.
+   * @return true if registered
+   */
+  bool RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc );
+
   /*
    * @copydoc Dali::Internal::TypeInfo::DoActionTo
    * Walks all base types until it finds a doer.
@@ -114,7 +126,7 @@ public:
    * @param [in] pBaseObject Pointer to a BaseObject
    * @return TypeInfo for the BaseObject.
    */
-  Dali::TypeInfo GetTypeInfo(Dali::BaseObject * const pBaseObject);
+  Dali::TypeInfo GetTypeInfo(const Dali::BaseObject * const pBaseObject);
 
   /*
    * Calls any type creation functions that have been flagged as initialization functions
index bc3a3df..b25cf01 100644 (file)
@@ -513,10 +513,28 @@ unsigned int ShaderEffect::GetDefaultPropertyCount() const
   return DEFAULT_PROPERTY_COUNT;
 }
 
+void ShaderEffect::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( DEFAULT_PROPERTY_COUNT );
+
+  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
+  {
+    indices.push_back( i );
+  }
+}
+
 const std::string& ShaderEffect::GetDefaultPropertyName(Property::Index index) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_NAMES[index];
+  if( index < DEFAULT_PROPERTY_COUNT )
+  {
+    return DEFAULT_PROPERTY_NAMES[index];
+  }
+  else
+  {
+    // index out of range..return empty string
+    static const std::string INVALID_PROPERTY_NAME;
+    return INVALID_PROPERTY_NAME;
+  }
 }
 
 Property::Index ShaderEffect::GetDefaultPropertyIndex(const std::string& name) const
@@ -557,13 +575,19 @@ bool ShaderEffect::IsDefaultPropertyAnimatable(Property::Index index) const
 
 Property::Type ShaderEffect::GetDefaultPropertyType(Property::Index index) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_TYPES[index];
+  if( index < DEFAULT_PROPERTY_COUNT )
+  {
+    return DEFAULT_PROPERTY_TYPES[index];
+  }
+  else
+  {
+    // index out of range...return Property::NONE
+    return Property::NONE;
+  }
 }
 
 void ShaderEffect::SetDefaultProperty( Property::Index index, const Property::Value& propertyValue )
 {
-  // ProxyObject guarantees the property is writable and index is in range
   switch ( index )
   {
     case Dali::ShaderEffect::GRID_DENSITY:
@@ -770,13 +794,8 @@ void ShaderEffect::SetCustomProperty( Property::Index /* index */, const CustomP
 
 Property::Value ShaderEffect::GetDefaultProperty(Property::Index /*index*/) const
 {
-  Property::Value value;
-
-  // ProxyObject guarantees the property is writable and index is in range
-
   // none of our properties are readable so return empty
-
-  return value;
+  return Property::Value();
 }
 
 void ShaderEffect::InstallSceneObjectProperty( PropertyBase& newProperty, const std::string& name, unsigned int index )
index 8088160..e0c2773 100644 (file)
@@ -193,6 +193,11 @@ public: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName( Property::Index index ) const;
index 8fa7281..336cafb 100644 (file)
@@ -197,6 +197,10 @@ unsigned int GestureDetector::GetDefaultPropertyCount() const
   return 0;
 }
 
+void GestureDetector::GetDefaultPropertyIndices( Property::IndexContainer& ) const
+{
+}
+
 const std::string& GestureDetector::GetDefaultPropertyName( Property::Index index ) const
 {
   return INVALID_PROPERTY;
index 231b6bc..41f6140 100644 (file)
@@ -181,6 +181,11 @@ private: // Default property extensions from ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index 1e9fb77..862f37d 100644 (file)
@@ -345,16 +345,35 @@ unsigned int PanGestureDetector::GetDefaultPropertyCount() const
   return DEFAULT_PROPERTY_COUNT;
 }
 
+void PanGestureDetector::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( DEFAULT_PROPERTY_COUNT );
+
+  int index = DEFAULT_GESTURE_DETECTOR_PROPERTY_MAX_COUNT;
+  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i, ++index )
+  {
+    indices.push_back( index );
+  }
+}
+
 const std::string& PanGestureDetector::GetDefaultPropertyName( Property::Index index ) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_NAMES[index];
+  index -= DEFAULT_GESTURE_DETECTOR_PROPERTY_MAX_COUNT;
+  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
+  {
+    return DEFAULT_PROPERTY_NAMES[ index ];
+  }
+  else
+  {
+    // Index out-of-range... return empty string.
+    static const std::string INVALID_PROPERTY_NAME;
+    return INVALID_PROPERTY_NAME;
+  }
 }
 
 Property::Index PanGestureDetector::GetDefaultPropertyIndex(const std::string& name) const
 {
-  //Property::Index index = Property::INVALID_INDEX;
-  Property::Index index = 0;
+  Property::Index index = Property::INVALID_INDEX;
 
   DALI_ASSERT_DEBUG( NULL != mDefaultPropertyLookup );
 
@@ -382,8 +401,16 @@ bool PanGestureDetector::IsDefaultPropertyAnimatable(Property::Index index) cons
 
 Property::Type PanGestureDetector::GetDefaultPropertyType(Property::Index index) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_TYPES[index];
+  index -= DEFAULT_GESTURE_DETECTOR_PROPERTY_MAX_COUNT;
+  if ( ( index >= 0 ) && ( index < DEFAULT_PROPERTY_COUNT ) )
+  {
+    return DEFAULT_PROPERTY_TYPES[ index ];
+  }
+  else
+  {
+    // Index out-of-range
+    return Property::NONE;
+  }
 }
 
 void PanGestureDetector::SetDefaultProperty( Property::Index index, const Property::Value& property )
@@ -400,7 +427,6 @@ Property::Value PanGestureDetector::GetDefaultProperty(Property::Index index) co
 {
   Property::Value value;
 
-  // ProxyObject guarantees that index is within range
   switch ( index )
   {
     case Dali::PanGestureDetector::SCREEN_POSITION:
index 5de1695..9a89701 100644 (file)
@@ -219,6 +219,11 @@ private:
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index e0b2f16..70a2a1e 100644 (file)
@@ -14,6 +14,7 @@
 // limitations under the License.
 //
 
+#include <dali/internal/event/common/property-index-ranges.h>
 #include <dali/internal/event/common/stage-impl.h>
 #include <dali/internal/event/common/thread-local-storage.h>
 #include <dali/internal/event/modeling/animatable-mesh-impl.h>
@@ -94,6 +95,7 @@ AnimatableMeshPtr AnimatableMesh::New(
   bool useVertexColor )
 {
   DALI_ASSERT_ALWAYS( numVertices > 0 && "Mesh has no vertices" );
+  DALI_ASSERT_ALWAYS( ( numVertices * 3 ) < DEFAULT_PROPERTY_MAX_COUNT && "Mesh exceeds maximum supported vertices" );
   DALI_ASSERT_ALWAYS( faceIndices.size() > 0 && "Mesh has no faces" );
   for( Dali::AnimatableMesh::FacesConstIter faceIter=faceIndices.begin() ;
        faceIter != faceIndices.end() ;
@@ -220,10 +222,28 @@ unsigned int AnimatableMesh::GetDefaultPropertyCount() const
   return mPropertyCount;
 }
 
+void AnimatableMesh::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( mPropertyCount );
+
+  for ( int i = 0; i < mPropertyCount; ++i )
+  {
+    indices.push_back( i );
+  }
+}
+
 const std::string& AnimatableMesh::GetDefaultPropertyName( Property::Index index ) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_NAMES[index % VERTEX_PROPERTY_COUNT];
+  if ( ( index >= 0 ) && ( index < mPropertyCount ) )
+  {
+    return DEFAULT_PROPERTY_NAMES[index % VERTEX_PROPERTY_COUNT];
+  }
+  else
+  {
+    // Index out-of-range... return empty string.
+    static const std::string INVALID_PROPERTY_NAME;
+    return INVALID_PROPERTY_NAME;
+  }
 }
 
 Property::Index AnimatableMesh::GetDefaultPropertyIndex(const std::string& name) const
@@ -247,13 +267,21 @@ bool AnimatableMesh::IsDefaultPropertyAnimatable(Property::Index index) const
 
 Property::Type AnimatableMesh::GetDefaultPropertyType(Property::Index index) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_TYPES[index % VERTEX_PROPERTY_COUNT ];
+  if ( ( index >= 0 ) && ( index < mPropertyCount ) )
+  {
+    return DEFAULT_PROPERTY_TYPES[index % VERTEX_PROPERTY_COUNT ];
+  }
+  else
+  {
+    // Index out-of-bounds
+    return Property::NONE;
+  }
 }
 
 void AnimatableMesh::SetDefaultProperty( Property::Index index, const Property::Value& property )
 {
-  // ProxyObject guarantees the property is writable and index is in range
+  DALI_ASSERT_ALWAYS( ( index >= 0 ) && ( index < mPropertyCount ) );
+
   int vertexProperty = index % VERTEX_PROPERTY_COUNT;
   int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
   switch ( vertexProperty )
@@ -292,7 +320,6 @@ Property::Value AnimatableMesh::GetDefaultProperty(Property::Index index) const
   int vertexProperty = index % VERTEX_PROPERTY_COUNT;
   int vertexIndex    = index / VERTEX_PROPERTY_COUNT;
 
-  // ProxyObject guarantees that index is within range
   switch ( vertexProperty )
   {
     case Dali::AnimatableVertex::POSITION:
index 2bf15b9..387999c 100644 (file)
@@ -164,6 +164,11 @@ public: // Implementation of ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index 8ee3629..90870aa 100644 (file)
@@ -447,10 +447,28 @@ unsigned int RenderTask::GetDefaultPropertyCount() const
   return DEFAULT_PROPERTY_COUNT;
 }
 
+void RenderTask::GetDefaultPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.reserve( DEFAULT_PROPERTY_COUNT );
+
+  for ( int i = 0; i < DEFAULT_PROPERTY_COUNT; ++i )
+  {
+    indices.push_back( i );
+  }
+}
+
 const std::string& RenderTask::GetDefaultPropertyName( Property::Index index ) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_NAMES[index];
+  if( index < DEFAULT_PROPERTY_COUNT )
+  {
+    return DEFAULT_PROPERTY_NAMES[index];
+  }
+  else
+  {
+    // index out of range..return empty string
+    static const std::string INVALID_PROPERTY_NAME;
+    return INVALID_PROPERTY_NAME;
+  }
 }
 
 Property::Index RenderTask::GetDefaultPropertyIndex(const std::string& name) const
@@ -491,13 +509,19 @@ bool RenderTask::IsDefaultPropertyAnimatable(Property::Index index) const
 
 Property::Type RenderTask::GetDefaultPropertyType(Property::Index index) const
 {
-  // ProxyObject guarantees that index is within range
-  return DEFAULT_PROPERTY_TYPES[index];
+  if( index < DEFAULT_PROPERTY_COUNT )
+  {
+    return DEFAULT_PROPERTY_TYPES[index];
+  }
+  else
+  {
+    // index out of range...return Property::NONE
+    return Property::NONE;
+  }
 }
 
 void RenderTask::SetDefaultProperty( Property::Index index, const Property::Value& property )
 {
-  // ProxyObject guarantees the property is writable and index is in range
   switch ( index )
   {
     case Dali::RenderTask::VIEWPORT_POSITION:
@@ -534,7 +558,6 @@ Property::Value RenderTask::GetDefaultProperty(Property::Index index) const
 {
   Property::Value value;
 
-  // ProxyObject guarantees that index is within range
   switch ( index )
   {
 
index ffd0402..f3e2992 100644 (file)
@@ -233,6 +233,11 @@ public: // Implementation of ProxyObject
   virtual unsigned int GetDefaultPropertyCount() const;
 
   /**
+   * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyIndices()
+   */
+  virtual void GetDefaultPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
    * @copydoc Dali::Internal::ProxyObject::GetDefaultPropertyName()
    */
   virtual const std::string& GetDefaultPropertyName(Property::Index index) const;
index b38c930..24792e1 100644 (file)
@@ -53,6 +53,9 @@
 #include <dali/public-api/modeling/model-data.h>
 #include <dali/public-api/modeling/model.h>
 
+#include <dali/public-api/object/type-info.h>
+#include <dali/public-api/object/type-registry.h>
+
 #include <dali/public-api/text/utf8.h>
 
 #include <dali/public-api/scripting/scripting.h>
index 1764840..ff48347 100644 (file)
@@ -161,7 +161,9 @@ public_api_core_modeling_header_files =  \
   $(public_api_src_dir)/modeling/model-data.h \
   $(public_api_src_dir)/modeling/model.h
 
-public_api_core_object_header_files =
+public_api_core_object_header_files = \
+  $(public_api_src_dir)/object/type-info.h \
+  $(public_api_src_dir)/object/type-registry.h
 
 public_api_core_render_tasks_header_files =
 
index 104ffba..bd3b605 100644 (file)
@@ -68,7 +68,7 @@ bool BaseHandle::DoAction(const std::string& command, const std::vector<Property
   return GetImplementation(*this).DoAction( command, attributes );
 }
 
-std::string BaseHandle::GetTypeName()
+const std::string& BaseHandle::GetTypeName() const
 {
   return GetImplementation(*this).GetTypeName();
 }
index a72ca28..65c0984 100644 (file)
@@ -66,10 +66,8 @@ bool BaseObject::DoAction(const std::string& actionName, const std::vector<Prope
   return false;
 }
 
-std::string BaseObject::GetTypeName()
+const std::string& BaseObject::GetTypeName() const
 {
-  std::string name;
-
   Dali::Internal::TypeRegistry* registry = Dali::Internal::TypeRegistry::Get();
 
   if( registry )
@@ -77,11 +75,14 @@ std::string BaseObject::GetTypeName()
     Dali::TypeInfo typeInfo = registry->GetTypeInfo(this);
     if( typeInfo )
     {
-      name = typeInfo.GetName();
+      return typeInfo.GetName();
     }
   }
 
-  return name;
+  // We should not reach here
+  static const std::string INVALID_NAME;
+  DALI_LOG_ERROR( "TypeName Not Found\n" );
+  return INVALID_NAME;
 }
 
 bool BaseObject::DoConnectSignal( ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
index ec74a82..b508240 100644 (file)
@@ -115,6 +115,11 @@ Property::Value Handle::GetProperty(Property::Index index) const
   return GetImplementation(*this).GetProperty( index );
 }
 
+void Handle::GetPropertyIndices( Property::IndexContainer& indices ) const
+{
+  GetImplementation(*this).GetPropertyIndices( indices );
+}
+
 Dali::PropertyNotification Handle::AddPropertyNotification(Property::Index index,
                                                            const PropertyCondition& condition)
 {
index 4278922..1af4079 100644 (file)
@@ -63,6 +63,17 @@ TypeInfo::NameContainer TypeInfo::GetSignals()
   return GetImplementation(*this).GetSignals();
 }
 
+void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
+{
+  indices.clear(); // We do not want to clear the container if called internally, so only clear here
+  GetImplementation(*this).GetPropertyIndices( indices );
+}
+
+const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
+{
+  return GetImplementation(*this).GetPropertyName( index );
+}
+
 TypeInfo::TypeInfo(Internal::TypeInfo* internal)
 : BaseHandle(internal)
 {
similarity index 71%
rename from capi/dali/public-api/object/type-info.h
rename to dali/public-api/object/type-info.h
index 58f197a..612196f 100644 (file)
@@ -58,6 +58,22 @@ public:
    */
   typedef bool (*SignalConnectorFunctionV2)(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor);
 
+  /**
+   * Callback to set an event-thread only property @see PropertyRegistration
+   * @param[in] object The object whose property should be set.
+   * @param[in] index The index of the property being set.
+   * @param[in] value The new value of the property for the object specified.
+   */
+  typedef void (*SetPropertyFunction)( BaseObject* object, Property::Index index, const Property::Value& value );
+
+  /**
+   * Callback to get the value of an event-thread only property @see PropertyRegistration
+   * @param[in] object The object whose property value is required.
+   * @param[in] index The index of the property required.
+   * @return The current value of the property for the object specified.
+   */
+  typedef Property::Value (*GetPropertyFunction)( BaseObject* object, Property::Index index );
+
   typedef std::vector<std::string> NameContainer;
 
   /**
@@ -111,6 +127,22 @@ public:
    */
   NameContainer GetSignals();
 
+  // Properties
+
+  /**
+   * Retrieve all the property indices for this type
+   * @param[out] indices Container of property indices
+   * @note The container will be cleared
+   */
+  void GetPropertyIndices( Property::IndexContainer& indices ) const;
+
+  /**
+   * Given a property index, retrieve the property name associated with it.
+   * @param[in] index The property index.
+   * @return The name of the property at the given index.
+   */
+  const std::string& GetPropertyName( Property::Index index ) const;
+
 public: // Not intended for application developers
   /**
    * This constructor is used by Dali Get() method
index 5d4cade..e18b789 100644 (file)
@@ -21,6 +21,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/internal/event/common/type-registry-impl.h>
+#include <dali/internal/event/common/property-index-ranges.h>
 
 namespace Dali
 {
@@ -110,4 +111,11 @@ TypeAction::TypeAction( TypeRegistration &registered, const std::string &name, T
   Internal::TypeRegistry::Get()->RegisterAction( registered, name, f );
 }
 
+PropertyRegistration::PropertyRegistration( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, TypeInfo::SetPropertyFunction setFunc, TypeInfo::GetPropertyFunction getFunc )
+{
+  DALI_ASSERT_ALWAYS( ( index >= START_INDEX ) && ( index <= MAX_INDEX ) );
+
+  Internal::TypeRegistry::Get()->RegisterProperty( registered, name, index, type, setFunc, getFunc );
+}
+
 } // namespace Dali
similarity index 74%
rename from capi/dali/public-api/object/type-registry.h
rename to dali/public-api/object/type-registry.h
index 57e380a..196b08d 100644 (file)
@@ -47,14 +47,15 @@ class TypeRegistry;
  * @code
  * // Note: object construction in namespace scope is defined in a translation unit as being
  * //       in appearance order (C++ standard 3.6/2). So TypeRegistration is declared first in
- * //       the cpp file below. Signal and action declarations follow in any order.
+ * //       the cpp file below. Signal, action and property declarations follow in any order.
  * namespace
  * {
  *   TypeRegistration myActorType(typeid(MyActor), typeid(Actor), CreateMyActor );
  *
- *   TypeSignalConnector( myActorType, "highlighted", ConnectSignalForMyActor );
+ *   SignalConnectorType( myActorType, "highlighted", ConnectSignalForMyActor );
  *   TypeAction( myActorType, "open", DoMyActorAction );
  *   TypeAction( myActorType, "close", DoMyActorAction );
+ *   PropertyRegistration( myActorType, "status", PropertyRegistration::START_INDEX, Property::BOOLEAN, SetPropertyFunction, GetPropertyFunction );
  * }
  * @endcode
  *
@@ -221,6 +222,47 @@ public:
   TypeAction( TypeRegistration &registered, const std::string &name, TypeInfo::ActionFunction f);
 };
 
+/**
+ * Register a property for the given type.
+ */
+class PropertyRegistration
+{
+public:
+
+  // Enumerations are being used here rather than static constants so that switch statements can be used to compare property indices
+  enum
+  {
+    START_INDEX = 10000000,   ///< The index for this type should start from this number
+    MAX_INDEX   = 19999999    ///< The maximum index supported for this type
+  };
+
+  /**
+   * This constructor registers the property with the registered type. This constructor is for event-thread
+   * only properties where the value of the property can be retrieved and set via specified functions.
+   *
+   * Functions of the following type may be used for setFunc and getFunc respectively:
+   * @code
+   *   void SetProperty( BaseObject* object, Property::Index index, const Property::Value& value );
+   *   Property::Value GetProperty( BaseObject* object, Property::Index index );
+   * @endcode
+   *
+   * @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 START_INDEX and MAX_INDEX inclusive.
+   * @param [in] type The property value type.
+   * @param [in] setFunc The function to call when setting the property. If NULL, then the property becomes read-only.
+   * @param [in] getFunc The function to call to retrieve the current value of the property. MUST be provided.
+   *
+   * @note The "index" value must be between START_INDEX and MAX_INDEX inclusive.
+   * @note If "setFunc" is NULL, then the property becomes a read-only property.
+   * @note "getFunc" MUST be provided
+   *
+   * @pre "registered" must be registered with the TypeRegistry.
+   */
+  PropertyRegistration( TypeRegistration& registered,
+                        const std::string& name, Property::Index index, Property::Type type,
+                        TypeInfo::SetPropertyFunction setFunc, TypeInfo::GetPropertyFunction getFunc );
+};
 
 } // namespace Dali