(FrameCallback) All values now local & baking of the value supported 54/190554/9
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Wed, 3 Oct 2018 19:16:46 +0000 (20:16 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 12 Oct 2018 08:29:12 +0000 (08:29 +0000)
- Callback now called before world matrix is calculated so removed
  the world matrix methods (as they will be a frame behind now)
- All values now in local actor space.
- Scale added.
- Added bake methods to save the values if required.
- Ensured that when an actor is removed, the node hierarchy is
  invalidated.

Change-Id: I76318fcf77c0ae6e7a217ee9169db71aeda9aa75

automated-tests/src/dali/utc-Dali-FrameCallbackInterface.cpp
dali/devel-api/update/update-proxy.cpp
dali/devel-api/update/update-proxy.h
dali/internal/event/animation/animation-impl.cpp
dali/internal/update/manager/frame-callback-processor.cpp
dali/internal/update/manager/frame-callback-processor.h
dali/internal/update/manager/update-manager.cpp
dali/internal/update/manager/update-proxy-impl.cpp
dali/internal/update/manager/update-proxy-impl.h

index 0a3afb2..c77f391 100644 (file)
@@ -45,17 +45,19 @@ class FrameCallbackBasic : public FrameCallbackInterface
 {
 public:
 
-  FrameCallbackBasic()
-  : mCalled( false )
-  {
-  }
+  FrameCallbackBasic() = default;
 
   virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
   {
     mCalled = true;
   }
 
-  bool mCalled;
+  virtual void Reset()
+  {
+    mCalled = false;
+  }
+
+  bool mCalled{ false };
 };
 
 } // anon namespace
@@ -69,27 +71,24 @@ public:
   {
   }
 
-  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ) override
   {
     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
-    updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrix, mSize );
-    mWorldMatrixGetWorldMatrixCall = updateProxy.GetWorldMatrix( mActorId );
-    mSizeGetSizeCall = updateProxy.GetSize( mActorId );
-    mPositionGetPositionCall = updateProxy.GetPosition( mActorId );
+    updateProxy.GetSize( mActorId, mSizeGetSizeCall );
+    updateProxy.GetPosition( mActorId, mPositionGetPositionCall );
     updateProxy.GetPositionAndSize( mActorId, mPositionGetPositionAndSizeCall, mSizeGetPositionAndSizeCall );
-    mWorldColor = updateProxy.GetWorldColor( mActorId );
+    updateProxy.GetColor( mActorId, mColor );
+    updateProxy.GetScale( mActorId, mScale );
   }
 
   const unsigned int mActorId;
 
-  Matrix mWorldMatrix;
-  Matrix mWorldMatrixGetWorldMatrixCall;
-  Vector3 mSize;
   Vector3 mSizeGetSizeCall;
   Vector3 mPositionGetPositionCall;
   Vector3 mPositionGetPositionAndSizeCall;
   Vector3 mSizeGetPositionAndSizeCall;
-  Vector4 mWorldColor;
+  Vector4 mColor;
+  Vector3 mScale;
 };
 
 class FrameCallbackSetter : public FrameCallbackBasic
@@ -98,40 +97,84 @@ public:
 
   FrameCallbackSetter(
       unsigned int actorId,
-      const Matrix& matrixToSet,
       const Vector3& sizeToSet,
       const Vector3& positionToSet,
-      const Vector4& colorToSet )
+      const Vector4& colorToSet,
+      const Vector3& scaleToSet )
   : mActorId( actorId ),
-    mMatrixToSet( matrixToSet ),
     mSizeToSet( sizeToSet ),
     mPositionToSet( positionToSet ),
-    mColorToSet( colorToSet )
+    mColorToSet( colorToSet ),
+    mScaleToSet( scaleToSet )
   {
   }
 
-  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ) override
   {
     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
-    updateProxy.SetWorldMatrix( mActorId, mMatrixToSet );
     updateProxy.SetSize( mActorId, mSizeToSet );
-    updateProxy.GetWorldMatrixAndSize( mActorId, mWorldMatrixAfterSetting, mSizeAfterSetting );
     updateProxy.SetPosition( mActorId, mPositionToSet );
-    mPositionAfterSetting = updateProxy.GetPosition( mActorId );
-    updateProxy.SetWorldColor( mActorId, mColorToSet );
-    mColorAfterSetting = updateProxy.GetWorldColor( mActorId );
+    updateProxy.SetColor( mActorId, mColorToSet );
+    updateProxy.SetScale( mActorId, mScaleToSet );
+    updateProxy.GetSize( mActorId, mSizeAfterSetting );
+    updateProxy.GetPosition( mActorId, mPositionAfterSetting );
+    updateProxy.GetColor( mActorId, mColorAfterSetting );
+    updateProxy.GetScale( mActorId, mScaleAfterSetting );
   }
 
   const unsigned int mActorId;
-  const Matrix& mMatrixToSet;
   const Vector3& mSizeToSet;
   const Vector3& mPositionToSet;
   const Vector4& mColorToSet;
+  const Vector3& mScaleToSet;
 
-  Matrix mWorldMatrixAfterSetting;
   Vector3 mSizeAfterSetting;
   Vector3 mPositionAfterSetting;
   Vector4 mColorAfterSetting;
+  Vector3 mScaleAfterSetting;
+};
+
+class FrameCallbackBaker : public FrameCallbackBasic
+{
+public:
+
+  FrameCallbackBaker(
+      unsigned int actorId,
+      const Vector3& sizeToSet,
+      const Vector3& positionToSet,
+      const Vector4& colorToSet,
+      const Vector3& scaleToSet )
+  : mActorId( actorId ),
+    mSizeToSet( sizeToSet ),
+    mPositionToSet( positionToSet ),
+    mColorToSet( colorToSet ),
+    mScaleToSet( scaleToSet )
+  {
+  }
+
+  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ) override
+  {
+    FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
+    updateProxy.BakeSize( mActorId, mSizeToSet );
+    updateProxy.BakePosition( mActorId, mPositionToSet );
+    updateProxy.BakeColor( mActorId, mColorToSet );
+    updateProxy.BakeScale( mActorId, mScaleToSet );
+    updateProxy.GetSize( mActorId, mSizeAfterSetting );
+    updateProxy.GetPosition( mActorId, mPositionAfterSetting );
+    updateProxy.GetColor( mActorId, mColorAfterSetting );
+    updateProxy.GetScale( mActorId, mScaleAfterSetting );
+  }
+
+  const unsigned int mActorId;
+  const Vector3& mSizeToSet;
+  const Vector3& mPositionToSet;
+  const Vector4& mColorToSet;
+  const Vector3& mScaleToSet;
+
+  Vector3 mSizeAfterSetting;
+  Vector3 mPositionAfterSetting;
+  Vector4 mColorAfterSetting;
+  Vector3 mScaleAfterSetting;
 };
 
 class FrameCallbackMultipleActors : public FrameCallbackBasic
