#ifndef __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
#define __DALI_INTERNAL_ACTIVE_CONSTRAINT_H__
-//
-// Copyright (c) 2014 Samsung Electronics Co., Ltd.
-//
-// Licensed under the Flora License, Version 1.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://floralicense.org/license/
-//
-// 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.
-//
+/*
+ * 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.
+ *
+ */
// EXTERNAL INCLUDES
#include <boost/function.hpp>
// INTERNAL INCLUDES
-#include <dali/public-api/common/set-wrapper.h>
#include <dali/internal/common/event-to-update.h>
#include <dali/internal/common/message.h>
#include <dali/internal/event/common/proxy-object.h>
namespace Internal
{
-typedef std::set<ProxyObject*> ProxyObjectContainer;
-typedef ProxyObjectContainer::iterator ProxyObjectIter;
+/**
+ * Helper to add only unique entries to the propertyOwner container
+ * @param propertyOwners to add the entries to
+ * @param object to add
+ */
+inline void AddUnique( SceneGraph::PropertyOwnerContainer& propertyOwners, SceneGraph::PropertyOwner* object )
+{
+ const SceneGraph::PropertyOwnerIter iter = std::find( propertyOwners.Begin(), propertyOwners.End(), object );
+ if( iter == propertyOwners.End() )
+ {
+ // each owner should only be added once
+ propertyOwners.PushBack( object );
+ }
+}
/**
* 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:
*/
virtual ~ActiveConstraint()
{
- StopObservation();
-
// This is not responsible for removing constraints.
}
funcPtr,
mInterpolatorFunction );
- clone->SetRemoveTime(mRemoveTime);
clone->SetAlphaFunction(mAlphaFunction);
clone->SetRemoveAction(mRemoveAction);
clone->SetTag( mTag );
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:
/**
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
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()
return;
}
- // Build a set of property-owners, providing the scene-graph properties
- SceneGraph::PropertyOwnerSet propertyOwners;
- propertyOwners.insert( targetObject );
+ // Build a container of property-owners, providing the scene-graph properties
+ SceneGraph::PropertyOwnerContainer propertyOwners;
+ propertyOwners.PushBack( targetObject );
// Build the constraint function; this requires a scene-graph property from each source
ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
/**
* Helper for ConnectConstraint. Creates a connected constraint-function.
- * Also populates the property-owner set, for each input connected to the constraint-function.
- * @param[out] propertyOwners The set of property-owners providing the scene-graph properties.
+ * Also populates the property-owner container, for each input connected to the constraint-function.
+ * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
* @return A connected constraint-function, or NULL if the scene-graph properties are not available.
*/
- PropertyConstraintBase<PropertyType>* ConnectConstraintFunction( SceneGraph::PropertyOwnerSet& propertyOwners )
+ PropertyConstraintBase<PropertyType>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
{
PropertyConstraintBase<PropertyType>* func = mUserFunction->Clone();
bool usingComponentFunc( false );
// The property owner will not exist, if the target proxy-object is off-stage
if( NULL != owner )
{
- propertyOwners.insert( owner );
+ AddUnique( propertyOwners, owner );
inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
// The property owner will not exist, if the parent proxy-object is off-stage
if ( NULL != owner )
{
- propertyOwners.insert( owner );
+ AddUnique( propertyOwners, owner );
inputProperty = const_cast< PropertyInputImpl* >( proxyParent->GetSceneObjectInputProperty( source.propertyIndex ) );
componentIndex = proxyParent->GetPropertyComponentIndex( source.propertyIndex );
Property::Index mTargetIndex;
- SourceContainer mSources;
- unsigned int mSourceCount;
-
- ProxyObjectContainer mObservedProxies; // We don't observe the same object twice
-
ConstraintFunctionPtr mUserFunction;
InterpolatorFunction mInterpolatorFunction;
};
* Variant which allows float components to be animated individually.
*/
template <>
-class ActiveConstraint<float> : public ActiveConstraintBase, public ProxyObject::Observer
+class ActiveConstraint<float> : public ActiveConstraintBase
{
public:
*/
virtual ~ActiveConstraint()
{
- StopObservation();
-
// This is not responsible for removing constraints.
}
funcPtr,
mInterpolatorFunction );
- clone->SetRemoveTime(mRemoveTime);
clone->SetAlphaFunction(mAlphaFunction);
clone->SetRemoveAction(mRemoveAction);
clone->SetTag( mTag );
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:
/**
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
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()
return;
}
- // Build a set of property-owners, providing the scene-graph properties
- SceneGraph::PropertyOwnerSet propertyOwners;
- propertyOwners.insert( targetObject );
+ // Build a container of property-owners, providing the scene-graph properties
+ SceneGraph::PropertyOwnerContainer propertyOwners;
+ propertyOwners.PushBack( targetObject );
// Build the constraint function; this requires a scene-graph property from each source
ConstraintFunctionPtr func( ConnectConstraintFunction( propertyOwners ) );
/**
* Helper for ConnectConstraint. Creates a connected constraint-function.
- * Also populates the property-owner set, for each input connected to the constraint-function.
- * @param[out] propertyOwners The set of property-owners providing the scene-graph properties.
+ * Also populates the property-owner container, for each input connected to the constraint-function.
+ * @param[out] propertyOwners The container of property-owners providing the scene-graph properties.
* @return A connected constraint-function, or NULL if the scene-graph properties are not available.
*/
- PropertyConstraintBase<float>* ConnectConstraintFunction( SceneGraph::PropertyOwnerSet& propertyOwners )
+ PropertyConstraintBase<float>* ConnectConstraintFunction( SceneGraph::PropertyOwnerContainer& propertyOwners )
{
PropertyConstraintBase<float>* func = mUserFunction->Clone();
bool usingComponentFunc( false );
// The property owner will not exist, if the target proxy-object is off-stage
if( NULL != owner )
{
- propertyOwners.insert( owner );
+ AddUnique( propertyOwners, owner );
inputProperty = const_cast< PropertyInputImpl* >( source.object->GetSceneObjectInputProperty( source.propertyIndex ) );
componentIndex = source.object->GetPropertyComponentIndex( source.propertyIndex );
// The property owner will not exist, if the parent proxy-object is off-stage
if ( NULL != owner )
{
- propertyOwners.insert( owner );
+ AddUnique( propertyOwners, owner );
inputProperty = const_cast< PropertyInputImpl* >( proxyParent->GetSceneObjectInputProperty( source.propertyIndex ) );
componentIndex = proxyParent->GetPropertyComponentIndex( source.propertyIndex );
Property::Index mTargetIndex;
- SourceContainer mSources;
- unsigned int mSourceCount;
-
- ProxyObjectContainer mObservedProxies; // We don't observe the same object twice
-
ConstraintFunctionPtr mUserFunction;
InterpolatorFunction mInterpolatorFunction;
};