Fix resource leaks in layouting. 09/196109/3
authorAnton Obzhirov <a.obzhirov@samsung.com>
Fri, 21 Dec 2018 15:00:14 +0000 (15:00 +0000)
committerAnton Obzhirov <a.obzhirov@samsung.com>
Mon, 24 Dec 2018 11:40:16 +0000 (11:40 +0000)
Change-Id: Ic8f126a9e5de6e9cf20120590843f901878c0889

automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.cpp
automated-tests/src/dali-toolkit/dali-toolkit-test-utils/dummy-control.h
automated-tests/src/dali-toolkit/utc-Dali-LayoutingAnimation.cpp
dali-toolkit/devel-api/layouting/layout-group-impl.cpp
dali-toolkit/devel-api/layouting/layout-item-impl.cpp
dali-toolkit/internal/layouting/layout-controller-impl.cpp
dali-toolkit/internal/layouting/layout-controller-impl.h
dali-toolkit/internal/layouting/layout-item-data-impl.cpp
dali-toolkit/internal/layouting/layout-item-data-impl.h
dali-toolkit/internal/layouting/layout-transition-data-impl.cpp
dali-toolkit/internal/layouting/layout-transition-data-impl.h

index 96699ecbba9694df90fd602a7fd4a34cb4165414..9825b56c8e9e61ddc6f1b212060791566c5bbe58 100644 (file)
@@ -201,6 +201,8 @@ Toolkit::DummyControl Impl::DummyControl::New()
   return control;
 }
 
+int Impl::DummyControl::constructorCount;
+int Impl::DummyControl::destructorCount;
 
 Impl::DummyControl::DummyControl()
 : DummyControlImpl(),
@@ -227,10 +229,13 @@ Impl::DummyControl::DummyControl()
   keyInputFocusGained(false),
   keyInputFocusLost(false)
 {
+  ++constructorCount;
 }
 
-Impl::DummyControl::~DummyControl() { }
-
+Impl::DummyControl::~DummyControl()
+{
+  ++destructorCount;
+}
 
 void Impl::DummyControl::OnInitialize() { initializeCalled = true; }
 bool Impl::DummyControl::OnAccessibilityActivated() { activatedCalled = true; return true; }
index 59882845f9e16e20a02b8bc591597f31a6843bf5..d991a82bd2693a4db0cf553b8f593c2ee067a536 100644 (file)
@@ -207,6 +207,8 @@ public:
   bool keyEventCalled;
   bool keyInputFocusGained;
   bool keyInputFocusLost;
+  static int constructorCount;
+  static int destructorCount;
 
   Property::Map mLayouts;
   RelayoutCallbackFunc mRelayoutCallback;
index 2bf827acf2added1968b344782649b1623d283c5..975007053b83d47a8aeb8526be8d06f587737087 100644 (file)
@@ -30,6 +30,7 @@
 #include <dali-toolkit/devel-api/layouting/layout-group-impl.h>
 
 #include <../custom-layout.h>
+#include <dummy-control.h>
 
 #include <layout-utils.h>
 
@@ -1797,3 +1798,72 @@ int UtcDaliLayouting_DefaultTransition01(void)
   END_TEST;
 }
 
