From 2aca6c3748a55a07b3fb937aae35117e7207ddcf Mon Sep 17 00:00:00 2001
From: Paul Wisbey
Date: Mon, 15 Sep 2014 11:36:03 +0100
Subject: [PATCH] Simplified the Constraint removal logic
[problem] Memory corruption caused by unsafe calls to SetWeight
[cause] The root cause is the Constraint using the ProxyObject::Observer interface
for two different purposes; firstly to find out about parent on/off stage
behavior, and also to track the objects providing property inputs.
[solution] Reduced the complexity of the constraint logic; removed observer usage
for the parent object, moved code from templates to common base class.
Deprecated the (unused) SetRemoveTime API bloat.
Change-Id: I4d789143f4dc36767cbc91adf63d47f488c37e1b
---
automated-tests/src/dali-internal/CMakeLists.txt | 1 +
.../dali-internal/utc-Dali-Internal-Constraint.cpp | 98 +++++++
automated-tests/src/dali/utc-Dali-Constraint.cpp | 205 +-------------
.../event/animation/active-constraint-base.cpp | 226 ++++++++++------
.../event/animation/active-constraint-base.h | 87 +++---
.../event/animation/active-constraint-impl.h | 293 +--------------------
dali/internal/event/animation/constraint-impl.cpp | 10 -
dali/internal/event/animation/constraint-impl.h | 10 -
dali/internal/event/common/proxy-object.cpp | 89 +++----
dali/internal/event/common/proxy-object.h | 6 -
.../animation/scene-graph-constraint-base.cpp | 36 ++-
.../update/animation/scene-graph-constraint-base.h | 17 ++
dali/public-api/animation/constraint.cpp | 5 +-
dali/public-api/animation/constraint.h | 9 +-
14 files changed, 392 insertions(+), 700 deletions(-)
create mode 100644 automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp
diff --git a/automated-tests/src/dali-internal/CMakeLists.txt b/automated-tests/src/dali-internal/CMakeLists.txt
index 08fbd2c..39598b8 100644
--- a/automated-tests/src/dali-internal/CMakeLists.txt
+++ b/automated-tests/src/dali-internal/CMakeLists.txt
@@ -15,6 +15,7 @@ SET(TC_SOURCES
utc-Dali-Internal-ResourceClient.cpp
utc-Dali-Internal-Image-Culling.cpp
utc-Dali-Internal-Text-Culling.cpp
+ utc-Dali-Internal-Constraint.cpp
)
LIST(APPEND TC_SOURCES
diff --git a/automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp b/automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp
new file mode 100644
index 0000000..983aec3
--- /dev/null
+++ b/automated-tests/src/dali-internal/utc-Dali-Internal-Constraint.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2014 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+using namespace Dali;
+
+using Dali::Internal::SceneGraph::ConstraintBase;
+
+int UtcDaliConstraintNewInput1OffStage(void)
+{
+ /**
+ * Test that the Constraint is correctly added/removed when an object
+ * providing the input property is added/removed from the stage
+ */
+ TestApplication application;
+
+ Actor parent = Actor::New();
+ Stage::GetCurrent().Add( parent );
+
+ Actor actor = Actor::New();
+ parent.Add( actor );
+
+ Actor sibling1 = Actor::New();
+ sibling1.SetPosition( Vector3(1.0f, 2.0f, 3.0f) );
+ parent.Add( sibling1 );
+
+ Vector3 startValue( 0.0f, 0.0f, 0.0f );
+ DALI_TEST_EQUALS( 0u, ConstraintBase::GetCurrentInstanceCount(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 0u, ConstraintBase::GetTotalInstanceCount(), TEST_LOCATION );
+
+ /**
+ * Test that the Constraint is correctly applied on a clean Node
+ */
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::POSITION ), startValue, TEST_LOCATION );
+
+ // Apply constraint with a parent input property
+
+ Constraint constraint = Constraint::New( Actor::POSITION,
+ Source( sibling1, Actor::POSITION ),
+ EqualToConstraint() );
+
+ actor.ApplyConstraint( constraint );
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::POSITION ), startValue, TEST_LOCATION );
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::POSITION ), Vector3(1.0f, 2.0f, 3.0f)/*from sibling1*/, TEST_LOCATION );
+ DALI_TEST_EQUALS( 1u, ConstraintBase::GetCurrentInstanceCount(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 1u, ConstraintBase::GetTotalInstanceCount(), TEST_LOCATION );
+
+ // Remove sibling1 providing the input property
+
+ parent.Remove( sibling1 );
+ actor.SetPosition( Vector3(2.0f, 2.0f, 2.0f) ); // This should be effective
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::POSITION ), Vector3(2.0f, 2.0f, 2.0f)/*from SetPosition*/, TEST_LOCATION );
+ DALI_TEST_EQUALS( 0u/*should have been removed*/, ConstraintBase::GetCurrentInstanceCount(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 1u, ConstraintBase::GetTotalInstanceCount(), TEST_LOCATION );
+
+ // Add sibling1 back again (re-enables constraint)
+
+ parent.Add( sibling1 );
+ actor.SetPosition( Vector3(3.0f, 3.0f, 3.0f) ); // This should NOT be effective
+
+ application.SendNotification();
+ application.Render(0);
+ DALI_TEST_EQUALS( actor.GetProperty( Actor::POSITION ), Vector3(1.0f, 2.0f, 3.0f)/*from sibling1*/, TEST_LOCATION );
+ DALI_TEST_EQUALS( 1u, ConstraintBase::GetCurrentInstanceCount(), TEST_LOCATION );
+ DALI_TEST_EQUALS( 2u/*recreated once*/, ConstraintBase::GetTotalInstanceCount(), TEST_LOCATION );
+
+ END_TEST;
+}
+
diff --git a/automated-tests/src/dali/utc-Dali-Constraint.cpp b/automated-tests/src/dali/utc-Dali-Constraint.cpp
index 56d773e..a1d0a37 100644
--- a/automated-tests/src/dali/utc-Dali-Constraint.cpp
+++ b/automated-tests/src/dali/utc-Dali-Constraint.cpp
@@ -2412,99 +2412,6 @@ int UtcDaliConstraintGetApplyTime(void)
END_TEST;
}
-int UtcDaliConstraintSetRemoveTime(void)
-{
- TestApplication application;
-
- Vector3 sourcePosition(0.0f, 0.0f, 0.0f);
- Vector3 targetPosition(100.0f, 100.0f, 100.0f);
-
- // Build constraint
-
- Constraint constraint = Constraint::New( Actor::POSITION, TestPositionConstraint(targetPosition) );
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(0.0f), TEST_LOCATION);
-
- float removeSeconds(8.0f);
- constraint.SetRemoveTime(removeSeconds);
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(removeSeconds), TEST_LOCATION);
-
- // Apply to an actor
-
- Actor actor = Actor::New();
- Stage::GetCurrent().Add(actor);
-
- actor.ApplyConstraint( constraint );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
-
- application.SendNotification();
- application.Render(100u/*0.1 seconds*/);
-
- // Constraint should be fully applied
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
-
- // Check that nothing has changed after a couple of buffer swaps
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
-
- // Remove from the actor, and set to alternative position
-
- actor.RemoveConstraints();
-
- Vector3 thirdPosition(200.0f, 200.0f, 200.0f);
- actor.SetPosition(thirdPosition); // Go back to 3rd position
-
- application.SendNotification();
- application.Render(static_cast(removeSeconds*200.0f)/* 20% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 twentyPercentBack( targetPosition + (thirdPosition - targetPosition)*0.2f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), twentyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 40% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 fourtyPercentBack( targetPosition + (thirdPosition - targetPosition)*0.4f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), fourtyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 60% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 sixtyPercentBack( targetPosition + (thirdPosition - targetPosition)*0.6f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sixtyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 80% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 eightyPercentBack( targetPosition + (thirdPosition - targetPosition)*0.8f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), eightyPercentBack, TEST_LOCATION );
-
- // Constraint should be fully removed
- application.Render(static_cast(removeSeconds*200.0f)/* 100% removal progress */);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), thirdPosition, TEST_LOCATION );
-
- // Constraint should still be fully applied
- application.Render(static_cast(removeSeconds*200.0f)/* Still 100% removal progress */);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), thirdPosition, TEST_LOCATION );
-
- // Check that nothing has changed after a couple of buffer swaps
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), thirdPosition, TEST_LOCATION );
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), thirdPosition, TEST_LOCATION );
- END_TEST;
-}
-
-int UtcDaliConstraintGetRemoveTime(void)
-{
- TestApplication application;
-
- Constraint constraint = Constraint::New( Actor::COLOR, TestConstraint() );
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(0.0f), TEST_LOCATION);
- END_TEST;
-}
-
int UtcDaliConstraintSetAlphaFunction(void)
{
TestApplication application;
@@ -2634,10 +2541,6 @@ int UtcDaliConstraintSetRemoveAction(void)
constraint.SetRemoveAction(Constraint::Discard);
DALI_TEST_EQUALS((unsigned int)constraint.GetRemoveAction(), (unsigned int)Constraint::Discard, TEST_LOCATION);
- float removeSeconds(8.0f);
- constraint.SetRemoveTime(removeSeconds);
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(removeSeconds), TEST_LOCATION);
-
// Apply to an actor
Actor actor = Actor::New();
@@ -2659,40 +2562,16 @@ int UtcDaliConstraintSetRemoveAction(void)
DALI_TEST_EQUALS( actor.GetCurrentPosition(), targetPosition, TEST_LOCATION );
// Remove from the actor
-
actor.RemoveConstraints(); // should go back to source position
application.SendNotification();
- application.Render(static_cast(removeSeconds*200.0f)/* 20% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 twentyPercentBack( targetPosition * 0.8f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), twentyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 40% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 fourtyPercentBack( targetPosition * 0.6f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), fourtyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 60% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 sixtyPercentBack( targetPosition * 0.4f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sixtyPercentBack, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*200.0f)/* 80% removal progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 eightyPercentBack( targetPosition * 0.2f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), eightyPercentBack, TEST_LOCATION );
+ application.Render(static_cast(1000.0f));
// Constraint should be fully removed
- application.Render(static_cast(removeSeconds*200.0f)/* 100% removal progress */);
DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
- // Constraint should still be fully applied
- application.Render(static_cast(removeSeconds*200.0f)/* Still 100% removal progress */);
+ // Constraint should still be fully removed
+ application.Render(static_cast(1000.0f)/* Still 100% removal progress */);
DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
// Check that nothing has changed after a couple of buffer swaps
@@ -2719,83 +2598,6 @@ int UtcDaliConstraintGetRemoveAction(void)
}
/**
- * Test a constraint with non-zero apply-time and remove-time, where the constraint is removed during the apply-time
- */
-int UtcDaliConstraintRemoveDuringApply(void)
-{
- TestApplication application;
-
- Vector3 sourcePosition(0.0f, 0.0f, 0.0f);
- Vector3 targetPosition(100.0f, 100.0f, 100.0f);
- Vector3 halfwayPosition(targetPosition * 0.5f);
-
- // Build constraint
-
- Constraint constraint = Constraint::New( Actor::POSITION, TestPositionConstraint(targetPosition) );
- DALI_TEST_EQUALS((unsigned int)constraint.GetRemoveAction(), (unsigned int)Constraint::Bake, TEST_LOCATION);
-
- float applySeconds(4.0f);
- constraint.SetApplyTime(applySeconds);
- DALI_TEST_EQUALS(constraint.GetApplyTime(), TimePeriod(applySeconds), TEST_LOCATION);
-
- float removeSeconds(8.0f);
- constraint.SetRemoveTime(removeSeconds);
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(removeSeconds), TEST_LOCATION);
-
- // Apply to an actor
-
- Actor actor = Actor::New();
- Stage::GetCurrent().Add(actor);
-
- actor.ApplyConstraint( constraint );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
-
- application.SendNotification();
- application.Render(static_cast(applySeconds*250.0f)/* 25% progress */);
-
- // Constraint shouldn't be fully applied yet
- Vector3 twentyFivePercent( targetPosition * 0.25f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), twentyFivePercent, TEST_LOCATION );
-
- application.Render(static_cast(applySeconds*250.0f)/* 50% progress */);
-
- // Constraint shouldn't be fully applied yet
- Vector3 fiftyPercent( targetPosition * 0.5f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), fiftyPercent, TEST_LOCATION );
-
- // Remove from the actor
-
- actor.RemoveConstraints(); // should go back to source position
-
- application.SendNotification();
- application.Render(static_cast(removeSeconds*100.0f)/* 50% - 5% = 45% progress */);
-
- // Constraint shouldn't be fully removed yet
- Vector3 fourtyFivePercent( targetPosition * 0.45f );
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), fourtyFivePercent, TEST_LOCATION );
-
- application.Render(static_cast(removeSeconds*400.0f)/* 50% - 25% = 25% progress */);
-
- // Constraint shouldn't be fully removed yet
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), twentyFivePercent, TEST_LOCATION );
-
- // Constraint should be fully removed
- application.Render(static_cast(removeSeconds*500.0f)/* 0% progress */);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
-
- // Constraint should still be fully applied
- application.Render(static_cast(removeSeconds*200.0f)/* Still 0% progress */);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
-
- // Check that nothing has changed after a couple of buffer swaps
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
- application.Render(0);
- DALI_TEST_EQUALS( actor.GetCurrentPosition(), sourcePosition, TEST_LOCATION );
- END_TEST;
-}
-
-/**
* Test a constraint with non-zero apply-time & zero (immediate) remove-time, where the constraint is removed during the apply-time
*/
int UtcDaliConstraintImmediateRemoveDuringApply(void)
@@ -2813,7 +2615,6 @@ int UtcDaliConstraintImmediateRemoveDuringApply(void)
float applySeconds(4.0f);
constraint.SetApplyTime(applySeconds);
DALI_TEST_EQUALS(constraint.GetApplyTime(), TimePeriod(applySeconds), TEST_LOCATION);
- DALI_TEST_EQUALS(constraint.GetRemoveTime(), TimePeriod(0.0f), TEST_LOCATION);
// Apply to an actor
diff --git a/dali/internal/event/animation/active-constraint-base.cpp b/dali/internal/event/animation/active-constraint-base.cpp
index 047aa0f..9accd09 100644
--- a/dali/internal/event/animation/active-constraint-base.cpp
+++ b/dali/internal/event/animation/active-constraint-base.cpp
@@ -74,35 +74,50 @@ const Property::Type DEFAULT_PROPERTY_TYPES[DEFAULT_PROPERTY_COUNT] =
} // unnamed namespace
-ActiveConstraintBase::ActiveConstraintBase( EventToUpdate& eventToUpdate, Property::Index targetPropertyIndex )
+ActiveConstraintBase::ActiveConstraintBase( EventToUpdate& eventToUpdate, Property::Index targetPropertyIndex, SourceContainer& sources, unsigned int sourceCount )
: mEventToUpdate( eventToUpdate ),
mTargetPropertyIndex( targetPropertyIndex ),
+ mSources( sources ),
+ mSourceCount( sourceCount ),
mTargetProxy( NULL ),
+ mObservedProxies(),
mSceneGraphConstraint( NULL ),
mCustomWeight( NULL ),
mOffstageWeight( Dali::ActiveConstraint::DEFAULT_WEIGHT ),
- mRemoveTime( 0.0f ),
mAlphaFunction( Dali::Constraint::DEFAULT_ALPHA_FUNCTION ),
mRemoveAction( Dali::Constraint::DEFAULT_REMOVE_ACTION ),
mTag(0),
- mApplyAnimation(),
- mRemoveAnimation()
+ mApplyAnimation()
{
+ // Skip init when any of the proxy objects have been destroyed
+ if ( mSources.size() != mSourceCount )
+ {
+ // Discard all proxy pointers
+ mTargetProxy = NULL;
+ mSources.clear();
+ }
+
+ // Observe the objects providing properties
+ for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
+ {
+ if ( OBJECT_PROPERTY == iter->sourceType )
+ {
+ DALI_ASSERT_ALWAYS( NULL != iter->object && "ActiveConstraint source object not found" );
+
+ ObserveProxy( *(iter->object) );
+ }
+ }
}
ActiveConstraintBase::~ActiveConstraintBase()
{
- // Disconnect from internal animation signals
+ StopObservation();
+ // Disconnect from internal animation signals
if ( mApplyAnimation )
{
GetImplementation(mApplyAnimation).SetFinishedCallback( NULL, NULL );
}
-
- if( mRemoveAnimation )
- {
- GetImplementation(mRemoveAnimation).SetFinishedCallback( NULL, NULL );
- }
}
void ActiveConstraintBase::SetCustomWeightObject( ProxyObject& weightObject, Property::Index weightIndex )
@@ -114,14 +129,21 @@ void ActiveConstraintBase::SetCustomWeightObject( ProxyObject& weightObject, Pro
{
mCustomWeight = sceneProperty;
- OnCustomWeightSet( weightObject );
+ ObserveProxy( weightObject );
}
}
void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime )
{
- // Notify derived classes
- OnFirstApply( parent );
+ DALI_ASSERT_ALWAYS( NULL == mTargetProxy && "Parent of ActiveConstraint already set" );
+
+ // No need to do anything, if the source objects are gone
+ if( mSources.size() == mSourceCount )
+ {
+ mTargetProxy = &parent;
+
+ ConnectConstraint();
+ }
if ( applyTime.durationSeconds > 0.0f )
{
@@ -141,45 +163,59 @@ void ActiveConstraintBase::FirstApply( ProxyObject& parent, TimePeriod applyTime
}
}
-void ActiveConstraintBase::BeginRemove()
+void ActiveConstraintBase::OnParentDestroyed()
{
- // Notify derived classes
- OnBeginRemove();
+ // Stop observing the remaining proxies
+ StopObservation();
- // Remove gradually by animating weight down to zero
- if ( mRemoveTime.durationSeconds > 0.0f )
- {
- // Stop baking behaviour from interfering with remove animation
- if ( mSceneGraphConstraint )
- {
- // Immediately remove from scene-graph
- SetRemoveActionMessage( mEventToUpdate, *mSceneGraphConstraint, Dali::Constraint::Discard );
- }
-
- // Interrupt ongoing apply-animations
- if ( mApplyAnimation )
- {
- mApplyAnimation.Stop();
- }
-
- // Reduce the weight to zero
- mRemoveAnimation = Dali::Animation::New( mRemoveTime.delaySeconds + mRemoveTime.durationSeconds );
- Dali::ActiveConstraint self( this );
- mRemoveAnimation.AnimateTo( Property( self, Dali::ActiveConstraint::WEIGHT ), 0.0f, mAlphaFunction, mRemoveTime );
- mRemoveAnimation.Play();
+ // Discard all proxy pointers
+ mTargetProxy = NULL;
+ mSources.clear();
+}
- // Finish removal when animation ends
- GetImplementation(mRemoveAnimation).SetFinishedCallback( &ActiveConstraintBase::OnRemoveFinished, this );
+void ActiveConstraintBase::OnParentSceneObjectAdded()
+{
+ if ( NULL == mSceneGraphConstraint &&
+ mTargetProxy )
+ {
+ ConnectConstraint();
}
- else
+}
+
+void ActiveConstraintBase::OnParentSceneObjectRemoved()
+{
+ if ( mSceneGraphConstraint )
{
- OnRemoveFinished( this );
+ // Notify base class that the scene-graph constraint is being removed
+ OnSceneObjectRemove();
+
+ // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
+ mSceneGraphConstraint = NULL;
}
}
-bool ActiveConstraintBase::IsRemoving()
+void ActiveConstraintBase::BeginRemove()
{
- return mRemoveAnimation;
+ // Stop observing the remaining proxies
+ StopObservation();
+
+ // Discard all proxy pointers
+ mSources.clear();
+
+ const SceneGraph::PropertyOwner* propertyOwner = mTargetProxy ? mTargetProxy->GetSceneObject() : NULL;
+
+ if ( propertyOwner &&
+ mSceneGraphConstraint )
+ {
+ // Notify base class that the scene-graph constraint is being removed
+ OnSceneObjectRemove();
+
+ // Remove from scene-graph
+ RemoveConstraintMessage( mEventToUpdate, *propertyOwner, *(mSceneGraphConstraint) );
+
+ // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
+ mSceneGraphConstraint = NULL;
+ }
}
ProxyObject* ActiveConstraintBase::GetParent()
@@ -249,16 +285,6 @@ bool ActiveConstraintBase::DoConnectSignal( BaseObject* object, ConnectionTracke
return connected;
}
-void ActiveConstraintBase::SetRemoveTime( TimePeriod removeTime )
-{
- mRemoveTime = removeTime;
-}
-
-TimePeriod ActiveConstraintBase::GetRemoveTime() const
-{
- return mRemoveTime;
-}
-
void ActiveConstraintBase::SetAlphaFunction( AlphaFunction alphaFunc )
{
mAlphaFunction = alphaFunc;
@@ -289,7 +315,6 @@ unsigned int ActiveConstraintBase::GetTag() const
return mTag;
}
-
bool ActiveConstraintBase::IsSceneObjectRemovable() const
{
return true; // The constraint removed when target SceneGraph::PropertyOwner is destroyed
@@ -446,6 +471,76 @@ const PropertyInputImpl* ActiveConstraintBase::GetSceneObjectInputProperty( Prop
return &mSceneGraphConstraint->mWeight;
}
+void ActiveConstraintBase::SceneObjectAdded( ProxyObject& proxy )
+{
+ // Should not be getting callbacks when mSources has been cleared
+ DALI_ASSERT_DEBUG( mSources.size() == mSourceCount );
+
+ if ( NULL == mSceneGraphConstraint &&
+ mTargetProxy )
+ {
+ ConnectConstraint();
+ }
+}
+
+void ActiveConstraintBase::SceneObjectRemoved( ProxyObject& proxy )
+{
+ // Notify base class that the scene-graph constraint is being removed
+ OnSceneObjectRemove();
+
+ if ( mSceneGraphConstraint )
+ {
+ // Preserve the previous weight
+ mOffstageWeight = mSceneGraphConstraint->GetWeight( mEventToUpdate.GetEventBufferIndex() );
+
+ const SceneGraph::PropertyOwner* propertyOwner = mTargetProxy ? mTargetProxy->GetSceneObject() : NULL;
+
+ if( propertyOwner )
+ {
+ // Remove from scene-graph
+ RemoveConstraintMessage( mEventToUpdate, *propertyOwner, *(mSceneGraphConstraint) );
+ }
+
+ // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
+ mSceneGraphConstraint = NULL;
+ }
+}
+
+void ActiveConstraintBase::ProxyDestroyed( ProxyObject& proxy )
+{
+ // Remove proxy pointer from observation set
+ ProxyObjectIter iter = mObservedProxies.find( &proxy );
+ DALI_ASSERT_DEBUG( mObservedProxies.end() != iter );
+ mObservedProxies.erase( iter );
+
+ // Stop observing the remaining proxies
+ StopObservation();
+
+ // Discard all proxy & scene-graph pointers
+ mSceneGraphConstraint = NULL;
+ mTargetProxy = NULL;
+ mSources.clear();
+}
+
+void ActiveConstraintBase::ObserveProxy( ProxyObject& proxy )
+{
+ if ( mObservedProxies.end() == mObservedProxies.find(&proxy) )
+ {
+ proxy.AddObserver( *this );
+ mObservedProxies.insert( &proxy );
+ }
+}
+
+void ActiveConstraintBase::StopObservation()
+{
+ for( ProxyObjectIter iter = mObservedProxies.begin(); mObservedProxies.end() != iter; ++iter )
+ {
+ (*iter)->RemoveObserver( *this );
+ }
+
+ mObservedProxies.clear();
+}
+
void ActiveConstraintBase::FirstApplyFinished( Object* object )
{
ActiveConstraintBase& self = dynamic_cast( *object );
@@ -469,29 +564,6 @@ void ActiveConstraintBase::FirstApplyFinished( Object* object )
// WARNING - this constraint may now have been deleted; don't do anything else here
}
-void ActiveConstraintBase::OnRemoveFinished( Object* object )
-{
- ActiveConstraintBase& self = dynamic_cast( *object );
-
- const SceneGraph::PropertyOwner* propertyOwner = self.mTargetProxy ? self.mTargetProxy->GetSceneObject() : NULL;
-
- if ( propertyOwner &&
- self.mSceneGraphConstraint )
- {
- // Notify base class that the scene-graph constraint is being removed
- self.OnSceneObjectRemove();
-
- // Remove from scene-graph
- RemoveConstraintMessage( self.mEventToUpdate, *propertyOwner, *(self.mSceneGraphConstraint) );
-
- // mSceneGraphConstraint will be deleted in update-thread, remove dangling pointer
- self.mSceneGraphConstraint = NULL;
- }
-
- // The animation is no longer needed
- self.mRemoveAnimation.Reset();
-}
-
} // namespace Internal
} // namespace Dali
diff --git a/dali/internal/event/animation/active-constraint-base.h b/dali/internal/event/animation/active-constraint-base.h
index 2ebc1b7..d17912e 100644
--- a/dali/internal/event/animation/active-constraint-base.h
+++ b/dali/internal/event/animation/active-constraint-base.h
@@ -27,6 +27,8 @@
#include
#include
#include
+#include
+#include
namespace Dali
{
@@ -35,7 +37,8 @@ namespace Internal
{
class EventToUpdate;
-class ProxyObject;
+typedef std::set ProxyObjectContainer;
+typedef ProxyObjectContainer::iterator ProxyObjectIter;
namespace SceneGraph
{
@@ -48,7 +51,7 @@ class AnimatableProperty;
/**
* An abstract base class for active constraints.
*/
-class ActiveConstraintBase : public ProxyObject
+class ActiveConstraintBase : public ProxyObject, public ProxyObject::Observer
{
public:
@@ -59,8 +62,10 @@ public:
* Constructor.
* @param[in] messageController Used to send messages to the update-thread.
* @param[in] targetPropertyIndex The index of the property being constrained.
+ * @param[in] sources The sources of the input properties.
+ * @param[in] sourceCount The original number of sources; this may not match sources.size() if objects have died.
*/
- ActiveConstraintBase( EventToUpdate& messageController, Property::Index targetPropertyIndex );
+ ActiveConstraintBase( EventToUpdate& messageController, Property::Index targetPropertyIndex, SourceContainer& sources, unsigned int sourceCount );
/**
* Virtual destructor.
@@ -94,11 +99,19 @@ public:
void BeginRemove();
/**
- * Query whether the constraint is being removed.
- * This is only possible if mRemoveTime.durationSeconds is non-zero.
- * @return True if constraint is being removed.
+ * Called when the target object is destroyed.
*/
- bool IsRemoving();
+ void OnParentDestroyed();
+
+ /**
+ * Called when the target object is connected to the scene-graph
+ */
+ void OnParentSceneObjectAdded();
+
+ /**
+ * Called when the target object is disconnected from the scene-graph
+ */
+ void OnParentSceneObjectRemoved();
/**
* Retrieve the parent of the active-constraint.
@@ -137,16 +150,6 @@ public:
ActiveConstraintSignalV2& AppliedSignal();
/**
- * @copydoc Dali::Constraint::SetRemoveTime()
- */
- void SetRemoveTime( TimePeriod timePeriod );
-
- /**
- * @copydoc Dali::Constraint::GetRemoveTime()
- */
- TimePeriod GetRemoveTime() const;
-
- /**
* @copydoc Dali::Constraint::SetAlphaFunction()
*/
void SetAlphaFunction(AlphaFunction func);
@@ -176,8 +179,6 @@ public:
*/
unsigned int GetTag() const;
-
-
/**
* Connects a callback function with the object's signals.
* @param[in] object The object providing the signal.
@@ -271,46 +272,58 @@ public: // Default property extensions from ProxyObject
*/
virtual const PropertyInputImpl* GetSceneObjectInputProperty( Property::Index index ) const;
-private:
+public: // ProxyObject::Observer methods
/**
- * Helper called after the first apply animation.
- * @param [in] object The active constraint.
+ * @copydoc ProxyObject::Observer::SceneObjectAdded()
*/
- static void FirstApplyFinished( Object* object );
+ virtual void SceneObjectAdded( ProxyObject& proxy );
/**
- * Helper called after the remove animation.
- * @param [in] object The active constraint.
+ * @copydoc ProxyObject::Observer::SceneObjectRemoved()
*/
- static void OnRemoveFinished( Object* object );
+ virtual void SceneObjectRemoved( ProxyObject& proxy );
- // To be implemented in derived classes
+ /**
+ * @copydoc ProxyObject::Observer::ProxyDestroyed()
+ */
+ virtual void ProxyDestroyed( ProxyObject& proxy );
+
+private:
/**
- * Used to observe the lifetime of an object with custom "weight" property
- * @param [in] weightObject The object.
+ * Helper to observe a proxy, if not already observing it
*/
- virtual void OnCustomWeightSet( ProxyObject& weightObject ) = 0;
+ void ObserveProxy( ProxyObject& proxy );
/**
- * Set the parent of the active-constraint; called during OnFirstApply().
- * @param [in] parent The parent object.
+ * Helper to stop observing proxies
*/
- virtual void OnFirstApply( ProxyObject& parent ) = 0;
+ void StopObservation();
/**
- * Notification for the derived class, when BeginRemove() is called.
+ * Helper called after the first apply animation.
+ * @param [in] object The active constraint.
*/
- virtual void OnBeginRemove() = 0;
+ static void FirstApplyFinished( Object* object );
+
+ // To be implemented in derived classes
+
+ /**
+ * Create and connect a constraint for a scene-object.
+ */
+ virtual void ConnectConstraint() = 0;
protected:
EventToUpdate& mEventToUpdate;
Property::Index mTargetPropertyIndex;
+ SourceContainer mSources;
+ const unsigned int mSourceCount;
ProxyObject* mTargetProxy; ///< The proxy-object owns the active-constraint.
+ ProxyObjectContainer mObservedProxies; // We don't observe the same object twice
const SceneGraph::ConstraintBase* mSceneGraphConstraint;
@@ -318,8 +331,6 @@ protected:
float mOffstageWeight;
- TimePeriod mRemoveTime;
-
AlphaFunction mAlphaFunction;
RemoveAction mRemoveAction;
@@ -330,8 +341,6 @@ private:
ActiveConstraintSignalV2 mAppliedSignal;
Dali::Animation mApplyAnimation; ///< Used to automatically animate weight from 0.0f -> 1.0f
- Dali::Animation mRemoveAnimation; ///< Used to automatically animate weight back to 0.0f
-
};
diff --git a/dali/internal/event/animation/active-constraint-impl.h b/dali/internal/event/animation/active-constraint-impl.h
index 6cf822c..a0d9253 100644
--- a/dali/internal/event/animation/active-constraint-impl.h
+++ b/dali/internal/event/animation/active-constraint-impl.h
@@ -44,14 +44,11 @@ namespace Dali
namespace Internal
{
-typedef std::set ProxyObjectContainer;
-typedef ProxyObjectContainer::iterator ProxyObjectIter;
-
/**
* Connects a constraint which takes another property as an input.
*/
template < typename PropertyType >
-class ActiveConstraint : public ActiveConstraintBase, public ProxyObject::Observer
+class ActiveConstraint : public ActiveConstraintBase
{
public:
@@ -83,8 +80,6 @@ public:
*/
virtual ~ActiveConstraint()
{
- StopObservation();
-
// This is not responsible for removing constraints.
}
@@ -104,7 +99,6 @@ public:
funcPtr,
mInterpolatorFunction );
- clone->SetRemoveTime(mRemoveTime);
clone->SetAlphaFunction(mAlphaFunction);
clone->SetRemoveAction(mRemoveAction);
clone->SetTag( mTag );
@@ -112,94 +106,6 @@ public:
return clone;
}
- /**
- * @copydoc ActiveConstraintBase::OnCustomWeightSet()
- */
- virtual void OnCustomWeightSet( ProxyObject& weightObject )
- {
- ObserveProxy( weightObject );
- }
-
- /**
- * @copydoc ActiveConstraintBase::OnFirstApply()
- */
- virtual void OnFirstApply( ProxyObject& parent )
- {
- DALI_ASSERT_ALWAYS( NULL == mTargetProxy && "Parent of ActiveConstraint already set" );
-
- // No need to do anything, if the source objects are gone
- if( mSources.size() == mSourceCount )
- {
- mTargetProxy = &parent;
-
- ObserveProxy( parent );
-
- ConnectConstraint();
- }
- }
-
- /**
- * @copydoc ActiveConstraintBase::OnBeginRemove()
- */
- virtual void OnBeginRemove()
- {
- // Stop observing the remaining proxies
- StopObservation();
-
- // Discard all proxy pointers
- mSources.clear();
- }
-
- /**
- * @copydoc ProxyObject::Observer::SceneObjectAdded()
- */
- virtual void SceneObjectAdded( ProxyObject& proxy )
- {
- // Should not be getting callbacks when mSources has been cleared
- DALI_ASSERT_DEBUG( mSources.size() == mSourceCount );
-
- if ( mTargetProxy )
- {
- ConnectConstraint();
- }
- }
-
- /**
- * @copydoc ProxyObject::Observer::SceneObjectRemoved()
- */
- virtual void SceneObjectRemoved( ProxyObject& proxy )
- {
- // Notify base class that the scene-graph constraint is being removed
- OnSceneObjectRemove();
-
- if ( mSceneGraphConstraint )
- {
- // Preserve the previous weight
- mOffstageWeight = mSceneGraphConstraint->GetWeight( mEventToUpdate.GetEventBufferIndex() );
-
- // This is not responsible for removing constraints.
- mSceneGraphConstraint = NULL;
- }
- }
-
- /**
- * @copydoc ProxyObject::Observer::ProxyDestroyed()
- */
- virtual void ProxyDestroyed( ProxyObject& proxy )
- {
- // Remove proxy pointer from observation set
- ProxyObjectIter iter = mObservedProxies.find( &proxy );
- DALI_ASSERT_DEBUG( mObservedProxies.end() != iter );
- mObservedProxies.erase( iter );
-
- // Stop observing the remaining proxies
- StopObservation();
-
- // Discard all proxy pointers
- mTargetProxy = NULL;
- mSources.clear();
- }
-
private:
/**
@@ -211,31 +117,11 @@ private:
unsigned int sourceCount,
ConstraintFunctionPtr& func,
InterpolatorFunction& interpolator )
- : ActiveConstraintBase( eventToUpdate, targetIndex ),
+ : ActiveConstraintBase( eventToUpdate, targetIndex, sources, sourceCount ),
mTargetIndex( targetIndex ),
- mSources( sources ),
- mSourceCount( sourceCount ),
mUserFunction( func ),
mInterpolatorFunction( interpolator )
{
- // Skip init when any of the proxy objects have been destroyed
- if ( mSources.size() != mSourceCount )
- {
- // Discard all proxy pointers
- mTargetProxy = NULL;
- mSources.clear();
- }
-
- // Observe the objects providing properties
- for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
- {
- if ( OBJECT_PROPERTY == iter->sourceType )
- {
- DALI_ASSERT_ALWAYS( NULL != iter->object && "ActiveConstraint source object not found" );
-
- ObserveProxy( *(iter->object) );
- }
- }
}
// Undefined
@@ -245,31 +131,6 @@ private:
ActiveConstraint& operator=( const ActiveConstraint& rhs );
/**
- * Helper to observe a proxy, if not already observing it
- */
- void ObserveProxy( ProxyObject& proxy )
- {
- if ( mObservedProxies.end() == mObservedProxies.find(&proxy) )
- {
- proxy.AddObserver( *this );
- mObservedProxies.insert( &proxy );
- }
- }
-
- /**
- * Helper to stop observing proxies
- */
- void StopObservation()
- {
- for( ProxyObjectIter iter = mObservedProxies.begin(); mObservedProxies.end() != iter; ++iter )
- {
- (*iter)->RemoveObserver( *this );
- }
-
- mObservedProxies.clear();
- }
-
- /**
* Create and connect a constraint for a scene-object.
*/
void ConnectConstraint()
@@ -428,11 +289,6 @@ protected:
Property::Index mTargetIndex;
- SourceContainer mSources;
- unsigned int mSourceCount;
-
- ProxyObjectContainer mObservedProxies; // We don't observe the same object twice
-
ConstraintFunctionPtr mUserFunction;
InterpolatorFunction mInterpolatorFunction;
};
@@ -441,7 +297,7 @@ protected:
* Variant which allows float components to be animated individually.
*/
template <>
-class ActiveConstraint : public ActiveConstraintBase, public ProxyObject::Observer
+class ActiveConstraint : public ActiveConstraintBase
{
public:
@@ -471,8 +327,6 @@ public:
*/
virtual ~ActiveConstraint()
{
- StopObservation();
-
// This is not responsible for removing constraints.
}
@@ -492,7 +346,6 @@ public:
funcPtr,
mInterpolatorFunction );
- clone->SetRemoveTime(mRemoveTime);
clone->SetAlphaFunction(mAlphaFunction);
clone->SetRemoveAction(mRemoveAction);
clone->SetTag( mTag );
@@ -500,94 +353,6 @@ public:
return clone;
}
- /**
- * @copydoc ActiveConstraintBase::OnCustomWeightSet()
- */
- virtual void OnCustomWeightSet( ProxyObject& weightObject )
- {
- ObserveProxy( weightObject );
- }
-
- /**
- * @copydoc ActiveConstraintBase::OnFirstApply()
- */
- virtual void OnFirstApply( ProxyObject& parent )
- {
- DALI_ASSERT_ALWAYS( NULL == mTargetProxy && "Parent of ActiveConstraint already set" );
-
- // No need to do anything, if the source objects are gone
- if( mSources.size() == mSourceCount )
- {
- mTargetProxy = &parent;
-
- ObserveProxy( parent );
-
- ConnectConstraint();
- }
- }
-
- /**
- * @copydoc ActiveConstraintBase::OnBeginRemove()
- */
- virtual void OnBeginRemove()
- {
- // Stop observing the remaining proxies
- StopObservation();
-
- // Discard all proxy pointers
- mSources.clear();
- }
-
- /**
- * @copydoc ProxyObject::Observer::SceneObjectAdded()
- */
- virtual void SceneObjectAdded( ProxyObject& proxy )
- {
- // Should not be getting callbacks when mSources has been cleared
- DALI_ASSERT_DEBUG( mSources.size() == mSourceCount );
-
- if ( mTargetProxy )
- {
- ConnectConstraint();
- }
- }
-
- /**
- * @copydoc ProxyObject::Observer::SceneObjectRemoved()
- */
- virtual void SceneObjectRemoved( ProxyObject& proxy )
- {
- // Notify base class that the scene-graph constraint is being removed
- OnSceneObjectRemove();
-
- if ( mSceneGraphConstraint )
- {
- // Preserve the previous weight
- mOffstageWeight = mSceneGraphConstraint->GetWeight( mEventToUpdate.GetEventBufferIndex() );
-
- // This is not responsible for removing constraints.
- mSceneGraphConstraint = NULL;
- }
- }
-
- /**
- * @copydoc ProxyObject::Observer::ProxyDestroyed()
- */
- virtual void ProxyDestroyed( ProxyObject& proxy )
- {
- // Remove proxy pointer from observation set
- ProxyObjectIter iter = mObservedProxies.find( &proxy );
- DALI_ASSERT_DEBUG( mObservedProxies.end() != iter );
- mObservedProxies.erase( iter );
-
- // Stop observing the remaining proxies
- StopObservation();
-
- // Discard all proxy pointers
- mTargetProxy = NULL;
- mSources.clear();
- }
-
private:
/**
@@ -599,31 +364,11 @@ private:
unsigned int sourceCount,
ConstraintFunctionPtr& func,
InterpolatorFunction& interpolator )
- : ActiveConstraintBase( eventToUpdate, targetIndex ),
+ : ActiveConstraintBase( eventToUpdate, targetIndex, sources, sourceCount ),
mTargetIndex( targetIndex ),
- mSources( sources ),
- mSourceCount( sourceCount ),
mUserFunction( func ),
mInterpolatorFunction( interpolator )
{
- // Skip init when any of the proxy objects have been destroyed
- if ( mSources.size() != mSourceCount )
- {
- // Discard all proxy pointers
- mTargetProxy = NULL;
- mSources.clear();
- }
-
- // Observe the objects providing properties
- for ( SourceIter iter = mSources.begin(); mSources.end() != iter; ++iter )
- {
- if ( OBJECT_PROPERTY == iter->sourceType )
- {
- DALI_ASSERT_ALWAYS( NULL != iter->object && "ActiveConstraint source object not found" );
-
- ObserveProxy( *(iter->object) );
- }
- }
}
// Undefined
@@ -633,31 +378,6 @@ private:
ActiveConstraint& operator=( const ActiveConstraint& rhs );
/**
- * Helper to observe a proxy, if not already observing it
- */
- void ObserveProxy( ProxyObject& proxy )
- {
- if ( mObservedProxies.end() == mObservedProxies.find(&proxy) )
- {
- proxy.AddObserver( *this );
- mObservedProxies.insert( &proxy );
- }
- }
-
- /**
- * Helper to stop observing proxies
- */
- void StopObservation()
- {
- for( ProxyObjectIter iter = mObservedProxies.begin(); mObservedProxies.end() != iter; ++iter )
- {
- (*iter)->RemoveObserver( *this );
- }
-
- mObservedProxies.clear();
- }
-
- /**
* Create and connect a constraint for a scene-object.
*/
void ConnectConstraint()
@@ -878,11 +598,6 @@ protected:
Property::Index mTargetIndex;
- SourceContainer mSources;
- unsigned int mSourceCount;
-
- ProxyObjectContainer mObservedProxies; // We don't observe the same object twice
-
ConstraintFunctionPtr mUserFunction;
InterpolatorFunction mInterpolatorFunction;
};
diff --git a/dali/internal/event/animation/constraint-impl.cpp b/dali/internal/event/animation/constraint-impl.cpp
index c8ce5d9..1b7fc86 100644
--- a/dali/internal/event/animation/constraint-impl.cpp
+++ b/dali/internal/event/animation/constraint-impl.cpp
@@ -251,16 +251,6 @@ TimePeriod Constraint::GetApplyTime() const
return mApplyTime;
}
-void Constraint::SetRemoveTime( TimePeriod timePeriod )
-{
- GetImplementation( mActiveConstraintTemplate ).SetRemoveTime( timePeriod );
-}
-
-TimePeriod Constraint::GetRemoveTime() const
-{
- return GetImplementation( mActiveConstraintTemplate ).GetRemoveTime();
-}
-
void Constraint::SetAlphaFunction( Dali::AlphaFunction func )
{
GetImplementation( mActiveConstraintTemplate ).SetAlphaFunction( func );
diff --git a/dali/internal/event/animation/constraint-impl.h b/dali/internal/event/animation/constraint-impl.h
index 2a0fabf..1de3625 100644
--- a/dali/internal/event/animation/constraint-impl.h
+++ b/dali/internal/event/animation/constraint-impl.h
@@ -69,16 +69,6 @@ public:
TimePeriod GetApplyTime() const;
/**
- * @copydoc Dali::Constraint::SetRemoveTime()
- */
- void SetRemoveTime( TimePeriod timePeriod );
-
- /**
- * @copydoc Dali::Constraint::GetRemoveTime()
- */
- TimePeriod GetRemoveTime() const;
-
- /**
* @copydoc Dali::Constraint::SetAlphaFunction( AlphaFunction func )
*/
void SetAlphaFunction( AlphaFunction func );
diff --git a/dali/internal/event/common/proxy-object.cpp b/dali/internal/event/common/proxy-object.cpp
index 98910f5..0085d20 100644
--- a/dali/internal/event/common/proxy-object.cpp
+++ b/dali/internal/event/common/proxy-object.cpp
@@ -61,7 +61,6 @@ ProxyObject::ProxyObject()
mCustomProperties( NULL ),
mTypeInfo( NULL ),
mConstraints( NULL ),
- mRemovedConstraints( NULL ),
mPropertyNotifications( NULL )
{
}
@@ -92,6 +91,17 @@ void ProxyObject::RemoveObserver(Observer& observer)
void ProxyObject::OnSceneObjectAdd()
{
+ // Notification for this object's constraints
+ if( mConstraints )
+ {
+ const ActiveConstraintConstIter endIter = mConstraints->end();
+ for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
+ {
+ ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
+ baseConstraint.OnParentSceneObjectAdded();
+ }
+ }
+
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
{
@@ -104,6 +114,17 @@ void ProxyObject::OnSceneObjectAdd()
void ProxyObject::OnSceneObjectRemove()
{
+ // Notification for this object's constraints
+ if( mConstraints )
+ {
+ const ActiveConstraintConstIter endIter = mConstraints->end();
+ for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
+ {
+ ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
+ baseConstraint.OnParentSceneObjectRemoved();
+ }
+ }
+
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
{
@@ -781,27 +802,6 @@ ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Da
return activeConstraintImpl;
}
-void ProxyObject::DeleteRemovedConstraints()
-{
- if( ! mRemovedConstraints )
- {
- return;
- }
-
- // Discard constraints which are fully removed
- for ( ActiveConstraintIter iter = mRemovedConstraints->begin(); mRemovedConstraints->end() != iter ;)
- {
- if ( !( GetImplementation( *iter ).IsRemoving() ) )
- {
- iter = mRemovedConstraints->erase( iter );
- }
- else
- {
- ++iter;
- }
- }
-}
-
void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
{
switch ( entry.type )
@@ -940,20 +940,6 @@ void ProxyObject::RemoveConstraint( ActiveConstraint& constraint, bool isInScene
{
ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
baseConstraint.BeginRemove();
- if ( baseConstraint.IsRemoving() )
- {
- if( !mRemovedConstraints )
- {
- mRemovedConstraints = new ActiveConstraintContainer;
- }
- // Wait for remove animation before destroying active-constraints
- mRemovedConstraints->push_back( constraint );
- }
- }
- else if( mRemovedConstraints )
- {
- delete mRemovedConstraints;
- mRemovedConstraints = NULL;
}
}
}
@@ -964,10 +950,6 @@ void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
if( mConstraints && Stage::IsInstalled() )
{
bool isInSceneGraph( NULL != GetSceneObject() );
- if( isInSceneGraph )
- {
- DeleteRemovedConstraints();
- }
ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
if( it != mConstraints->end() )
@@ -984,10 +966,6 @@ void ProxyObject::RemoveConstraints( unsigned int tag )
if( mConstraints && Stage::IsInstalled() )
{
bool isInSceneGraph( NULL != GetSceneObject() );
- if( isInSceneGraph )
- {
- DeleteRemovedConstraints();
- }
ActiveConstraintIter iter( mConstraints->begin() );
while(iter != mConstraints->end() )
@@ -1013,16 +991,8 @@ void ProxyObject::RemoveConstraints()
{
// If we have nothing in the scene-graph, just clear constraint containers
const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
- if ( NULL == propertyOwner )
+ if ( NULL != propertyOwner )
{
- delete mRemovedConstraints;
- mRemovedConstraints = NULL;
- }
- else
- {
- // Discard constraints which are fully removed
- DeleteRemovedConstraints();
-
const ActiveConstraintConstIter endIter = mConstraints->end();
for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
{
@@ -1042,6 +1012,18 @@ void ProxyObject::SetTypeInfo( const TypeInfo* typeInfo )
ProxyObject::~ProxyObject()
{
+ // Notification for this object's constraints
+ // (note that the ActiveConstraint handles may outlive the ProxyObject)
+ if( mConstraints )
+ {
+ const ActiveConstraintConstIter endIter = mConstraints->end();
+ for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
+ {
+ ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
+ baseConstraint.OnParentDestroyed();
+ }
+ }
+
// Notification for observers
for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
{
@@ -1050,7 +1032,6 @@ ProxyObject::~ProxyObject()
delete mCustomProperties;
delete mConstraints;
- delete mRemovedConstraints;
delete mPropertyNotifications;
}
diff --git a/dali/internal/event/common/proxy-object.h b/dali/internal/event/common/proxy-object.h
index 14fb561..fcc658d 100644
--- a/dali/internal/event/common/proxy-object.h
+++ b/dali/internal/event/common/proxy-object.h
@@ -324,11 +324,6 @@ private:
ActiveConstraintBase* DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject );
/**
- * Helper to delete removed constraints
- */
- void DeleteRemovedConstraints();
-
- /**
* Helper to remove active constraints
*/
void RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph );
@@ -449,7 +444,6 @@ private:
Dali::Vector mObservers;
ActiveConstraintContainer* mConstraints; ///< Container of owned active-constraints.
- ActiveConstraintContainer* mRemovedConstraints; ///< Container of owned active-constraints, which are being removed.
typedef std::vector< Dali::PropertyNotification > PropertyNotificationContainer;
typedef PropertyNotificationContainer::iterator PropertyNotificationContainerIter;
diff --git a/dali/internal/update/animation/scene-graph-constraint-base.cpp b/dali/internal/update/animation/scene-graph-constraint-base.cpp
index 9e80267..19b0373 100644
--- a/dali/internal/update/animation/scene-graph-constraint-base.cpp
+++ b/dali/internal/update/animation/scene-graph-constraint-base.cpp
@@ -30,6 +30,11 @@ namespace Internal
namespace SceneGraph
{
+#ifdef DEBUG_ENABLED
+ unsigned int ConstraintBase::mCurrentInstanceCount = 0;
+ unsigned int ConstraintBase::mTotalInstanceCount = 0;
+#endif
+
ConstraintBase::ConstraintBase( PropertyOwnerSet& ownerSet )
: mWeight( Dali::ActiveConstraint::DEFAULT_WEIGHT ),
mRemoveAction( Dali::Constraint::DEFAULT_REMOVE_ACTION ),
@@ -37,6 +42,10 @@ ConstraintBase::ConstraintBase( PropertyOwnerSet& ownerSet )
mDisconnected( true ),
mObservedOwners( ownerSet )
{
+#ifdef DEBUG_ENABLED
+ ++mCurrentInstanceCount;
+ ++mTotalInstanceCount;
+#endif
}
ConstraintBase::~ConstraintBase()
@@ -46,10 +55,11 @@ ConstraintBase::~ConstraintBase()
StopObservation();
}
-// TODO - Override new & delete to provide this for everything
-#if defined(DEBUG_ENABLED) && !defined(EMSCRIPTEN)
- // Fill with garbage pattern to help detect invalid memory access
- memset ( &mWeight, 0xFA, sizeof(mWeight) );
+#ifdef DEBUG_ENABLED
+ --mCurrentInstanceCount;
+#ifndef EMSCRIPTEN
+ memset ( &mWeight, 0xFA, sizeof(mWeight) ); // Fill with garbage pattern to help detect invalid memory access
+#endif
#endif
}
@@ -59,6 +69,24 @@ void ConstraintBase::ResetDefaultProperties( BufferIndex updateBufferIndex )
DALI_ASSERT_DEBUG( false );
}
+unsigned int ConstraintBase::GetCurrentInstanceCount()
+{
+#ifdef DEBUG_ENABLED
+ return mCurrentInstanceCount;
+#else
+ return 0u;
+#endif
+}
+
+unsigned int ConstraintBase::GetTotalInstanceCount()
+{
+#ifdef DEBUG_ENABLED
+ return mTotalInstanceCount;
+#else
+ return 0u;
+#endif
+}
+
} // namespace SceneGraph
} // namespace Internal
diff --git a/dali/internal/update/animation/scene-graph-constraint-base.h b/dali/internal/update/animation/scene-graph-constraint-base.h
index 3a292c1..355b8b3 100644
--- a/dali/internal/update/animation/scene-graph-constraint-base.h
+++ b/dali/internal/update/animation/scene-graph-constraint-base.h
@@ -124,6 +124,18 @@ public:
*/
virtual void Apply( BufferIndex updateBufferIndex ) = 0;
+ /**
+ * Helper for internal test cases; only available for debug builds.
+ * @return The current number of Constraint instances in existence.
+ */
+ static unsigned int GetCurrentInstanceCount();
+
+ /**
+ * Helper for internal test cases; only available for debug builds.
+ * @return The total number of Constraint instances created during the Dali core lifetime.
+ */
+ static unsigned int GetTotalInstanceCount();
+
private:
/**
@@ -193,6 +205,11 @@ protected:
private:
PropertyOwnerSet mObservedOwners; ///< A set of pointers to each observed object. Not owned.
+
+#ifdef DEBUG_ENABLED
+ static unsigned int mCurrentInstanceCount; ///< The current number of Constraint instances in existence.
+ static unsigned int mTotalInstanceCount; ///< The total number of Constraint instances created during the Dali core lifetime.
+#endif
};
// Messages for ConstraintBase
diff --git a/dali/public-api/animation/constraint.cpp b/dali/public-api/animation/constraint.cpp
index 4b7df23..2c8cc98 100644
--- a/dali/public-api/animation/constraint.cpp
+++ b/dali/public-api/animation/constraint.cpp
@@ -72,12 +72,13 @@ TimePeriod Constraint::GetApplyTime() const
void Constraint::SetRemoveTime( TimePeriod timePeriod )
{
- GetImplementation(*this).SetRemoveTime( timePeriod );
+ // TODO - Remove this deprecated method
}
TimePeriod Constraint::GetRemoveTime() const
{
- return GetImplementation(*this).GetRemoveTime();
+ // TODO - Remove this deprecated method
+ return TimePeriod(0.0f);
}
void Constraint::SetAlphaFunction( AlphaFunction func )
diff --git a/dali/public-api/animation/constraint.h b/dali/public-api/animation/constraint.h
index c5cfe90..583fe43 100644
--- a/dali/public-api/animation/constraint.h
+++ b/dali/public-api/animation/constraint.h
@@ -563,17 +563,12 @@ public:
TimePeriod GetApplyTime() const;
/**
- * @brief Set the time taken for the constraint to be fully removed.
- *
- * The default is zero, meaning that the constraint is removed immediately.
- * @param [in] timePeriod The constraint will be removed during this time period.
+ * @deprecated Use animation API directly instead.
*/
void SetRemoveTime( TimePeriod timePeriod );
/**
- * @brief Retrieve the time taken for the constraint to be fully removed.
- *
- * @return The remove time.
+ * @deprecated Use animation API directly instead.
*/
TimePeriod GetRemoveTime() const;
--
2.7.4