@@ -142,29 +185,97 @@ public:
   {
   }
 
-  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds )
+  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ) override
   {
     FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
     for( auto&& i : mActorIds )
     {
-      Matrix matrix( false );
+      Vector3 position;
       Vector3 size;
-      updateProxy.GetWorldMatrixAndSize( i, matrix, size );
-      mWorldMatrices[ i ] = matrix;
+      updateProxy.GetPositionAndSize( i, position, size );
+      mPositions[ i ] = position;
       mSizes[ i ] = size;
     }
   }
 
   Vector< unsigned int > mActorIds;
 
-  std::map< unsigned int, Matrix > mWorldMatrices;
+  std::map< unsigned int, Vector3 > mPositions;
   std::map< unsigned int, Vector3 > mSizes;
 };
 
+class FrameCallbackActorIdCheck : public FrameCallbackBasic
+{
+public:
+
+  FrameCallbackActorIdCheck( unsigned int actorId )
+  : mActorId( actorId )
+  {
+  }
+
+  virtual void Update( Dali::UpdateProxy& updateProxy, float elapsedSeconds ) override
+  {
+    FrameCallbackBasic::Update( updateProxy, elapsedSeconds );
+    Vector3 vec3;
+    Vector4 vec4;
+
+    mGetSizeCallSuccess            = updateProxy.GetSize( mActorId, vec3 );
+    mGetPositionCallSuccess        = updateProxy.GetPosition( mActorId, vec3 );
+    mGetColorCallSuccess           = updateProxy.GetColor( mActorId, vec4 );
+    mGetScaleCallSuccess           = updateProxy.GetScale( mActorId, vec3 );
+    mGetPositionAndSizeCallSuccess = updateProxy.GetPositionAndSize( mActorId, vec3, vec3 );
+    mSetSizeCallSuccess            = updateProxy.SetSize( mActorId, vec3 );
+    mSetPositionCallSuccess        = updateProxy.SetPosition( mActorId, vec3 );
+    mSetColorCallSuccess           = updateProxy.SetColor( mActorId, vec4 );
+    mSetScaleCallSuccess           = updateProxy.SetScale( mActorId, vec3 );
+    mBakeSizeCallSuccess           = updateProxy.BakeSize( mActorId, vec3 );
+    mBakePositionCallSuccess       = updateProxy.BakePosition( mActorId, vec3 );
+    mBakeColorCallSuccess          = updateProxy.BakeColor( mActorId, vec4 );
+    mBakeScaleCallSuccess          = updateProxy.BakeScale( mActorId, vec3 );
+  }
+
+  virtual void Reset() override
+  {
+    // Up-call
+    FrameCallbackBasic::Reset();
+
+    mGetSizeCallSuccess = false;
+    mGetPositionCallSuccess = false;
+    mGetColorCallSuccess = false;
+    mGetScaleCallSuccess = false;
+    mGetPositionAndSizeCallSuccess = false;
+    mSetSizeCallSuccess = false;
+    mSetPositionCallSuccess = false;
+    mSetColorCallSuccess = false;
+    mSetScaleCallSuccess = false;
+    mBakeSizeCallSuccess = false;
+    mBakePositionCallSuccess = false;
+    mBakeColorCallSuccess = false;
+    mBakeScaleCallSuccess = false;
+  }
+
+  const uint32_t mActorId;
+  bool mGetSizeCallSuccess{ false };
+  bool mGetPositionCallSuccess{ false };
+  bool mGetColorCallSuccess{ false };
+  bool mGetScaleCallSuccess{ false };
+  bool mGetPositionAndSizeCallSuccess{ false };
+  bool mSetSizeCallSuccess{ false };
+  bool mSetPositionCallSuccess{ false };
+  bool mSetColorCallSuccess{ false };
+  bool mSetScaleCallSuccess{ false };
+  bool mBakeSizeCallSuccess{ false };
+  bool mBakePositionCallSuccess{ false };
+  bool mBakeColorCallSuccess{ false };
+  bool mBakeScaleCallSuccess{ false };
+};
+
 ///////////////////////////////////////////////////////////////////////////////
 
 int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
 {
+  // Basic test to check that the frame-callback can be installed and removed correctly
+
   TestApplication application;
 
   FrameCallbackBasic frameCallback;
@@ -191,10 +302,13 @@ int UtcDaliFrameCallbackCheckInstallationAndRemoval(void)
 
 int UtcDaliFrameCallbackGetters(void)
 {
+  // Test to see that the Getters all return the expected values
+
   TestApplication application;
   Vector2 actorSize( 200, 300 );
   Vector4 color( 0.5f, 0.6f, 0.7f, 0.8f );
   Vector3 position( 10.0f, 20.0f, 30.0f );
+  Vector3 scale( 2.0f, 4.0f, 6.0f );
 
   Actor actor = Actor::New();
   actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
@@ -202,10 +316,10 @@ int UtcDaliFrameCallbackGetters(void)
   actor.SetSize( actorSize );
   actor.SetColor( color );
   actor.SetPosition( position );
+  actor.SetScale( scale );
 
   Stage stage = Stage::GetCurrent();
   stage.Add( actor );
-  Vector2 stageSize = stage.GetSize();
 
   FrameCallbackOneActor frameCallback( actor.GetId() );
   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
@@ -213,29 +327,21 @@ int UtcDaliFrameCallbackGetters(void)
   application.SendNotification();
   application.Render();
 
-  Vector3 expectedPosition( -stageSize.width * 0.5f + actorSize.width * 0.5f + position.x,
-                            -stageSize.height * 0.5f + actorSize.height * 0.5f + position.y,
-                            0.0f + position.z );
-
-  Matrix expectedWorldMatrix( false );
-  expectedWorldMatrix.SetIdentity();
-  expectedWorldMatrix.SetTranslation( expectedPosition );
-
   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mWorldMatrix, expectedWorldMatrix, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, expectedWorldMatrix, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mSize, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, expectedPosition, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mPositionGetPositionAndSizeCall, expectedPosition, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, position, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mPositionGetPositionAndSizeCall, position, TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mSizeGetPositionAndSizeCall, Vector3( actorSize.width, actorSize.height, 0.0f ), TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mWorldColor, color, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mColor, color, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mScale, scale, TEST_LOCATION );
 
   END_TEST;
 }
 
 int UtcDaliFrameCallbackSetters(void)
 {
+  // Test to see that the setters set the values appropriately
+
   TestApplication application;
   Vector2 actorSize( 200, 300 );
 
@@ -246,39 +352,90 @@ int UtcDaliFrameCallbackSetters(void)
 
   Stage stage = Stage::GetCurrent();
   stage.Add( actor );
-  Vector2 stageSize = stage.GetSize();
 
-  Matrix matrixToSet( Matrix::IDENTITY );
-  matrixToSet.SetTranslation( Vector3( 100.0f, 500.0f, 50.0f ) );
   Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
   Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
   Vector4 colorToSet( Color::MAGENTA );
+  Vector3 scaleToSet( 1.0f, 3.0f, 5.0f );
 
-  FrameCallbackSetter frameCallback( actor.GetId(), matrixToSet, sizeToSet, positionToSet, colorToSet );
+  FrameCallbackSetter frameCallback( actor.GetId(), sizeToSet, positionToSet, colorToSet, scaleToSet );
   DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
 
   application.SendNotification();
   application.Render();
 
-  Matrix expectedWorldMatrix( false );
-  expectedWorldMatrix.SetIdentity();
-  expectedWorldMatrix.SetTranslation( Vector3( -stageSize.width * 0.5f + actorSize.width * 0.5f,
-                                               -stageSize.height * 0.5f + actorSize.height * 0.5f,
-                                               0.0f ) );
+  DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION );
+
+  // Ensure the actual actor values haven't changed as we didn't bake the values after removing the callback
+  DevelStage::RemoveFrameCallback( stage, frameCallback );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(), Vector3( actorSize ), TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::COLOR ).Get< Vector4 >(), Color::WHITE, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SCALE ).Get< Vector3 >(), Vector3::ONE, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliFrameCallbackBake(void)
+{
+  // Test to see that the bake methods bake the values
+
+  TestApplication application;
+  Vector2 actorSize( 200, 300 );
+
+  Actor actor = Actor::New();
+  actor.SetParentOrigin( ParentOrigin::TOP_LEFT );
+  actor.SetAnchorPoint( AnchorPoint::TOP_LEFT );
+  actor.SetSize( actorSize );
+
+  Stage stage = Stage::GetCurrent();
+  stage.Add( actor );
+
+  Vector3 sizeToSet( 1.0f, 2.0f, 3.0f );
+  Vector3 positionToSet( 10.0f, 20.0f, 30.0f );
+  Vector4 colorToSet( Color::MAGENTA );
+  Vector3 scaleToSet( 1.0f, 3.0f, 5.0f );
+
+  FrameCallbackBaker frameCallback( actor.GetId(), sizeToSet, positionToSet, colorToSet, scaleToSet );
+  DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+  application.SendNotification();
+  application.Render();
 
   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
-  DALI_TEST_CHECK( expectedWorldMatrix != matrixToSet );
-  DALI_TEST_EQUALS( frameCallback.mWorldMatrixAfterSetting, matrixToSet, TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mSizeAfterSetting, sizeToSet, TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mPositionAfterSetting, positionToSet, TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mColorAfterSetting, colorToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mScaleAfterSetting, scaleToSet, TEST_LOCATION );
+
+  // Ensure the new values are saved after removing the callback
+  DevelStage::RemoveFrameCallback( stage, frameCallback );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::POSITION ).Get< Vector3 >(), positionToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SIZE ).Get< Vector3 >(), sizeToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::COLOR ).Get< Vector4 >(), colorToSet, TEST_LOCATION );
+  DALI_TEST_EQUALS( actor.GetCurrentProperty( Actor::Property::SCALE ).Get< Vector3 >(), scaleToSet, TEST_LOCATION );
 
   END_TEST;
 }
 