+int UtcDaliLayouting_CheckResourceLeak01(void)
+{
+  ToolkitTestApplication application;
+  tet_infoline(" UtcDaliLayouting_CheckResourceLeak01 - Remove animating layout and add child to stage" );
+
+  Dali::Toolkit::Impl::DummyControl::constructorCount = 0;
+  Dali::Toolkit::Impl::DummyControl::destructorCount = 0;
+
+  Stage stage = Stage::GetCurrent();
+  auto container = Control::New();
+  auto linearLayout = LinearLayout::New();
+  linearLayout.SetAnimateLayout( true );
+
+  DevelControl::SetLayout( container, linearLayout );
+  container.SetName( "Container" );
+
+  stage.Add( container );
+
+  DummyControl control = DummyControl::New( true );
+  control.SetName( "DummyControl01" );
+  control.SetSize( 100, 100 );
+  container.Add( control );
+
+  control = DummyControl::New( true );
+  control.SetName( "DummyControl02" );
+  control.SetSize( 100, 100 );
+  container.Add( control );
+
+  linearLayout.SetAnimateLayout( true );
+
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::constructorCount, 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::destructorCount, 0, TEST_LOCATION );
+
+  // Initial rendering done
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ );
+
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::constructorCount, 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::destructorCount, 0, TEST_LOCATION );
+
+  stage.Remove( container );
+  container.Reset();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ );
+
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::constructorCount, 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::destructorCount, 1, TEST_LOCATION );
+
+  Stage::GetCurrent().Add( control );
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ );
+
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::constructorCount, 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::destructorCount, 1, TEST_LOCATION );
+
+  stage.Remove( control );
+  control.Reset();
+
+  application.SendNotification();
+  application.Render(static_cast<unsigned int>( 0.5f * 1000.0f ) + 1u /*just after the end of the animation*/ );
+
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::constructorCount, 2, TEST_LOCATION );
+  DALI_TEST_EQUALS( Dali::Toolkit::Impl::DummyControl::destructorCount, 2, TEST_LOCATION );
+
+  END_TEST;
+}
+
index 835aa66a3ceb10c54a5cee8100ea9e4faea70cf0..a27f060b40fa76e6cc7c73b9324fec5ef08230bb 100644 (file)
@@ -614,7 +614,7 @@ void LayoutGroup::ChildRemovedFromOwner( Actor child )
     if( childLayout )
     {
       Remove( *childLayout.Get() );
-      RequestLayout( Dali::Toolkit::LayoutTransitionData::Type::ON_CHILD_REMOVE, child, Actor() );
+      RequestLayout( Dali::Toolkit::LayoutTransitionData::Type::ON_CHILD_REMOVE, Actor(), child );
     }
   }
 }
index fe26362886470d099f28563748beb000b4436da8..a41a13edd59a9e452f890d0b5e33701879f17096 100644 (file)
@@ -66,14 +66,14 @@ LayoutItemPtr LayoutItem::New( Handle& owner )
 
 void LayoutItem::Initialize( Handle& owner, const std::string& containerType )
 {
-  mImpl->mOwner = &(owner.GetBaseObject());
+  mImpl->mOwner = owner;
   RegisterChildProperties( containerType );
   OnInitialize(); // Ensure direct deriving class gets initialized
 }
 
 Handle LayoutItem::GetOwner() const
 {
-  return Handle::DownCast(BaseHandle(mImpl->mOwner));
+  return mImpl->mOwner.GetHandle();
 }
 
 void LayoutItem::Unparent()
@@ -92,7 +92,7 @@ void LayoutItem::Unparent()
   SetParent(nullptr);
 
   // Last, clear owner
-  mImpl->mOwner = NULL;
+  mImpl->mOwner.Reset();
 }
 
 LayoutTransitionDataPtr LayoutItem::GetDefaultTransition()
@@ -317,7 +317,7 @@ void LayoutItem::SetMinimumHeight( LayoutLength minimumHeight )
 
 Extents LayoutItem::GetPadding() const
 {
-  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
   if( control )
   {
     Extents padding = control.GetProperty<Extents>( Toolkit::Control::Property::PADDING );
@@ -336,7 +336,7 @@ Extents LayoutItem::GetPadding() const
 
 Extents LayoutItem::GetMargin() const
 {
-  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
   if ( control )
   {
     return control.GetProperty<Extents>( Toolkit::Control::Property::MARGIN );
@@ -415,44 +415,47 @@ LayoutParent* LayoutItem::GetParent()
 
 void LayoutItem::RequestLayout()
 {
-  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
   if( control )
   {
     DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s)\n",
         control.GetName().c_str() );
+
+    // @todo Enforce failure if called in Measure/Layout passes.
+    mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
+    Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
+    layoutController.RequestLayout( Toolkit::LayoutItem( this ) );
   }
-  // @todo Enforce failure if called in Measure/Layout passes.
-  mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
-  Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
-  layoutController.RequestLayout( Toolkit::LayoutItem( this ) );
 }
 
 void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType )
 {
-  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
   if ( control )
   {
     DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n",
         control.GetName().c_str(), (int)layoutAnimationType );
+
+    // @todo Enforce failure if called in Measure/Layout passes.
+    mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
+    Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
+    layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType );
   }
