2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/common/proxy-object.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
27 #include <dali/internal/update/common/animatable-property.h>
28 #include <dali/internal/update/common/property-owner-messages.h>
29 #include <dali/internal/event/animation/active-constraint-base.h>
30 #include <dali/internal/event/animation/constraint-impl.h>
31 #include <dali/internal/event/common/stage-impl.h>
32 #include <dali/internal/event/common/property-notification-impl.h>
33 #include <dali/internal/event/common/property-index-ranges.h>
34 #include <dali/internal/event/common/type-registry-impl.h>
36 using Dali::Internal::SceneGraph::AnimatableProperty;
37 using Dali::Internal::SceneGraph::PropertyBase;
45 namespace // unnamed namespace
47 const int SUPPORTED_CAPABILITIES = Dali::Handle::DYNAMIC_PROPERTIES; // ProxyObject provides this capability
48 typedef Dali::Vector<ProxyObject::Observer*>::Iterator ObserverIter;
49 typedef Dali::Vector<ProxyObject::Observer*>::ConstIterator ConstObserverIter;
51 #if defined(DEBUG_ENABLED)
52 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PROXY_OBJECT" );
54 } // unnamed namespace
56 ProxyObject::ProxyObject()
59 mPropertyNotifications( NULL )
63 void ProxyObject::AddObserver(Observer& observer)
65 // make sure an observer doesn't observe the same object twice
66 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ProxyDestroyed()
67 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
69 mObservers.PushBack( &observer );
72 void ProxyObject::RemoveObserver(Observer& observer)
74 // Find the observer...
75 const ConstObserverIter endIter = mObservers.End();
76 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
78 if( (*iter) == &observer)
80 mObservers.Erase( iter );
84 DALI_ASSERT_DEBUG(endIter != mObservers.End());
87 void ProxyObject::OnSceneObjectAdd()
89 // Notification for this object's constraints
92 const ActiveConstraintConstIter endIter = mConstraints->end();
93 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
95 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
96 baseConstraint.OnParentSceneObjectAdded();
100 // Notification for observers
101 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
103 (*iter)->SceneObjectAdded(*this);
106 // enable property notifications in scene graph
107 EnablePropertyNotifications();
110 void ProxyObject::OnSceneObjectRemove()
112 // Notification for this object's constraints
115 const ActiveConstraintConstIter endIter = mConstraints->end();
116 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
118 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
119 baseConstraint.OnParentSceneObjectRemoved();
123 // Notification for observers
124 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
126 (*iter)->SceneObjectRemoved(*this);
129 // disable property notifications in scene graph
130 DisablePropertyNotifications();
133 int ProxyObject::GetPropertyComponentIndex( Property::Index index ) const
135 return Property::INVALID_COMPONENT_INDEX;
138 bool ProxyObject::Supports( Capability capability ) const
140 return (capability & SUPPORTED_CAPABILITIES);
143 unsigned int ProxyObject::GetPropertyCount() const
145 unsigned int count = GetDefaultPropertyCount();
147 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
149 const TypeInfo* typeInfo( GetTypeInfo() );
152 unsigned int manual( typeInfo->GetPropertyCount() );
155 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
158 unsigned int custom( mCustomProperties.Count() );
160 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
162 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
167 std::string ProxyObject::GetPropertyName( Property::Index index ) const
169 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
171 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
173 return GetDefaultPropertyName( index );
176 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
178 const TypeInfo* typeInfo( GetTypeInfo() );
181 return typeInfo->GetPropertyName( index );
185 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
189 CustomProperty* custom = FindCustomProperty( index );
197 Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
199 Property::Index index = GetDefaultPropertyIndex( name );
201 if ( index == Property::INVALID_INDEX )
203 const TypeInfo* typeInfo( GetTypeInfo() );
206 index = typeInfo->GetPropertyIndex( name );
210 if( ( index == Property::INVALID_INDEX )&&( mCustomProperties.Count() > 0 ) )
212 Property::Index count = PROPERTY_CUSTOM_START_INDEX;
213 const CustomPropertyLookup::ConstIterator end = mCustomProperties.End();
214 for( CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
216 CustomProperty* custom = *iter;
217 if ( custom->name == name )
228 bool ProxyObject::IsPropertyWritable( Property::Index index ) const
230 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
232 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
234 return IsDefaultPropertyWritable( index );
237 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
239 const TypeInfo* typeInfo( GetTypeInfo() );
242 return typeInfo->IsPropertyWritable( index );
246 DALI_ASSERT_ALWAYS( ! "Invalid property index" );
250 CustomProperty* custom = FindCustomProperty( index );
253 return custom->IsWritable();
258 bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
260 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
262 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
264 return IsDefaultPropertyAnimatable( index );
267 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
269 // Type Registry event-thread only properties are not animatable.
273 CustomProperty* custom = FindCustomProperty( index );
276 return custom->IsAnimatable();
281 bool ProxyObject::IsPropertyAConstraintInput( Property::Index index ) const
283 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
285 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
287 return IsDefaultPropertyAConstraintInput( index );
290 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
292 // Type Registry event-thread only properties cannot be used as an input to a constraint.
296 CustomProperty* custom = FindCustomProperty( index );
299 // ... custom properties can be used as input to a constraint.
305 Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
307 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
309 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
311 return GetDefaultPropertyType( index );
314 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
316 const TypeInfo* typeInfo( GetTypeInfo() );
319 return typeInfo->GetPropertyType( index );
323 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
327 CustomProperty* custom = FindCustomProperty( index );
332 return Property::NONE;
335 void ProxyObject::SetProperty( Property::Index index, const Property::Value& propertyValue )
337 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
339 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
341 SetDefaultProperty( index, propertyValue );
343 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
345 const TypeInfo* typeInfo( GetTypeInfo() );
348 typeInfo->SetProperty( this, index, propertyValue );
352 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
357 CustomProperty* custom = FindCustomProperty( index );
358 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
359 if( custom->IsAnimatable() )
361 // set the scene graph property value
362 SetSceneGraphProperty( index, *custom, propertyValue );
364 else if( custom->IsWritable() )
366 custom->value = propertyValue;
367 OnPropertySet(index, propertyValue);
369 // trying to set value on read only property is no-op
373 Property::Value ProxyObject::GetProperty(Property::Index index) const
375 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
377 Property::Value value;
379 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
381 value = GetDefaultProperty( index );
383 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
385 const TypeInfo* typeInfo( GetTypeInfo() );
388 value = typeInfo->GetProperty( this, index );
392 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
395 else if( mCustomProperties.Count() > 0 )
397 CustomProperty* custom = FindCustomProperty( index );
398 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
400 if( !custom->IsAnimatable() )
402 value = custom->value;
406 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
408 switch ( custom->type )
410 case Property::BOOLEAN:
412 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( custom->GetSceneGraphProperty() );
413 DALI_ASSERT_DEBUG( NULL != property );
415 value = (*property)[ bufferIndex ];
419 case Property::FLOAT:
421 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( custom->GetSceneGraphProperty() );
422 DALI_ASSERT_DEBUG( NULL != property );
424 value = (*property)[ bufferIndex ];
428 case Property::INTEGER:
430 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( custom->GetSceneGraphProperty() );
431 DALI_ASSERT_DEBUG( NULL != property );
433 value = (*property)[ bufferIndex ];
437 case Property::VECTOR2:
439 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( custom->GetSceneGraphProperty() );
440 DALI_ASSERT_DEBUG( NULL != property );
442 value = (*property)[ bufferIndex ];
446 case Property::VECTOR3:
448 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( custom->GetSceneGraphProperty() );
449 DALI_ASSERT_DEBUG( NULL != property );
451 value = (*property)[ bufferIndex ];
455 case Property::VECTOR4:
457 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( custom->GetSceneGraphProperty() );
458 DALI_ASSERT_DEBUG( NULL != property );
460 value = (*property)[ bufferIndex ];
464 case Property::MATRIX:
466 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( custom->GetSceneGraphProperty() );
467 DALI_ASSERT_DEBUG( NULL != property );
469 value = (*property)[ bufferIndex ];
473 case Property::MATRIX3:
475 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( custom->GetSceneGraphProperty() );
476 DALI_ASSERT_DEBUG( NULL != property );
478 value = (*property)[ bufferIndex ];
482 case Property::ROTATION:
484 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( custom->GetSceneGraphProperty() );
485 DALI_ASSERT_DEBUG( NULL != property );
487 value = (*property)[ bufferIndex ];
493 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
504 void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
508 // Default Properties
509 GetDefaultPropertyIndices( indices );
512 const TypeInfo* typeInfo( GetTypeInfo() );
515 typeInfo->GetPropertyIndices( indices );
519 if ( mCustomProperties.Count() > 0 )
521 indices.reserve( indices.size() + mCustomProperties.Count() );
523 CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin();
524 const CustomPropertyLookup::ConstIterator endIter = mCustomProperties.End();
526 for ( ; iter != endIter; ++iter, ++i )
528 indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
533 Property::Index ProxyObject::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
535 // Create a new property
536 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
538 switch ( propertyValue.GetType() )
540 case Property::BOOLEAN:
542 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
546 case Property::FLOAT:
548 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
552 case Property::INTEGER:
554 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
558 case Property::VECTOR2:
560 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
564 case Property::VECTOR3:
566 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
570 case Property::VECTOR4:
572 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
576 case Property::MATRIX:
578 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
582 case Property::MATRIX3:
584 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
588 case Property::ROTATION:
590 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
594 case Property::UNSIGNED_INTEGER:
595 case Property::RECTANGLE:
596 case Property::STRING:
597 case Property::ARRAY:
600 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
601 DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
607 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
608 DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
613 // get the scene property owner from derived class
614 const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
615 Property::Index index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
616 // we can only pass properties to scene graph side if there is a scene object
617 if( scenePropertyOwner )
619 // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
620 const PropertyBase* property = newProperty.Get();
621 mCustomProperties.PushBack( new CustomProperty( name, propertyValue.GetType(), property ) );
623 // queue a message to add the property
624 InstallCustomPropertyMessage( Stage::GetCurrent()->GetUpdateInterface(), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
626 // notify the derived class (optional) method in case it needs to do some more work on the new property
627 // note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
628 NotifyScenePropertyInstalled( *property, name, index );
632 // property was orphaned and killed so return invalid index
633 index = Property::INVALID_INDEX;
639 Property::Index ProxyObject::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
641 Property::Index index = Property::INVALID_INDEX;
643 if(Property::ANIMATABLE == accessMode)
645 index = RegisterProperty(name, propertyValue);
649 // Add entry to the property lookup
650 index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
651 mCustomProperties.PushBack( new CustomProperty( name, propertyValue, accessMode ) );
657 Dali::PropertyNotification ProxyObject::AddPropertyNotification(Property::Index index,
659 const Dali::PropertyCondition& condition)
661 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
663 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
665 DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
667 else if ( mCustomProperties.Count() > 0 )
669 CustomProperty* custom = FindCustomProperty( index );
670 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
671 DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
675 Dali::Handle self(this);
676 Property target( self, index );
678 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
679 Dali::PropertyNotification propertyNotification(internal.Get());
681 if( !mPropertyNotifications )
683 mPropertyNotifications = new PropertyNotificationContainer;
685 mPropertyNotifications->push_back(propertyNotification);
687 return propertyNotification;
690 void ProxyObject::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
692 if( mPropertyNotifications )
694 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
695 while(iter != mPropertyNotifications->end() )
697 if(*iter == propertyNotification)
699 mPropertyNotifications->erase(iter);
700 // As we can't ensure all references are removed, we can just disable
702 GetImplementation(propertyNotification).Disable();
710 void ProxyObject::RemovePropertyNotifications()
712 if( mPropertyNotifications )
714 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
715 while(iter != mPropertyNotifications->end() )
717 // As we can't ensure all references are removed, we can just disable
719 GetImplementation(*iter).Disable();
723 mPropertyNotifications->clear();
727 void ProxyObject::EnablePropertyNotifications()
729 if( mPropertyNotifications )
731 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
732 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
734 for( ; iter != endIter; ++iter )
736 GetImplementation(*iter).Enable();
741 void ProxyObject::DisablePropertyNotifications()
743 if( mPropertyNotifications )
745 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
746 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
748 for( ; iter != endIter; ++iter )
750 GetImplementation(*iter).Disable();
755 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint )
757 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Constrainable() ) );
760 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
762 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
765 ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
767 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
768 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
770 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
774 ProxyObject& weightObjectImpl = GetImplementation( weightObject );
775 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
777 if( Property::INVALID_INDEX != weightIndex )
779 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
785 mConstraints = new ActiveConstraintContainer;
787 mConstraints->push_back( activeConstraint );
789 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
791 return activeConstraintImpl;
794 void ProxyObject::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
796 switch ( entry.type )
798 case Property::BOOLEAN:
800 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
801 DALI_ASSERT_DEBUG( NULL != property );
803 // property is being used in a separate thread; queue a message to set the property
804 BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
808 case Property::FLOAT:
810 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
811 DALI_ASSERT_DEBUG( NULL != property );
813 // property is being used in a separate thread; queue a message to set the property
814 BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
818 case Property::INTEGER:
820 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
821 DALI_ASSERT_DEBUG( NULL != property );
823 // property is being used in a separate thread; queue a message to set the property
824 BakeMessage<int>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<int>() );
828 case Property::VECTOR2:
830 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
831 DALI_ASSERT_DEBUG( NULL != property );
833 // property is being used in a separate thread; queue a message to set the property
834 BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
838 case Property::VECTOR3:
840 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
841 DALI_ASSERT_DEBUG( NULL != property );
843 // property is being used in a separate thread; queue a message to set the property
844 BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
848 case Property::VECTOR4:
850 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
851 DALI_ASSERT_DEBUG( NULL != property );
853 // property is being used in a separate thread; queue a message to set the property
854 BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
858 case Property::ROTATION:
860 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
861 DALI_ASSERT_DEBUG( NULL != property );
863 // property is being used in a separate thread; queue a message to set the property
864 BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
868 case Property::MATRIX:
870 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
871 DALI_ASSERT_DEBUG( NULL != property );
873 // property is being used in a separate thread; queue a message to set the property
874 BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
878 case Property::MATRIX3:
880 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
881 DALI_ASSERT_DEBUG( NULL != property );
883 // property is being used in a separate thread; queue a message to set the property
884 BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
890 // non-animatable scene graph property, do nothing
895 const TypeInfo* ProxyObject::GetTypeInfo() const
899 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
900 // especially as the type-info does not change during the life-time of an application
902 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
903 if ( typeInfoHandle )
905 mTypeInfo = &GetImplementation( typeInfoHandle );
912 void ProxyObject::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
914 // guard against constraint sending messages during core destruction
915 if ( Stage::IsInstalled() )
919 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
920 baseConstraint.BeginRemove();
925 void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
927 // guard against constraint sending messages during core destruction
928 if( mConstraints && Stage::IsInstalled() )
930 bool isInSceneGraph( NULL != GetSceneObject() );
932 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
933 if( it != mConstraints->end() )
935 RemoveConstraint( *it, isInSceneGraph );
936 mConstraints->erase( it );
941 void ProxyObject::RemoveConstraints( unsigned int tag )
943 // guard against constraint sending messages during core destruction
944 if( mConstraints && Stage::IsInstalled() )
946 bool isInSceneGraph( NULL != GetSceneObject() );
948 ActiveConstraintIter iter( mConstraints->begin() );
949 while(iter != mConstraints->end() )
951 ActiveConstraintBase& constraint = GetImplementation( *iter );
952 if( constraint.GetTag() == tag )
954 RemoveConstraint( *iter, isInSceneGraph );
955 iter = mConstraints->erase( iter );
965 void ProxyObject::RemoveConstraints()
967 // guard against constraint sending messages during core destruction
968 if( mConstraints && Stage::IsInstalled() )
970 // If we have nothing in the scene-graph, just clear constraint containers
971 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
972 if ( NULL != propertyOwner )
974 const ActiveConstraintConstIter endIter = mConstraints->end();
975 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
977 RemoveConstraint( *iter, true );
986 void ProxyObject::SetTypeInfo( const TypeInfo* typeInfo )
988 mTypeInfo = typeInfo;
991 ProxyObject::~ProxyObject()
993 // Notification for this object's constraints
994 // (note that the ActiveConstraint handles may outlive the ProxyObject)
997 const ActiveConstraintConstIter endIter = mConstraints->end();
998 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1000 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
1001 baseConstraint.OnParentDestroyed();
1005 // Notification for observers
1006 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1008 (*iter)->ProxyDestroyed(*this);
1011 delete mConstraints;
1012 delete mPropertyNotifications;
1015 CustomProperty* ProxyObject::FindCustomProperty( Property::Index index ) const
1017 CustomProperty* property( NULL );
1018 int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
1019 if( arrayIndex >= 0 )
1021 if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
1023 property = mCustomProperties[ arrayIndex ];
1029 } // namespace Internal