+
 int UtcDaliFrameCallbackMultipleActors(void)
 {
   /**
+   * Test to check that the frame callback behaves appropriately with multiple actors
+   *
    * Tree:
    *              root-layer
    *              /        \
@@ -292,7 +449,7 @@ int UtcDaliFrameCallbackMultipleActors(void)
    *      /                        \
    *   actorC                     actorH
    *
-   *  Screen positions:
+   *  Screen positions (with minor alterations due to local position):
    *  -----------------------
    *  |actorA|actorD        |
    *  |      actorB         |
@@ -309,7 +466,6 @@ int UtcDaliFrameCallbackMultipleActors(void)
 
   TestApplication application;
   Stage stage = Stage::GetCurrent();
-  const Vector2 stageSize = stage.GetSize();
 
   std::map< char, Vector3 > sizes;
   sizes['A'] = Vector3(  50.0f,  50.0f, 0.0f );
@@ -321,81 +477,70 @@ int UtcDaliFrameCallbackMultipleActors(void)
   sizes['G'] = Vector3( 350.0f, 350.0f, 0.0f );
   sizes['H'] = Vector3( 400.0f, 350.0f, 0.0f );
 
-  std::map< char, Matrix > matrices;
-  for( char i = 'A'; i <= 'H'; ++i )
-  {
-    matrices[i] = Matrix::IDENTITY;
-  }
-
-  matrices['A'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['A'].width * 0.5f,
-                                         -stageSize.height * 0.5f + sizes['A'].height * 0.5f,
-                                         0.0f ) );
-  matrices['B'].SetTranslation( Vector3( matrices['A'].GetTranslation3() + sizes['A'] * 0.5f + sizes['B'] * 0.5f ) );
-  matrices['C'].SetTranslation( Vector3( matrices['B'].GetTranslation3().x,
-                                         matrices['B'].GetTranslation3().y + sizes['B'].height * 0.5f + sizes['C'].height * 0.5f,
-                                         0.0f ) );
-  matrices['D'].SetTranslation( Vector3( matrices['A'].GetTranslation3().x + sizes['A'].width * 0.5f + sizes['D'].width * 0.5f,
-                                         matrices['A'].GetTranslation3().y,
-                                         0.0f ) );
-  matrices['E'].SetTranslation( Vector3( -stageSize.width * 0.5f + sizes['E'].width * 0.5f,
-                                         stageSize.height * 0.5f - sizes['E'].height * 0.5f,
-                                         0.0f ) );
-  matrices['F'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x,
-                                         matrices['E'].GetTranslation3().y - sizes['E'].height * 0.5f - sizes['F'].height * 0.5f,
-                                         0.0f ) );
-  matrices['G'].SetTranslation( Vector3( matrices['E'].GetTranslation3().x + sizes['E'].width * 0.5f + sizes['G'].width * 0.5f,
-                                         matrices['E'].GetTranslation3().y,
-                                         0.0f ) );
-  matrices['H'].SetTranslation( Vector3( matrices['G'].GetTranslation3().x + sizes['G'].width * 0.5f + sizes['H'].width * 0.5f,
-                                         matrices['G'].GetTranslation3().y - sizes['G'].height * 0.5f - sizes['H'].height * 0.5f,
-                                         0.0f ) );
+  std::map< char, Vector3 > positions;
+  positions['A'] = Vector3(  0.0f,  1.0f,  2.0f );
+  positions['B'] = Vector3(  2.0f,  3.0f,  4.0f );
+  positions['C'] = Vector3(  5.0f,  6.0f,  7.0f );
+  positions['D'] = Vector3(  8.0f,  9.0f, 10.0f );
+  positions['E'] = Vector3( 11.0f, 12.0f, 13.0f );
+  positions['F'] = Vector3( 14.0f, 15.0f, 16.0f );
+  positions['G'] = Vector3( 17.0f, 18.0f, 19.0f );
+  positions['H'] = Vector3( 20.0f, 21.0f, 22.0f );
 
   Actor actorA = Actor::New();
   actorA.SetParentOrigin( ParentOrigin::TOP_LEFT );
   actorA.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   actorA.SetSize( sizes['A'] );
+  actorA.SetPosition( positions['A'] );
   stage.Add( actorA );
 
   Actor actorB = Actor::New();
   actorB.SetParentOrigin( ParentOrigin::BOTTOM_RIGHT );
   actorB.SetAnchorPoint( AnchorPoint::TOP_LEFT );
   actorB.SetSize( sizes['B'] );
+  actorB.SetPosition( positions['B'] );
   actorA.Add( actorB );
 
   Actor actorC = Actor::New();
   actorC.SetParentOrigin( ParentOrigin::BOTTOM_CENTER );
   actorC.SetAnchorPoint( AnchorPoint::TOP_CENTER );
   actorC.SetSize( sizes['C'] );
+  actorC.SetPosition( positions['C'] );
   actorB.Add( actorC );
 
   Actor actorD = Actor::New();
   actorD.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
   actorD.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
   actorD.SetSize( sizes['D'] );
+  actorD.SetPosition( positions['D'] );
   actorA.Add( actorD );
 
   Actor actorE = Actor::New();
   actorE.SetParentOrigin( ParentOrigin::BOTTOM_LEFT );
   actorE.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
   actorE.SetSize( sizes['E'] );
+  actorE.SetPosition( positions['E'] );
   stage.Add( actorE );
 
   Actor actorF = Actor::New();
   actorF.SetParentOrigin( ParentOrigin::TOP_CENTER );
   actorF.SetAnchorPoint( AnchorPoint::BOTTOM_CENTER );
   actorF.SetSize( sizes['F'] );
+  actorF.SetPosition( positions['F'] );
   actorE.Add( actorF );
 
   Actor actorG = Actor::New();
   actorG.SetParentOrigin( ParentOrigin::CENTER_RIGHT );
   actorG.SetAnchorPoint( AnchorPoint::CENTER_LEFT );
   actorG.SetSize( sizes['G'] );
+  actorG.SetPosition( positions['G'] );
   actorE.Add( actorG );
 
   Actor actorH = Actor::New();
   actorH.SetParentOrigin( ParentOrigin::TOP_RIGHT );
   actorH.SetAnchorPoint( AnchorPoint::BOTTOM_LEFT );
   actorH.SetSize( sizes['H'] );
+  actorH.SetPosition( positions['H'] );
   actorG.Add( actorH );
 
   std::map< char, unsigned int > actorIds;
@@ -423,7 +568,7 @@ int UtcDaliFrameCallbackMultipleActors(void)
 
   for( char i = 'A'; i <= 'H'; ++i )
   {
-    DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
+    DALI_TEST_EQUALS( frameCallback.mPositions[ actorIds[ i ] ], positions[ i ], TEST_LOCATION );
     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
   }
 
@@ -437,7 +582,7 @@ int UtcDaliFrameCallbackMultipleActors(void)
 
   for( char i = 'A'; i <= 'H'; ++i )
   {
-    DALI_TEST_EQUALS( frameCallback.mWorldMatrices[ actorIds[ i ] ], matrices[ i ], TEST_LOCATION );
+    DALI_TEST_EQUALS( frameCallback.mPositions[ actorIds[ i ] ], positions[ i ], TEST_LOCATION );
     DALI_TEST_EQUALS( frameCallback.mSizes[ actorIds[ i ] ], sizes[ i ], TEST_LOCATION );
   }
 
@@ -460,11 +605,128 @@ int UtcDaliFrameCallbackCheckActorNotAdded(void)
   application.SendNotification();
   application.Render();
 
+  // All should be default constructed objects
   DALI_TEST_EQUALS( frameCallback.mCalled, true, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mWorldMatrix, Matrix(true) /* Unchanged Matrix */, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mWorldMatrixGetWorldMatrixCall, Matrix::IDENTITY, TEST_LOCATION );