-  // @todo Enforce failure if called in Measure/Layout passes.
-  mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
-  Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
-  layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType );
 }
 
 void LayoutItem::RequestLayout( Dali::Toolkit::LayoutTransitionData::Type layoutAnimationType, Actor gainedChild, Actor lostChild )
 {
-  Toolkit::Control control = Toolkit::Control::DownCast( mImpl->mOwner );
+  Toolkit::Control control = Toolkit::Control::DownCast( GetOwner() );
   if ( control )
   {
     DALI_LOG_INFO( gLayoutFilter, Debug::Verbose, "LayoutItem::RequestLayout control(%s) layoutTranstionType(%d)\n",
         control.GetName().c_str(), (int)layoutAnimationType );
+
+    // @todo Enforce failure if called in Measure/Layout passes.
+    mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
+    Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
+    layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType, gainedChild, lostChild );
   }
-  // @todo Enforce failure if called in Measure/Layout passes.
-  mImpl->SetPrivateFlag( Impl::PRIVATE_FLAG_FORCE_LAYOUT );
-  Toolkit::LayoutController layoutController = Toolkit::LayoutController::Get();
-  layoutController.RequestLayout( Toolkit::LayoutItem(this), layoutAnimationType, gainedChild, lostChild );
 }
 
 bool LayoutItem::IsLayoutRequested() const
@@ -517,7 +520,7 @@ MeasuredSize LayoutItem::GetMeasuredHeightAndState() const
 LayoutLength LayoutItem::GetSuggestedMinimumWidth() const
 {
   auto owner = GetOwner();
-  auto actor = Actor::DownCast(owner);
+  auto actor = Actor::DownCast( owner );
   auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
 
   return std::max( mImpl->mMinimumSize.GetWidth(), LayoutLength( naturalSize.width ) );
@@ -526,7 +529,7 @@ LayoutLength LayoutItem::GetSuggestedMinimumWidth() const
 LayoutLength LayoutItem::GetSuggestedMinimumHeight() const
 {
   auto owner = GetOwner();
-  auto actor = Actor::DownCast(owner);
+  auto actor = Actor::DownCast( owner );
   auto naturalSize = actor ? actor.GetNaturalSize() : Vector3::ZERO;
 
   return std::max( mImpl->mMinimumSize.GetHeight(), LayoutLength( naturalSize.height ) );
index 746e8e5509ea85c10c6035efda078e8e07efaa77..9d0b94784417f52e02ca3c396d9898bc8791da77 100644 (file)
@@ -82,7 +82,10 @@ void LayoutController::RequestLayout( LayoutItem& layoutItem, int layoutTransiti
   auto actor = Actor::DownCast( layoutItem.GetOwner() );
   if ( actor )
   {
-    DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutTransitionType(%d)\n", actor.GetName().c_str(), &layoutItem, layoutTransitionType );
+    DALI_LOG_INFO( gLogFilter, Debug::Concise, "LayoutController::RequestLayout owner[%s] layoutItem[%p] layoutTransitionType(%d) gainedChild[%s] lostChild[%s]\n",
+      actor.GetName().c_str(), &layoutItem, layoutTransitionType,
+      gainedChild ? gainedChild.GetName().c_str() : "",
+      lostChild ? lostChild.GetName().c_str() : "");
   }
   else
   {
@@ -236,16 +239,19 @@ void LayoutController::UpdateMeasureHierarchyForAnimation( LayoutData& layoutDat
       continue;
     }
 
-    Actor actor = Actor::DownCast( layoutDataElement.handle );
-    LayoutDataAnimator animator = layoutData.layoutAnimatorArray[ layoutDataElement.animatorIndex ];
-    float width = actor.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
-    float height = actor.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
-
-    if( layoutDataElement.AdjustMeasuredSize( width, height, animator.animatorType ) )
+    Actor actor = layoutDataElement.handle.GetHandle();
+    if( actor )
     {
-      mActorSizeSpecs.push_back( ActorSizeSpec( actor ) );
-      actor.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, static_cast<int>( width ) );
-      actor.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, static_cast<int>( height ) );
+      LayoutDataAnimator animator = layoutData.layoutAnimatorArray[ layoutDataElement.animatorIndex ];
+      float width = actor.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION );
+      float height = actor.GetProperty<int>( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION );
+
+      if( layoutDataElement.AdjustMeasuredSize( width, height, animator.animatorType ) )
+      {
+        mActorSizeSpecs.push_back( ActorSizeSpec( actor ) );
+        actor.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, static_cast<int>( width ) );
+        actor.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, static_cast<int>( height ) );
+      }
     }
   }
 
