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/object-impl.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/type-registry-impl.h>
35 using Dali::Internal::SceneGraph::AnimatableProperty;
36 using Dali::Internal::SceneGraph::PropertyBase;
44 namespace // unnamed namespace
46 const int SUPPORTED_CAPABILITIES = Dali::Handle::DYNAMIC_PROPERTIES; // Object provides this capability
47 typedef Dali::Vector<Object::Observer*>::Iterator ObserverIter;
48 typedef Dali::Vector<Object::Observer*>::ConstIterator ConstObserverIter;
50 #if defined(DEBUG_ENABLED)
51 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_OBJECT" );
53 } // unnamed namespace
58 mPropertyNotifications( NULL )
62 void Object::AddObserver(Observer& observer)
64 // make sure an observer doesn't observe the same object twice
65 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ObjectDestroyed()
66 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
68 mObservers.PushBack( &observer );
71 void Object::RemoveObserver(Observer& observer)
73 // Find the observer...
74 const ConstObserverIter endIter = mObservers.End();
75 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
77 if( (*iter) == &observer)
79 mObservers.Erase( iter );
83 DALI_ASSERT_DEBUG(endIter != mObservers.End());
86 void Object::OnSceneObjectAdd()
88 // Notification for this object's constraints
91 const ActiveConstraintConstIter endIter = mConstraints->end();
92 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
94 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
95 baseConstraint.OnParentSceneObjectAdded();
99 // Notification for observers
100 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
102 (*iter)->SceneObjectAdded(*this);
105 // enable property notifications in scene graph
106 EnablePropertyNotifications();
109 void Object::OnSceneObjectRemove()
111 // Notification for this object's constraints
114 const ActiveConstraintConstIter endIter = mConstraints->end();
115 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
117 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
118 baseConstraint.OnParentSceneObjectRemoved();
122 // Notification for observers
123 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
125 (*iter)->SceneObjectRemoved(*this);
128 // disable property notifications in scene graph
129 DisablePropertyNotifications();
132 int Object::GetPropertyComponentIndex( Property::Index index ) const
134 return Property::INVALID_COMPONENT_INDEX;
137 bool Object::Supports( Capability capability ) const
139 return (capability & SUPPORTED_CAPABILITIES);
142 unsigned int Object::GetPropertyCount() const
144 unsigned int count = GetDefaultPropertyCount();
146 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
148 const TypeInfo* typeInfo( GetTypeInfo() );
151 unsigned int manual( typeInfo->GetPropertyCount() );
154 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
157 unsigned int custom( mCustomProperties.Count() );
159 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
161 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
166 std::string Object::GetPropertyName( Property::Index index ) const
168 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
170 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
172 return GetDefaultPropertyName( index );
175 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
177 const TypeInfo* typeInfo( GetTypeInfo() );
180 return typeInfo->GetPropertyName( index );
184 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
188 CustomProperty* custom = FindCustomProperty( index );
196 Property::Index Object::GetPropertyIndex(const std::string& name) const
198 Property::Index index = GetDefaultPropertyIndex( name );
200 if ( index == Property::INVALID_INDEX )
202 const TypeInfo* typeInfo( GetTypeInfo() );
205 index = typeInfo->GetPropertyIndex( name );
209 if( ( index == Property::INVALID_INDEX )&&( mCustomProperties.Count() > 0 ) )
211 Property::Index count = PROPERTY_CUSTOM_START_INDEX;
212 const CustomPropertyLookup::ConstIterator end = mCustomProperties.End();
213 for( CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
215 CustomProperty* custom = *iter;
216 if ( custom->name == name )
227 bool Object::IsPropertyWritable( Property::Index index ) const
229 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
231 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
233 return IsDefaultPropertyWritable( index );
236 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
238 const TypeInfo* typeInfo( GetTypeInfo() );
241 return typeInfo->IsPropertyWritable( index );
245 DALI_ASSERT_ALWAYS( ! "Invalid property index" );
249 CustomProperty* custom = FindCustomProperty( index );
252 return custom->IsWritable();
257 bool Object::IsPropertyAnimatable( Property::Index index ) const
259 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
261 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
263 return IsDefaultPropertyAnimatable( index );
266 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
268 // Type Registry event-thread only properties are not animatable.
272 CustomProperty* custom = FindCustomProperty( index );
275 return custom->IsAnimatable();
280 bool Object::IsPropertyAConstraintInput( Property::Index index ) const
282 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
284 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
286 return IsDefaultPropertyAConstraintInput( index );
289 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
291 // Type Registry event-thread only properties cannot be used as an input to a constraint.
295 CustomProperty* custom = FindCustomProperty( index );
298 // ... custom properties can be used as input to a constraint.
304 Property::Type Object::GetPropertyType( Property::Index index ) const
306 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
308 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
310 return GetDefaultPropertyType( index );
313 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
315 const TypeInfo* typeInfo( GetTypeInfo() );
318 return typeInfo->GetPropertyType( index );
322 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
326 CustomProperty* custom = FindCustomProperty( index );
331 return Property::NONE;
334 void Object::SetProperty( Property::Index index, const Property::Value& propertyValue )
336 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
338 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
340 SetDefaultProperty( index, propertyValue );
342 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
344 const TypeInfo* typeInfo( GetTypeInfo() );
347 typeInfo->SetProperty( this, index, propertyValue );
351 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
356 CustomProperty* custom = FindCustomProperty( index );
357 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
358 if( custom->IsAnimatable() )
360 // set the scene graph property value
361 SetSceneGraphProperty( index, *custom, propertyValue );
363 else if( custom->IsWritable() )
365 custom->value = propertyValue;
366 OnPropertySet(index, propertyValue);
368 // trying to set value on read only property is no-op
372 Property::Value Object::GetProperty(Property::Index index) const
374 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
376 Property::Value value;
378 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
380 value = GetDefaultProperty( index );
382 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
384 const TypeInfo* typeInfo( GetTypeInfo() );
387 value = typeInfo->GetProperty( this, index );
391 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
394 else if( mCustomProperties.Count() > 0 )
396 CustomProperty* custom = FindCustomProperty( index );
397 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
399 if( !custom->IsAnimatable() )
401 value = custom->value;
405 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
407 switch ( custom->type )
409 case Property::BOOLEAN:
411 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( custom->GetSceneGraphProperty() );
412 DALI_ASSERT_DEBUG( NULL != property );
414 value = (*property)[ bufferIndex ];
418 case Property::FLOAT:
420 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( custom->GetSceneGraphProperty() );
421 DALI_ASSERT_DEBUG( NULL != property );
423 value = (*property)[ bufferIndex ];
427 case Property::INTEGER:
429 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( custom->GetSceneGraphProperty() );
430 DALI_ASSERT_DEBUG( NULL != property );
432 value = (*property)[ bufferIndex ];
436 case Property::VECTOR2:
438 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( custom->GetSceneGraphProperty() );
439 DALI_ASSERT_DEBUG( NULL != property );
441 value = (*property)[ bufferIndex ];
445 case Property::VECTOR3:
447 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( custom->GetSceneGraphProperty() );
448 DALI_ASSERT_DEBUG( NULL != property );
450 value = (*property)[ bufferIndex ];
454 case Property::VECTOR4:
456 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( custom->GetSceneGraphProperty() );
457 DALI_ASSERT_DEBUG( NULL != property );
459 value = (*property)[ bufferIndex ];
463 case Property::MATRIX:
465 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( custom->GetSceneGraphProperty() );
466 DALI_ASSERT_DEBUG( NULL != property );
468 value = (*property)[ bufferIndex ];
472 case Property::MATRIX3:
474 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( custom->GetSceneGraphProperty() );
475 DALI_ASSERT_DEBUG( NULL != property );
477 value = (*property)[ bufferIndex ];
481 case Property::ROTATION:
483 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( custom->GetSceneGraphProperty() );
484 DALI_ASSERT_DEBUG( NULL != property );
486 value = (*property)[ bufferIndex ];
492 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
503 void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
507 // Default Properties
508 GetDefaultPropertyIndices( indices );
511 const TypeInfo* typeInfo( GetTypeInfo() );
514 typeInfo->GetPropertyIndices( indices );
518 if ( mCustomProperties.Count() > 0 )
520 indices.reserve( indices.size() + mCustomProperties.Count() );
522 CustomPropertyLookup::ConstIterator iter = mCustomProperties.Begin();
523 const CustomPropertyLookup::ConstIterator endIter = mCustomProperties.End();
525 for ( ; iter != endIter; ++iter, ++i )
527 indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
532 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
534 // Create a new property
535 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
537 switch ( propertyValue.GetType() )
539 case Property::BOOLEAN:
541 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
545 case Property::FLOAT:
547 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
551 case Property::INTEGER:
553 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
557 case Property::VECTOR2:
559 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
563 case Property::VECTOR3:
565 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
569 case Property::VECTOR4:
571 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
575 case Property::MATRIX:
577 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
581 case Property::MATRIX3:
583 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
587 case Property::ROTATION:
589 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
593 case Property::UNSIGNED_INTEGER:
594 case Property::RECTANGLE:
595 case Property::STRING:
596 case Property::ARRAY:
599 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
600 DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
606 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
607 DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
612 // get the scene property owner from derived class
613 const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
614 Property::Index index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
615 // we can only pass properties to scene graph side if there is a scene object
616 if( scenePropertyOwner )
618 // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
619 const PropertyBase* property = newProperty.Get();
620 mCustomProperties.PushBack( new CustomProperty( name, propertyValue.GetType(), property ) );
622 // queue a message to add the property
623 InstallCustomPropertyMessage( Stage::GetCurrent()->GetUpdateInterface(), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
625 // notify the derived class (optional) method in case it needs to do some more work on the new property
626 // note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
627 NotifyScenePropertyInstalled( *property, name, index );
631 // property was orphaned and killed so return invalid index
632 index = Property::INVALID_INDEX;
638 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
640 Property::Index index = Property::INVALID_INDEX;
642 if(Property::ANIMATABLE == accessMode)
644 index = RegisterProperty(name, propertyValue);
648 // Add entry to the property lookup
649 index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
650 mCustomProperties.PushBack( new CustomProperty( name, propertyValue, accessMode ) );
656 Dali::PropertyNotification Object::AddPropertyNotification(Property::Index index,
658 const Dali::PropertyCondition& condition)
660 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
662 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
664 DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
666 else if ( mCustomProperties.Count() > 0 )
668 CustomProperty* custom = FindCustomProperty( index );
669 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
670 DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
674 Dali::Handle self(this);
675 Property target( self, index );
677 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
678 Dali::PropertyNotification propertyNotification(internal.Get());
680 if( !mPropertyNotifications )
682 mPropertyNotifications = new PropertyNotificationContainer;
684 mPropertyNotifications->push_back(propertyNotification);
686 return propertyNotification;
689 void Object::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
691 if( mPropertyNotifications )
693 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
694 while(iter != mPropertyNotifications->end() )
696 if(*iter == propertyNotification)
698 mPropertyNotifications->erase(iter);
699 // As we can't ensure all references are removed, we can just disable
701 GetImplementation(propertyNotification).Disable();
709 void Object::RemovePropertyNotifications()
711 if( mPropertyNotifications )
713 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
714 while(iter != mPropertyNotifications->end() )
716 // As we can't ensure all references are removed, we can just disable
718 GetImplementation(*iter).Disable();
722 mPropertyNotifications->clear();
726 void Object::EnablePropertyNotifications()
728 if( mPropertyNotifications )
730 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
731 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
733 for( ; iter != endIter; ++iter )
735 GetImplementation(*iter).Enable();
740 void Object::DisablePropertyNotifications()
742 if( mPropertyNotifications )
744 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
745 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
747 for( ; iter != endIter; ++iter )
749 GetImplementation(*iter).Disable();
754 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint )
756 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Handle() ) );
759 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
761 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
764 ActiveConstraintBase* Object::DoApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
766 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
767 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
769 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
773 Object& weightObjectImpl = GetImplementation( weightObject );
774 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
776 if( Property::INVALID_INDEX != weightIndex )
778 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
784 mConstraints = new ActiveConstraintContainer;
786 mConstraints->push_back( activeConstraint );
788 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
790 return activeConstraintImpl;
793 void Object::SetSceneGraphProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
795 switch ( entry.type )
797 case Property::BOOLEAN:
799 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
800 DALI_ASSERT_DEBUG( NULL != property );
802 // property is being used in a separate thread; queue a message to set the property
803 BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
807 case Property::FLOAT:
809 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
810 DALI_ASSERT_DEBUG( NULL != property );
812 // property is being used in a separate thread; queue a message to set the property
813 BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
817 case Property::INTEGER:
819 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
820 DALI_ASSERT_DEBUG( NULL != property );
822 // property is being used in a separate thread; queue a message to set the property
823 BakeMessage<int>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<int>() );
827 case Property::VECTOR2:
829 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
830 DALI_ASSERT_DEBUG( NULL != property );
832 // property is being used in a separate thread; queue a message to set the property
833 BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
837 case Property::VECTOR3:
839 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
840 DALI_ASSERT_DEBUG( NULL != property );
842 // property is being used in a separate thread; queue a message to set the property
843 BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
847 case Property::VECTOR4:
849 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
850 DALI_ASSERT_DEBUG( NULL != property );
852 // property is being used in a separate thread; queue a message to set the property
853 BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
857 case Property::ROTATION:
859 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
860 DALI_ASSERT_DEBUG( NULL != property );
862 // property is being used in a separate thread; queue a message to set the property
863 BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
867 case Property::MATRIX:
869 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
870 DALI_ASSERT_DEBUG( NULL != property );
872 // property is being used in a separate thread; queue a message to set the property
873 BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
877 case Property::MATRIX3:
879 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
880 DALI_ASSERT_DEBUG( NULL != property );
882 // property is being used in a separate thread; queue a message to set the property
883 BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
889 // non-animatable scene graph property, do nothing
894 const TypeInfo* Object::GetTypeInfo() const
898 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
899 // especially as the type-info does not change during the life-time of an application
901 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
902 if ( typeInfoHandle )
904 mTypeInfo = &GetImplementation( typeInfoHandle );
911 void Object::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
913 // guard against constraint sending messages during core destruction
914 if ( Stage::IsInstalled() )
918 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
919 baseConstraint.BeginRemove();
924 void Object::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
926 // guard against constraint sending messages during core destruction
927 if( mConstraints && Stage::IsInstalled() )
929 bool isInSceneGraph( NULL != GetSceneObject() );
931 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
932 if( it != mConstraints->end() )
934 RemoveConstraint( *it, isInSceneGraph );
935 mConstraints->erase( it );
940 void Object::RemoveConstraints( unsigned int tag )
942 // guard against constraint sending messages during core destruction
943 if( mConstraints && Stage::IsInstalled() )
945 bool isInSceneGraph( NULL != GetSceneObject() );
947 ActiveConstraintIter iter( mConstraints->begin() );
948 while(iter != mConstraints->end() )
950 ActiveConstraintBase& constraint = GetImplementation( *iter );
951 if( constraint.GetTag() == tag )
953 RemoveConstraint( *iter, isInSceneGraph );
954 iter = mConstraints->erase( iter );
964 void Object::RemoveConstraints()
966 // guard against constraint sending messages during core destruction
967 if( mConstraints && Stage::IsInstalled() )
969 // If we have nothing in the scene-graph, just clear constraint containers
970 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
971 if ( NULL != propertyOwner )
973 const ActiveConstraintConstIter endIter = mConstraints->end();
974 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
976 RemoveConstraint( *iter, true );
985 void Object::SetTypeInfo( const TypeInfo* typeInfo )
987 mTypeInfo = typeInfo;
992 // Notification for this object's constraints
993 // (note that the ActiveConstraint handles may outlive the Object)
996 const ActiveConstraintConstIter endIter = mConstraints->end();
997 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
999 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
1000 baseConstraint.OnParentDestroyed();
1004 // Notification for observers
1005 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1007 (*iter)->ObjectDestroyed(*this);
1010 delete mConstraints;
1011 delete mPropertyNotifications;
1014 CustomProperty* Object::FindCustomProperty( Property::Index index ) const
1016 CustomProperty* property( NULL );
1017 int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
1018 if( arrayIndex >= 0 )
1020 if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
1022 property = mCustomProperties[ arrayIndex ];
1028 } // namespace Internal