-  DALI_TEST_EQUALS( frameCallback.mSize, Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mPositionGetPositionCall, Vector3::ZERO, TEST_LOCATION );
   DALI_TEST_EQUALS( frameCallback.mSizeGetSizeCall, Vector3::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mColor, Vector4::ZERO, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mScale, Vector3::ZERO, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliFrameCallbackInvalidActorId(void)
+{
+  // Test to ensure that there are no issues when trying to use the update-proxy methods with an invalid actor ID.
+
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  FrameCallbackActorIdCheck frameCallback( 10000 );
+  DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+  application.SendNotification();
+  application.Render();
+
+  // Invalid Actor ID so all the methods should not return successfully.
+
+  DALI_TEST_EQUALS( frameCallback.mCalled,                        true,  TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetSizeCallSuccess,            false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionCallSuccess,        false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetColorCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetScaleCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionAndSizeCallSuccess, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetSizeCallSuccess,            false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetPositionCallSuccess,        false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetColorCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetScaleCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeSizeCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakePositionCallSuccess,       false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeColorCallSuccess,          false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeScaleCallSuccess,          false, TEST_LOCATION );
+
+  END_TEST;
+}
+
+int UtcDaliFrameCallbackActorRemovedAndAdded(void)
+{
+  // Test to ensure that we do not call methods on actors that have been removed on the stage
+  // and then re-start calling the required methods if that actor is re-added back to the stage
+
+  TestApplication application;
+  Stage stage = Stage::GetCurrent();
+
+  Actor actor = Actor::New();
+  stage.Add( actor );
+
+  FrameCallbackActorIdCheck frameCallback( actor.GetId() );
+  DevelStage::AddFrameCallback( stage, frameCallback, stage.GetRootLayer() );
+
+  application.SendNotification();
+  application.Render();
+
+  // All methods should return successfully.
+
+  DALI_TEST_EQUALS( frameCallback.mCalled,                        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetSizeCallSuccess,            true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionCallSuccess,        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetColorCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetScaleCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionAndSizeCallSuccess, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetSizeCallSuccess,            true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetPositionCallSuccess,        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetColorCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetScaleCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeSizeCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakePositionCallSuccess,       true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeColorCallSuccess,          true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeScaleCallSuccess,          true, TEST_LOCATION );
+  frameCallback.Reset();
+
+  // Remove the actor from stage, the methods should not return successfully.
+
+  stage.Remove( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( frameCallback.mCalled,                        true,  TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetSizeCallSuccess,            false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionCallSuccess,        false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetColorCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetScaleCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionAndSizeCallSuccess, false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetSizeCallSuccess,            false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetPositionCallSuccess,        false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetColorCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetScaleCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeSizeCallSuccess,           false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakePositionCallSuccess,       false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeColorCallSuccess,          false, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeScaleCallSuccess,          false, TEST_LOCATION );
+  frameCallback.Reset();
+
+  // Re-add the actor back to the stage, all the methods should once again, return successfully.
+
+  stage.Add( actor );
+
+  application.SendNotification();
+  application.Render();
+
+  DALI_TEST_EQUALS( frameCallback.mCalled,                        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetSizeCallSuccess,            true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionCallSuccess,        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetColorCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetScaleCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mGetPositionAndSizeCallSuccess, true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetSizeCallSuccess,            true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetPositionCallSuccess,        true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetColorCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mSetScaleCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeSizeCallSuccess,           true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakePositionCallSuccess,       true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeColorCallSuccess,          true, TEST_LOCATION );
+  DALI_TEST_EQUALS( frameCallback.mBakeScaleCallSuccess,          true, TEST_LOCATION );
 
   END_TEST;
 }
index 67511b4..b88bbd1 100644 (file)
 namespace Dali
 {
 
-Vector3 UpdateProxy::GetPosition( unsigned int id ) const
+bool UpdateProxy::GetPosition( unsigned int id, Vector3& position ) const
 {
-  return mImpl.GetPosition( id );
+  return mImpl.GetPosition( id, position );
 }
 
-void UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
+bool UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
 {
-  mImpl.SetPosition( id, position );
+  return mImpl.SetPosition( id, position );
 }
 
-const Vector3& UpdateProxy::GetSize( unsigned int id ) const
+bool UpdateProxy::BakePosition( unsigned int id, const Vector3& position )
 {
-  return mImpl.GetSize( id );
+  return mImpl.BakePosition( id, position );
 }
 
-void UpdateProxy::SetSize( unsigned int id, const Vector3& size )
+bool UpdateProxy::GetSize( unsigned int id, Vector3& size ) const
 {
-  mImpl.SetSize( id, size );
+  return mImpl.GetSize( id, size );
 }
 
-void UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
+bool UpdateProxy::SetSize( unsigned int id, const Vector3& size )
 {
-  mImpl.GetPositionAndSize( id, position, size );
+  return mImpl.SetSize( id, size );
 }
 
-Vector4 UpdateProxy::GetWorldColor( unsigned int id ) const
+bool UpdateProxy::BakeSize( unsigned int id, const Vector3& size )
 {
-  return mImpl.GetWorldColor( id );
+  return mImpl.BakeSize( id, size );
 }
 
-void UpdateProxy::SetWorldColor( unsigned int id, const Vector4& color ) const
+bool UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
 {
-  mImpl.SetWorldColor( id, color );
+  return mImpl.GetPositionAndSize( id, position, size );
 }
 
-void UpdateProxy::GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const
+bool UpdateProxy::GetScale( unsigned int id, Vector3& scale ) const
 {
-  mImpl.GetWorldMatrixAndSize( id, worldMatrix, size );
+  return mImpl.GetScale( id, scale );
 }
 
-const Matrix& UpdateProxy::GetWorldMatrix( unsigned int id ) const
+bool UpdateProxy::SetScale( unsigned int id, const Vector3& scale )
 {
-  return mImpl.GetWorldMatrix( id );
+  return mImpl.SetScale( id, scale );
 }
 
-void UpdateProxy::SetWorldMatrix( unsigned int id, const Matrix& worldMatrix )
+bool UpdateProxy::BakeScale( unsigned int id, const Vector3& scale )
 {
-  mImpl.SetWorldMatrix( id, worldMatrix );
+  return mImpl.BakeScale( id, scale );
+}
+
+bool UpdateProxy::GetColor( unsigned int id, Vector4& color ) const
+{
+  return mImpl.GetColor( id, color );
+}
+
+bool UpdateProxy::SetColor( unsigned int id, const Vector4& color ) const
+{
+  return mImpl.SetColor( id, color );
+}
+
+bool UpdateProxy::BakeColor( unsigned int id, const Vector4& color ) const
+{
+  return mImpl.BakeColor( id, color );
 }
 
 UpdateProxy::UpdateProxy( Internal::UpdateProxy& impl )
index 2ea1194..4595e7c 100644 (file)
@@ -45,83 +45,117 @@ class DALI_CORE_API UpdateProxy
 public:
 
   /**
-   * @brief Given the Actor ID, this retrieves that Actor's position.
-   * @param[in]  id  The Actor ID
-   * @return If valid Actor ID, then the Actor's position is returned.
+   * @brief Given the Actor ID, this retrieves that Actor's local position.
+   * @param[in]   id        The Actor ID
+   * @param[out]  position  Set to the Actor's current position, if Actor ID is valid
+   * @return Whether the method call was successful or not.
+   */
+  bool GetPosition( unsigned int id, Vector3& position ) const;
+
+  /**
+   * @brief Allows setting an Actor's local position from the Frame callback function for the current frame only.
+   * @param[in]  id        The Actor ID
+   * @param[in]  position  The position to set
+   * @return Whether the method call was successful or not.
+   * @note This will get reset to the internally calculated or previously baked value in the next frame, so will have to be set again.
    */
-  Vector3 GetPosition( unsigned int id ) const;
+  bool SetPosition( unsigned int id, const Vector3& position );
 
   /**
-   * @brief Allows setting an Actor's position from the Frame callback function.
+   * @brief Allows baking an Actor's local position from the Frame callback function.
    * @param[in]  id        The Actor ID
-   * @param[in]  position  The position to set.
-   * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+   * @param[in]  position  The position to bake
+   * @return Whether the method call was successful or not.
+   * @note The value is saved so will cause undesired effects if this property is being animated.
    */
-  void SetPosition( unsigned int id, const Vector3& position );
+  bool BakePosition( unsigned int id, const Vector3& position );
 
   /**
    * @brief Given the Actor ID, this retrieves that Actor's size.
-   * @param[in]  id  The Actor ID
-   * @return If valid Actor ID, then Actor's size is returned, otherwise Vector3::ZERO.
+   * @param[in]   id    The Actor ID
+   * @param[out]  size  Set to the Actor's current size, if Actor ID is valid
+   * @return Whether the method call was successful or not.
    */
-  const Vector3& GetSize( unsigned int id ) const;
+  bool GetSize( unsigned int id, Vector3& size ) const;
 
   /**
-   * @brief Allows setting an Actor's size from the Frame callback function.
+   * @brief Allows setting an Actor's size from the Frame callback function for the current frame only.
    * @param[in]  id    The Actor ID
-   * @param[in]  size  The size to set.
-   * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+   * @param[in]  size  The size to set
+   * @return Whether the method call was successful or not.
+   * @note This will get reset to the internally calculated or previously baked value in the next frame, so will have to be set again.
    */
-  void SetSize( unsigned int id, const Vector3& size );
+  bool SetSize( unsigned int id, const Vector3& size );
 
   /**
-   * @brief Given the Actor ID, this retrieves that Actor's position and size.
-   * @param[in]   id        The Actor ID
-   * @param[out]  position  If valid Actor ID, then Actor's position is set
-   * @param[out]  size      If valid Actor ID, then Actor's size is set
+   * @brief Allows baking an Actor's size from the Frame callback function.
+   * @param[in]  id    The Actor ID
+   * @param[in]  size  The size to bake
+   * @return Whether the method call was successful or not.
+   * @note The value is saved so will cause undesired effects if this property is being animated.
    */
-  void GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
+  bool BakeSize( unsigned int id, const Vector3& size );
 
   /**
-   * @brief Given the Actor ID, this retrieves that Actor's color.
+   * @brief Given the Actor ID, this retrieves that Actor's local position and size.
    * @param[in]   id        The Actor ID
-   * @return If valid Actor ID, then Actor's color is returned, otherwise Vector4::ZERO.
+   * @param[out]  position  Set to the Actor's current position, if Actor ID is valid
+   * @param[out]  size      Set to the Actor's current size, if Actor ID is valid
+   * @return Whether the method call was successful or not.
+   */
+  bool GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
+
+  /**
+   * @brief Given the Actor ID, this retrieves that Actor's local scale.
+   * @param[in]   id     The Actor ID
+   * @param[out]  scale  Set to the Actor's current scale, if Actor ID is valid
+   * @return Whether the method call was successful or not.
    */
-  Vector4 GetWorldColor( unsigned int id ) const;
+  bool GetScale( unsigned int id, Vector3& scale ) const;
 
   /**
-   * @brief Allows setting an Actor's color from the Frame callback function.
+   * @brief Allows setting an Actor's local scale from the Frame callback function for the current frame only.
    * @param[in]  id     The Actor ID
-   * @param[in]  color  The color to set
-   * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
+   * @param[in]  scale  The scale to set
+   * @return Whether the method call was successful or not.
+   * @note This will get reset to the internally calculated or previously baked value in the next frame, so will have to be set again.
    */
-  void SetWorldColor( unsigned int id, const Vector4& color ) const;
+  bool SetScale( unsigned int id, const Vector3& scale );
 
   /**
-   * @brief Given the Actor ID, this retrieves that Actor's world-matrix and size.
-   * @param[in]   id           The Actor ID
-   * @param[out]  worldMatrix  If valid Actor ID, then Actor's world matrix is set
-   * @param[out]  size         If valid Actor ID, then Actor's size is set
+   * @brief Allows baking an Actor's local scale from the Frame callback function.
+   * @param[in]  id     The Actor ID
+   * @param[in]  scale  The scale to bake
+   * @return Whether the method call was successful or not.
+   * @note The value is saved so will cause undesired effects if this property is being animated.
    */
-  void GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const;
+  bool BakeScale( unsigned int id, const Vector3& scale );
 
   /**
-   * @brief Given the Actor ID, this retrieves that Actor's world-matrix.
-   * @param[in]  id  The Actor ID
-   * @return If valid Actor ID, then Actor's world matrix is returned, otherwise Matrix::IDENTITY.
+   * @brief Given the Actor ID, this retrieves that Actor's local color.
+   * @param[in]   id     The Actor ID
+   * @param[out]  color  Set to the Actor's current color, if Actor ID is valid
+   * @return Whether the method call was successful or not.
    */
-  const Matrix& GetWorldMatrix( unsigned int id ) const;
+  bool GetColor( unsigned int id, Vector4& color ) const;
 
   /**
-   * @brief Allows the setting an Actor's world-matrix from the Frame callback function.
-   * @param[in]  id           The Actor ID
-   * @param[in]  worldMatrix  The world matrix to set.
-   * @note This will get reset to the internally calculated value in the next frame, so will have to be set again.
-   * @note This will only set the world matrix for that particular actor.
-   *       The world matrices of the children will not change and will have to be manually changed in the callback
-   *       as well (if required).
+   * @brief Allows setting an Actor's local color from the Frame callback function for the current frame only.
+   * @param[in]  id     The Actor ID
+   * @param[in]  color  The color to set
+   * @return Whether the method call was successful or not.
+   * @note This will get reset to the internally calculated or previously baked value in the next frame, so will have to be set again.
+   */
+  bool SetColor( unsigned int id, const Vector4& color ) const;
+
+  /**
+   * @brief Allows baking an Actor's local color from the Frame callback function.
+   * @param[in]  id     The Actor ID
+   * @param[in]  color  The color to bake
+   * @return Whether the method call was successful or not.
+   * @note The value is saved so will cause undesired effects if this property is being animated.
    */
-  void SetWorldMatrix( unsigned int id, const Matrix& worldMatrix );
+  bool BakeColor( unsigned int id, const Vector4& color ) const;
 
 public: // Not intended for application developers
 
index 876c7e6..6a914c3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -187,7 +187,6 @@ void Animation::SetDuration(float seconds)
     seconds = 0.0f;
   }
 
-  // Cache for public getters
   mDurationSeconds = seconds;
 
   // mAnimation is being used in a separate thread; queue a message to set the value
index 87f3b89..17423d1 100644 (file)
@@ -60,7 +60,8 @@ private:
 FrameCallbackProcessor::FrameCallbackProcessor( TransformManager& transformManager, Node& rootNode )
 : mFrameCallbacks(),
   mTransformManager( transformManager ),
-  mRootNode( rootNode )
+  mRootNode( rootNode ),
+  mNodeHierarchyChanged( true )
 {
 }
 
@@ -105,9 +106,16 @@ void FrameCallbackProcessor::Update( BufferIndex bufferIndex, float elapsedSecon
   {
     UpdateProxy& updateProxyImpl = *iter.updateProxyImpl;
     updateProxyImpl.SetCurrentBufferIndex( bufferIndex );
+
+    if( mNodeHierarchyChanged )
+    {
+      updateProxyImpl.NodeHierarchyChanged();
+    }
+
     Dali::UpdateProxy updateProxy( updateProxyImpl );
     iter.frameCallback->Update( updateProxy, elapsedSeconds );
   }
+  mNodeHierarchyChanged = false;
 }
 
 void FrameCallbackProcessor::PropertyOwnerDestroyed( PropertyOwner& owner )
index 90d9c7d..15d7376 100644 (file)
@@ -83,6 +83,14 @@ public:
    */
   void Update( BufferIndex bufferIndex, float elapsedSeconds );
 
+  /**
+   * Called by the UpdateManager when the node hierarchy changes.
+   */
+  void NodeHierarchyChanged()
+  {
+    mNodeHierarchyChanged = true;
+  }
+
 private:
 
   // From PropertyOwner::Observer
@@ -116,6 +124,8 @@ private:
 
   TransformManager& mTransformManager;
   Node& mRootNode;
+
+  bool mNodeHierarchyChanged;
 };
 
 } // namespace SceneGraph