@@ -294,9 +300,12 @@ void LayoutController::RestoreActorsSpecs()
 {
   for( auto& actorSizeSpec : mActorSizeSpecs )
   {
-    Actor actor = actorSizeSpec.actor;
-    actor.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, actorSizeSpec.widthSpec );
-    actor.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, actorSizeSpec.heightSpec );
+    Actor actor = actorSizeSpec.actor.GetHandle();
+    if( actor )
+    {
+      actor.SetProperty( Toolkit::LayoutItem::ChildProperty::WIDTH_SPECIFICATION, actorSizeSpec.widthSpec );
+      actor.SetProperty( Toolkit::LayoutItem::ChildProperty::HEIGHT_SPECIFICATION, actorSizeSpec.heightSpec );
+    }
   }
 }
 
@@ -333,10 +342,10 @@ void LayoutController::PerformLayoutPositioning( LayoutPositionDataArray& layout
 
   for( auto layoutPositionData : layoutPositionDataArray )
   {
-    Actor actor = Actor::DownCast( layoutPositionData.handle );
+    Actor actor = layoutPositionData.handle.GetHandle();
     if( actor && ( !layoutPositionData.animated || all ) )
     {
-      if ( !layoutPositionData.animated )
+      if( !layoutPositionData.animated )
       {
         actor.SetPosition( layoutPositionData.left, layoutPositionData.top );
         actor.SetSize( layoutPositionData.right - layoutPositionData.left, layoutPositionData.bottom - layoutPositionData.top );
@@ -365,7 +374,7 @@ void LayoutController::PerformLayoutAnimation( LayoutTransition& layoutTransitio
   {
     if( layoutDataElement.animatorIndex >= 0 )
     {
-      Actor actor = Actor::DownCast( layoutDataElement.handle );
+      Actor actor = layoutDataElement.handle.GetHandle();
       if ( actor )
       {
         LayoutDataAnimator animator = layoutAnimatorArray[ layoutDataElement.animatorIndex ];
index 7443776d9f5e5553f6af465397d2c31831ea928b..8f78c32da2cd47c207d7f2b72fc0c91dedc02d0f 100644 (file)
@@ -101,7 +101,7 @@ private:
     {
     }
 
-    Actor actor;
+    WeakHandle<Actor> actor;
     int widthSpec;
     int heightSpec;
   };
@@ -129,7 +129,7 @@ private:
     {
       layoutController.PerformLayoutPositioning( layoutDataPositionArray, true );
       layoutController.mAnimationFinishedFunctors.pop_front();
-      if (layoutTransitionType != -1)
+      if( layoutTransitionType != -1 )
       {
         LayoutTransitionDataPtr layoutTransitionDataPtr = layoutItem->GetTransitionData( layoutTransitionType );
         layoutTransitionDataPtr->EmitSignalFinish( layoutTransitionType );
index c97a8dfd0d9369add58fa38cd77506a4c5f00503..e6e41b617676d62b1cd0ea04d7ee121506c70784 100644 (file)
@@ -30,7 +30,7 @@ bool LayoutItem::Impl::sUseZeroUnspecifiedMeasureSpec = false;
 LayoutData* LayoutItem::Impl::sLayoutData = nullptr;
 
 LayoutItem::Impl::Impl()
-: mOwner( nullptr ),
+: mOwner(),
   mLayoutParent( nullptr ),
   mOldWidthMeasureSpec( 0 ),
   mOldHeightMeasureSpec( 0 ),
index 0b415ad54507c35ffbf56598a102a32eaa149690..e7b2819dbd03bb662139e604644403ddd4073543 100644 (file)
@@ -16,7 +16,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
+#include <dali/public-api/object/weak-handle.h>
 #include <dali-toolkit/devel-api/layouting/layout-item-impl.h>
 #include <dali-toolkit/devel-api/layouting/layout-controller.h>
 #include <dali-toolkit/devel-api/layouting/layout-size.h>
@@ -35,7 +35,7 @@ public:
   Impl();
 
 public:
-  BaseObject* mOwner; ///< Control or Visual that owns this layout. Raw pointer to prevent cyclic references
+  WeakHandle<Handle> mOwner; ///< Control or Visual that owns this layout. Weak pointer to prevent cyclic references
   LayoutParent* mLayoutParent; ///< The containing layout parent.
 
   MeasureSpec mOldWidthMeasureSpec;
index fa24192de23cf03a5584cdd507c09fade06155f5..07a32ca520acb8dbcb5e9e33f7a0ef6dc88465db 100644 (file)
@@ -88,7 +88,7 @@ bool LayoutDataElement::AdjustMeasuredSize( float& width, float& height, Toolkit
     return false;
   }
 
-  Actor actor = Actor::DownCast( handle );
+  Actor actor = handle.GetHandle();
   float animateByMultiplier = ( animatorType == Toolkit::LayoutTransitionData::Animator::Type::ANIMATE_BY ) ? 1.0f : 0.0f;
   Vector3 size = actor.GetCurrentSize();
 
@@ -164,10 +164,13 @@ bool LayoutDataElement::AdjustMeasuredSize( float& width, float& height, Toolkit
 
 void LayoutDataElement::UpdatePropertyIndex()
 {
-  if( propertyIndex == -1 && handle && !propertyName.empty() )
+  if( propertyIndex == -1 && !propertyName.empty() )
   {
-    Actor actor = Actor::DownCast( handle );
-    propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( propertyName ) );
+    Actor actor = handle.GetHandle();
+    if( actor )
+    {
+      propertyIndex = DevelHandle::GetPropertyIndex( actor, Property::Key( propertyName ) );
+    }
   }
 }
 
@@ -223,7 +226,7 @@ LayoutTransitionDataPtr LayoutTransitionData::New()
 }
 
 LayoutTransitionData::PropertyAnimator::PropertyAnimator( )
-  : handle( Actor( ) )
+  : handle()
   , map()
   , interpolation( Animation::Linear )
 {
@@ -638,38 +641,41 @@ void LayoutTransitionData::CollectChildrenLayoutDataElements( Actor child, Layou
   // Add the children animators
   for( const LayoutDataElement& iter : layoutData.childrenLayoutDataArray )
   {
-    if( iter.handle != nullptr && iter.handle != child )
+    Actor actor = iter.handle.GetHandle();
+    if( actor && actor != child )
     {
       continue;
     }
 
     LayoutDataElement layoutDataElement = iter;
+    Actor gainedChild = layoutData.layoutTransition.gainedChild.GetHandle();
+    Actor lostChild = layoutData.layoutTransition.lostChild.GetHandle();
     switch ( layoutDataElement.condition )
     {
       case Dali::Toolkit::LayoutTransitionData::Condition::ON_ADD:
         if ( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_ADD
-            || layoutData.layoutTransition.gainedChild != child )
+            || gainedChild != child )
         {
           continue;
         }
         break;
       case Dali::Toolkit::LayoutTransitionData::Condition::ON_REMOVE:
         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_REMOVE
-            || layoutData.layoutTransition.lostChild != child )
+            || lostChild != child )
         {
           continue;
         }
         break;
       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_GAINED:
         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
-            || layoutData.layoutTransition.gainedChild != child )
+            || gainedChild != child )
         {
           continue;
         }
         break;
       case Dali::Toolkit::LayoutTransitionData::Condition::ON_FOCUS_LOST:
         if( layoutData.layoutTransition.layoutTransitionType != Dali::Toolkit::LayoutTransitionData::ON_CHILD_FOCUS
-            || layoutData.layoutTransition.lostChild != child )
+            || lostChild != child )
         {
           continue;
         }
@@ -713,7 +719,8 @@ void LayoutTransitionData::CollectLayoutDataElements( Actor owner, LayoutData& l
   // Collect the transition animators
   for( const LayoutDataElement& iter : mLayoutDataElements )
   {
-    if( iter.handle == nullptr || iter.handle != owner )
+    Actor actor = iter.handle.GetHandle();
+    if( !actor || actor != owner )
     {
       layoutData.childrenLayoutDataArray.push_back( iter );
       continue;
index 348f2d9aa67be5c77b183113df57ac15a38b3bdb..354a1bd904b2755757faa811a71f18d135c762bd 100644 (file)
@@ -22,6 +22,7 @@
 #include <dali/public-api/object/base-object.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/public-api/object/weak-handle.h>
 #include <dali/public-api/actors/actor-enumerations.h>
 #include <dali/public-api/animation/animation.h>
 
@@ -60,8 +61,8 @@ struct LayoutTransition
 
   LayoutItemPtr layoutItem;
   int layoutTransitionType;
-  Actor gainedChild;
-  Actor lostChild;
+  WeakHandle<Actor> gainedChild;
+  WeakHandle<Actor> lostChild;
 };
 
 const float DEFAULT_TRANSITION_DURATION( 0.5f );
@@ -92,12 +93,12 @@ using LayoutAnimatorArray = std::vector< LayoutDataAnimator >;
 
 struct LayoutPositionData
 {
-  LayoutPositionData( Handle handle, float left, float top, float right, float bottom, bool animated ) :
+  LayoutPositionData( Actor handle, float left, float top, float right, float bottom, bool animated ) :
       handle( handle ), left( left ), top( top ), right( right ), bottom( bottom ), animated( animated ), updateWithCurrentSize(false)
   {
   };
 
-  BaseHandle handle;
+  WeakHandle<Actor> handle;
   float left;
   float top;
   float right;
@@ -124,7 +125,7 @@ struct LayoutDataElement
   void UpdateAnimatorIndex( const LayoutAnimatorArray& animators );
   void UpdatePositionDataIndex( LayoutData& layoutData );
 
-  BaseHandle handle;
+  WeakHandle<Actor> handle;
   std::string propertyName;
   Property::Index propertyIndex;
   Property::Value initialValue;
@@ -154,7 +155,7 @@ public:
     PropertyAnimator( Actor actor, Property::Map map, Path path, Vector3 forward );
     PropertyAnimator( Actor actor, Property::Map map, KeyFrames keyFrames, Animation::Interpolation interpolation );
 
-    BaseHandle handle;
+    WeakHandle<Actor> handle;
 
     Property::Map map;