index 10f290f..8a3bfb9 100644 (file)
@@ -408,6 +408,12 @@ void UpdateManager::ConnectNode( Node* parent, Node* node )
   DALI_ASSERT_ALWAYS( NULL == node->GetParent() ); // Should not have a parent yet
 
   parent->ConnectChild( node );
+
+  // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+  if( mImpl->frameCallbackProcessor )
+  {
+    mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+  }
 }
 
 void UpdateManager::DisconnectNode( Node* node )
@@ -417,6 +423,12 @@ void UpdateManager::DisconnectNode( Node* node )
   parent->SetDirtyFlag( ChildDeletedFlag ); // make parent dirty so that render items dont get reused
 
   parent->DisconnectChild( mSceneGraphBuffers.GetUpdateBufferIndex(), *node );
+
+  // Inform the frame-callback-processor, if set, about the node-hierarchy changing
+  if( mImpl->frameCallbackProcessor )
+  {
+    mImpl->frameCallbackProcessor->NodeHierarchyChanged();
+  }
 }
 
 void UpdateManager::DestroyNode( Node* node )
@@ -892,15 +904,15 @@ unsigned int UpdateManager::Update( float elapsedSeconds,
     //Update renderers and apply constraints
     UpdateRenderers( bufferIndex );
 
-    //Update the transformations of all the nodes
-    mImpl->transformManager.Update();
-
     // Call the frame-callback-processor if set
     if( mImpl->frameCallbackProcessor )
     {
       mImpl->frameCallbackProcessor->Update( bufferIndex, elapsedSeconds );
     }
 
+    //Update the transformations of all the nodes
+    mImpl->transformManager.Update();
+
     //Process Property Notifications
     ProcessPropertyNotifications( bufferIndex );
 
index 85404a9..e6d1434 100644 (file)
@@ -65,98 +65,169 @@ UpdateProxy::~UpdateProxy()
 {
 }
 
-Vector3 UpdateProxy::GetPosition( unsigned int id ) const
+bool UpdateProxy::GetPosition( unsigned int id, Vector3& position ) const
 {
-  const Dali::Matrix& matrix = GetWorldMatrix( id );
-  return matrix.GetTranslation3();
+  bool success = false;
+  const SceneGraph::Node* node = GetNodeWithId( id );
+  if( node )
+  {
+    position = mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_POSITION );
+    success = true;
+  }
+  return success;
 }
 
-void UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
+bool UpdateProxy::SetPosition( unsigned int id, const Vector3& position )
 {
-  const SceneGraph::Node* node = GetNodeWithId( id );
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    Matrix& matrix = mTransformManager.GetWorldMatrix( node->mTransformId );
-    matrix.SetTranslation( position );
+    mTransformManager.SetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_POSITION, position );
+    success = true;
   }
+  return success;
 }
 
-const Vector3& UpdateProxy::GetSize( unsigned int id ) const
+bool UpdateProxy::BakePosition( unsigned int id, const Vector3& position )
 {
-  const SceneGraph::Node* node = GetNodeWithId( id );
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    return mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE );
+    mTransformManager.BakeVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_POSITION, position );
+    success = true;
   }
+  return success;
+}
 
-  return Vector3::ZERO;
+bool UpdateProxy::GetSize( unsigned int id, Vector3& size ) const
+{
+  bool success = false;
+  const SceneGraph::Node* node = GetNodeWithId( id );
+  if( node )
+  {
+    size = mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE );
+    success = true;
+  }
+  return success;
 }
 
-void UpdateProxy::SetSize( unsigned int id, const Vector3& size )
+bool UpdateProxy::SetSize( unsigned int id, const Vector3& size )
 {
+  bool success = false;
   SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
     mTransformManager.SetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE, size );
+    success = true;
   }
+  return success;
 }
 
-void UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
+bool UpdateProxy::BakeSize( unsigned int id, const Vector3& size )
 {
-  Matrix worldMatrix( false );
-  GetWorldMatrixAndSize( id, worldMatrix, size );
-  position = worldMatrix.GetTranslation3();
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
+  if( node )
+  {
+    mTransformManager.BakeVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE, size );
+    success = true;
+  }
+  return success;
 }
 
-Vector4 UpdateProxy::GetWorldColor( unsigned int id ) const
+bool UpdateProxy::GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const
 {
-  SceneGraph::Node* node = GetNodeWithId( id );
+  bool success = false;
+  const SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    return node->mWorldColor.Get( mCurrentBufferIndex );
+    position = mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_POSITION );
+    size = mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SIZE );
+    success = true;
   }
+  return success;
+}
 
-  return Vector4::ZERO;
+bool UpdateProxy::GetScale( unsigned int id, Vector3& scale ) const
+{
+  bool success = false;
+  const SceneGraph::Node* node = GetNodeWithId( id );
+  if( node )
+  {
+    scale = mTransformManager.GetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SCALE );
+    success = true;
+  }
+
+  return success;
 }
 
-void UpdateProxy::SetWorldColor( unsigned int id, const Vector4& color ) const
+bool UpdateProxy::SetScale( unsigned int id, const Vector3& scale )
 {
+  bool success = false;
   SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    Vector4& currentColor = node->mWorldColor.Get( mCurrentBufferIndex );
-    currentColor = color;
+    mTransformManager.SetVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SCALE, scale );
+    success = true;
   }
+  return success;
 }
 
-void UpdateProxy::GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const
+bool UpdateProxy::BakeScale( unsigned int id, const Vector3& scale )
 {
-  const SceneGraph::Node* node = GetNodeWithId( id );
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    mTransformManager.GetWorldMatrixAndSize( node->mTransformId, worldMatrix, size );
+    mTransformManager.BakeVector3PropertyValue( node->mTransformId, SceneGraph::TRANSFORM_PROPERTY_SCALE, scale );
+    success = true;
   }
+  return success;
 }
 
-const Matrix& UpdateProxy::GetWorldMatrix( unsigned int id ) const
+bool UpdateProxy::GetColor( unsigned int id, Vector4& color ) const
 {
-  const SceneGraph::Node* node = GetNodeWithId( id );
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    return mTransformManager.GetWorldMatrix( node->mTransformId );
+    color = node->mColor.Get( mCurrentBufferIndex );
+    success = true;
   }
 
-  return Matrix::IDENTITY;
+  return success;
 }
 
-void UpdateProxy::SetWorldMatrix( unsigned int id, const Matrix& worldMatrix )
+bool UpdateProxy::SetColor( unsigned int id, const Vector4& color ) const
 {
+  bool success = false;
   SceneGraph::Node* node = GetNodeWithId( id );
   if( node )
   {
-    Matrix& currentMatrix = mTransformManager.GetWorldMatrix( node->mTransformId );
-    currentMatrix = worldMatrix;
+    node->mColor.Set( mCurrentBufferIndex, color );
+    success = true;
   }
+  return success;
+}
+
+bool UpdateProxy::BakeColor( unsigned int id, const Vector4& color ) const
+{
+  bool success = false;
+  SceneGraph::Node* node = GetNodeWithId( id );
+  if( node )
+  {
+    node->mColor.Bake( mCurrentBufferIndex, color );
+    success = true;
+  }
+  return success;
+}
+
+void UpdateProxy::NodeHierarchyChanged()
+{
+  mLastCachedIdNodePair = { 0u, NULL };
+  mNodeContainer.clear();
 }
 
 SceneGraph::Node* UpdateProxy::GetNodeWithId( unsigned int id ) const
index f730a75..5a63e2d 100644 (file)
@@ -67,52 +67,67 @@ public:
   /**
    * @copydoc Dali::UpdateProxy::GetPosition()
    */
-  Vector3 GetPosition( unsigned int id ) const;
+  bool GetPosition( unsigned int id, Vector3& position) const;
 
   /**
    * @copydoc Dali::UpdateProxy::SetPosition()
    */
-  void SetPosition( unsigned int id, const Vector3& position );
+  bool SetPosition( unsigned int id, const Vector3& position );
+
+  /**
+   * @copydoc Dali::UpdateProxy::BakePosition()
+   */
+  bool BakePosition( unsigned int id, const Vector3& position );
 
   /**
    * @copydoc Dali::UpdateProxy::GetSize()
    */
-  const Vector3& GetSize( unsigned int id ) const;
+  bool GetSize( unsigned int id, Vector3& size ) const;
 
   /**
    * @copydoc Dali::UpdateProxy::SetSize()
    */
-  void SetSize( unsigned int id, const Vector3& size );
+  bool SetSize( unsigned int id, const Vector3& size );
+
+  /**
+   * @copydoc Dali::UpdateProxy::BakeSize()
+   */
+  bool BakeSize( unsigned int id, const Vector3& size );
 
   /**
    * @copydoc Dali::UpdateProxy::GetPositionAndSize()
    */
-  void GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
+  bool GetPositionAndSize( unsigned int id, Vector3& position, Vector3& size ) const;
 
   /**
-   * @copydoc Dali::UpdateProxy::GetColor()
+   * @copydoc Dali::UpdateProxy::GetScale()
    */
-  Vector4 GetWorldColor( unsigned int id ) const;
+  bool GetScale( unsigned int id, Vector3& scale ) const;
 
   /**
-   * @copydoc Dali::UpdateProxy::SetColor()
+   * @copydoc Dali::UpdateProxy::SetScale()
+   */
+  bool SetScale( unsigned int id, const Vector3& scale );
+
+  /**
+   * @copydoc Dali::UpdateProxy::BakeScale()
    */
-  void SetWorldColor( unsigned int id, const Vector4& color ) const;
+  bool BakeScale( unsigned int id, const Vector3& scale );
 
   /**
-   * @copydoc Dali::UpdateProxy::GetWorldMatrixAndSize()
+   * @copydoc Dali::UpdateProxy::GetColor()
    */
-  void GetWorldMatrixAndSize( unsigned int id, Matrix& worldMatrix, Vector3& size ) const;
+  bool GetColor( unsigned int id, Vector4& color ) const;
 
   /**
-   * @copydoc Dali::UpdateProxy::GetWorldMatrix()
+   * @copydoc Dali::UpdateProxy::SetColor()
    */
-  const Matrix& GetWorldMatrix( unsigned int id ) const;
+  bool SetColor( unsigned int id, const Vector4& color ) const;
 
   /**
-   * @copydoc Dali::UpdateProxy::SetWorldMatrix()
+   * @copydoc Dali::UpdateProxy::BakeColor()
    */
-  void SetWorldMatrix( unsigned int id, const Matrix& worldMatrix );
+  bool BakeColor( unsigned int id, const Vector4& color ) const;
 
   /**
    * @brief Retrieves the root-node used by this class
@@ -123,11 +138,20 @@ public:
     return mRootNode;
   }
 
+  /**
+   * @brief Sets the buffer index to use when processing the next callback.
+   * @param[in]  bufferIndex  The current buffer index
+   */
   void SetCurrentBufferIndex( BufferIndex bufferIndex )
   {
     mCurrentBufferIndex = bufferIndex;
   }
 
+  /**
+   * @brief Informs the update-proxy that the node hierarchy has changed.
+   */
+  void NodeHierarchyChanged();
+
 private:
 
   /**
@@ -151,7 +175,7 @@ private:
 
   mutable std::vector< IdNodePair > mNodeContainer; ///< Used to store cached pointers to already searched for Nodes.
   mutable IdNodePair mLastCachedIdNodePair; ///< Used to cache the last retrieved id-node pair.
-  unsigned int mCurrentBufferIndex;
+  BufferIndex mCurrentBufferIndex;
 
   SceneGraph::TransformManager& mTransformManager; ///< Reference to the Transform Manager.
   SceneGraph::Node& mRootNode; ///< The root node of this update proxy.