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
56 : mEventThreadServices( *Stage::GetCurrent() ),
59 mPropertyNotifications( NULL )
63 void Object::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 ObjectDestroyed()
67 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
69 mObservers.PushBack( &observer );
72 void Object::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 Object::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 Object::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 Object::GetPropertyComponentIndex( Property::Index index ) const
135 return Property::INVALID_COMPONENT_INDEX;
138 bool Object::Supports( Capability capability ) const
140 return (capability & SUPPORTED_CAPABILITIES);
143 unsigned int Object::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 Object::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 ) )
177 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
179 const TypeInfo* typeInfo( GetTypeInfo() );
182 return typeInfo->GetPropertyName( index );
186 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
190 CustomPropertyMetadata* custom = FindCustomProperty( index );
198 Property::Index Object::GetPropertyIndex(const std::string& name) const
200 Property::Index index = GetDefaultPropertyIndex( name );
202 if(index == Property::INVALID_INDEX)
204 const TypeInfo* typeInfo( GetTypeInfo() );
207 index = typeInfo->GetPropertyIndex( name );
208 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
210 // check whether the animatable property is registered already, if not then register one.
211 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
212 if(!animatableProperty)
214 const TypeInfo* typeInfo( GetTypeInfo() );
217 index = RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index)));
224 if( (index == Property::INVALID_INDEX)&&( mCustomProperties.Count() > 0 ) )
226 Property::Index count = PROPERTY_CUSTOM_START_INDEX;
227 const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
228 for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
230 CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
231 if ( custom->name == name )
242 bool Object::IsPropertyWritable( Property::Index index ) const
244 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
246 bool writable = false;
248 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
250 writable = IsDefaultPropertyWritable( index );
252 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
254 const TypeInfo* typeInfo( GetTypeInfo() );
257 writable = typeInfo->IsPropertyWritable( index );
261 DALI_ASSERT_ALWAYS( ! "Invalid property index" );
264 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
266 // Type Registry scene-graph properties are writable.
271 CustomPropertyMetadata* custom = FindCustomProperty( index );
274 writable = custom->IsWritable();
281 bool Object::IsPropertyAnimatable( Property::Index index ) const
283 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
285 bool animatable = false;
287 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
289 animatable = IsDefaultPropertyAnimatable( index );
291 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
293 // Type Registry event-thread only properties are not animatable.
296 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
298 // Type Registry scene-graph properties are animatable.
303 CustomPropertyMetadata* custom = FindCustomProperty( index );
306 animatable = custom->IsAnimatable();
313 bool Object::IsPropertyAConstraintInput( Property::Index index ) const
315 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
317 bool isConstraintInput = false;
319 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
321 isConstraintInput = IsDefaultPropertyAConstraintInput( index );
323 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
325 // Type Registry event-thread only properties cannot be used as an input to a constraint.
326 isConstraintInput = false;
328 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
330 // scene graph properties can be used as input to a constraint.
331 isConstraintInput = true;
335 CustomPropertyMetadata* custom = FindCustomProperty( index );
338 // ... custom properties can be used as input to a constraint.
339 isConstraintInput = true;
343 return isConstraintInput;
346 Property::Type Object::GetPropertyType( Property::Index index ) const
348 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
350 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
352 return GetDefaultPropertyType( index );
355 if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
356 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
358 const TypeInfo* typeInfo( GetTypeInfo() );
361 return typeInfo->GetPropertyType( index );
365 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
369 CustomPropertyMetadata* custom = FindCustomProperty( index );
374 return Property::NONE;
377 void Object::SetProperty( Property::Index index, const Property::Value& propertyValue )
379 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
381 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
383 SetDefaultProperty( index, propertyValue );
385 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
387 const TypeInfo* typeInfo( GetTypeInfo() );
390 typeInfo->SetProperty( this, index, propertyValue );
394 DALI_LOG_ERROR("Cannot find property index\n");
397 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
399 // check whether the animatable property is registered already, if not then register one.
400 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
401 if(!animatableProperty)
403 const TypeInfo* typeInfo( GetTypeInfo() );
406 DALI_LOG_ERROR("Cannot find property index\n");
408 else if ( Property::INVALID_INDEX == RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, propertyValue ) )
410 DALI_LOG_ERROR("Cannot register property\n");
415 // set the scene graph property value
416 SetSceneGraphProperty( index, *animatableProperty, propertyValue );
421 CustomPropertyMetadata* custom = FindCustomProperty( index );
424 if( custom->IsAnimatable() )
426 // set the scene graph property value
427 SetSceneGraphProperty( index, *custom, propertyValue );
429 else if( custom->IsWritable() )
431 custom->value = propertyValue;
432 OnPropertySet(index, propertyValue);
434 // trying to set value on read only property is no-op
438 DALI_LOG_ERROR("Invalid property index\n");
443 Property::Value Object::GetProperty(Property::Index index) const
445 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
447 Property::Value value;
449 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
451 value = GetDefaultProperty( index );
453 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
455 const TypeInfo* typeInfo( GetTypeInfo() );
458 value = typeInfo->GetProperty( this, index );
462 DALI_LOG_ERROR("Cannot find property index\n");
465 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
467 // check whether the animatable property is registered already, if not then register one.
468 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
469 if(!animatableProperty)
471 const TypeInfo* typeInfo( GetTypeInfo() );
474 if(Property::INVALID_INDEX != RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index))))
476 value = Property::Value(typeInfo->GetPropertyType(index)); // Return an initialized property value according to the type
480 DALI_LOG_ERROR("Cannot register property\n");
485 DALI_LOG_ERROR("Cannot find property index\n");
490 // get the animatable property value
491 value = GetPropertyValue( animatableProperty );
494 else if(mCustomProperties.Count() > 0)
496 CustomPropertyMetadata* custom = FindCustomProperty( index );
499 // get the custom property value
500 value = GetPropertyValue( custom );
504 DALI_LOG_ERROR("Invalid property index\n");
511 void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
515 // Default Properties
516 GetDefaultPropertyIndices( indices );
519 const TypeInfo* typeInfo( GetTypeInfo() );
522 typeInfo->GetPropertyIndices( indices );
526 if ( mCustomProperties.Count() > 0 )
528 indices.reserve( indices.size() + mCustomProperties.Count() );
530 PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin();
531 const PropertyMetadataLookup::ConstIterator endIter = mCustomProperties.End();
533 for ( ; iter != endIter; ++iter, ++i )
535 indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
540 Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
542 // Create a new property
543 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
545 switch ( propertyValue.GetType() )
547 case Property::BOOLEAN:
549 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
553 case Property::FLOAT:
555 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
559 case Property::INTEGER:
561 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
565 case Property::VECTOR2:
567 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
571 case Property::VECTOR3:
573 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
577 case Property::VECTOR4:
579 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
583 case Property::MATRIX:
585 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
589 case Property::MATRIX3:
591 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
595 case Property::ROTATION:
597 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
601 case Property::UNSIGNED_INTEGER:
602 case Property::RECTANGLE:
603 case Property::STRING:
604 case Property::ARRAY:
607 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
608 DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
614 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
615 DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
620 // get the scene property owner from derived class
621 const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
622 // we can only pass properties to scene graph side if there is a scene object
623 if( scenePropertyOwner )
625 // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
626 const PropertyBase* property = newProperty.Get();
627 if(index >= PROPERTY_CUSTOM_START_INDEX)
629 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
633 mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, propertyValue.GetType(), property ) );
636 // queue a message to add the property
637 InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
639 // notify the derived class (optional) method in case it needs to do some more work on the new property
640 // note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
641 NotifyScenePropertyInstalled( *property, name, index );
647 // property was orphaned and killed so return invalid index
648 return Property::INVALID_INDEX;
652 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
654 return RegisterSceneGraphProperty(name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue);
657 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
659 Property::Index index = Property::INVALID_INDEX;
661 if(Property::ANIMATABLE == accessMode)
663 index = RegisterProperty(name, propertyValue);
667 // Add entry to the property lookup
668 index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
669 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
675 Dali::PropertyNotification Object::AddPropertyNotification(Property::Index index,
677 const Dali::PropertyCondition& condition)
679 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
681 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
683 DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
685 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
687 // check whether the animatable property is registered already, if not then register one.
688 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
691 const TypeInfo* typeInfo( GetTypeInfo() );
694 if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
696 animatable = FindAnimatableProperty( index );
700 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
702 else if ( mCustomProperties.Count() > 0 )
704 CustomPropertyMetadata* custom = FindCustomProperty( index );
705 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
706 DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
710 Dali::Handle self(this);
711 Property target( self, index );
713 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
714 Dali::PropertyNotification propertyNotification(internal.Get());
716 if( !mPropertyNotifications )
718 mPropertyNotifications = new PropertyNotificationContainer;
720 mPropertyNotifications->push_back(propertyNotification);
722 return propertyNotification;
725 void Object::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
727 if( mPropertyNotifications )
729 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
730 while(iter != mPropertyNotifications->end() )
732 if(*iter == propertyNotification)
734 mPropertyNotifications->erase(iter);
735 // As we can't ensure all references are removed, we can just disable
737 GetImplementation(propertyNotification).Disable();
745 void Object::RemovePropertyNotifications()
747 if( mPropertyNotifications )
749 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
750 while(iter != mPropertyNotifications->end() )
752 // As we can't ensure all references are removed, we can just disable
754 GetImplementation(*iter).Disable();
758 mPropertyNotifications->clear();
762 void Object::EnablePropertyNotifications()
764 if( mPropertyNotifications )
766 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
767 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
769 for( ; iter != endIter; ++iter )
771 GetImplementation(*iter).Enable();
776 void Object::DisablePropertyNotifications()
778 if( mPropertyNotifications )
780 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
781 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
783 for( ; iter != endIter; ++iter )
785 GetImplementation(*iter).Disable();
790 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint )
792 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Handle() ) );
795 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
797 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
800 ActiveConstraintBase* Object::DoApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
802 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
803 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
805 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
809 Object& weightObjectImpl = GetImplementation( weightObject );
810 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
812 if( Property::INVALID_INDEX != weightIndex )
814 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
820 mConstraints = new ActiveConstraintContainer;
822 mConstraints->push_back( activeConstraint );
824 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
826 return activeConstraintImpl;
829 Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
831 Property::Value value;
833 DALI_ASSERT_ALWAYS( entry && "Invalid property metadata" );
835 if( !entry->IsAnimatable() )
837 value = entry->value;
841 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
843 switch ( entry->type )
845 case Property::BOOLEAN:
847 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->GetSceneGraphProperty() );
848 DALI_ASSERT_DEBUG( NULL != property );
850 value = (*property)[ bufferIndex ];
854 case Property::FLOAT:
856 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->GetSceneGraphProperty() );
857 DALI_ASSERT_DEBUG( NULL != property );
859 value = (*property)[ bufferIndex ];
863 case Property::INTEGER:
865 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->GetSceneGraphProperty() );
866 DALI_ASSERT_DEBUG( NULL != property );
868 value = (*property)[ bufferIndex ];
872 case Property::VECTOR2:
874 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->GetSceneGraphProperty() );
875 DALI_ASSERT_DEBUG( NULL != property );
877 value = (*property)[ bufferIndex ];
881 case Property::VECTOR3:
883 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->GetSceneGraphProperty() );
884 DALI_ASSERT_DEBUG( NULL != property );
886 value = (*property)[ bufferIndex ];
890 case Property::VECTOR4:
892 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->GetSceneGraphProperty() );
893 DALI_ASSERT_DEBUG( NULL != property );
895 value = (*property)[ bufferIndex ];
899 case Property::MATRIX:
901 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->GetSceneGraphProperty() );
902 DALI_ASSERT_DEBUG( NULL != property );
904 value = (*property)[ bufferIndex ];
908 case Property::MATRIX3:
910 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->GetSceneGraphProperty() );
911 DALI_ASSERT_DEBUG( NULL != property );
913 value = (*property)[ bufferIndex ];
917 case Property::ROTATION:
919 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->GetSceneGraphProperty() );
920 DALI_ASSERT_DEBUG( NULL != property );
922 value = (*property)[ bufferIndex ];
928 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
937 void Object::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
939 switch ( entry.type )
941 case Property::BOOLEAN:
943 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
944 DALI_ASSERT_DEBUG( NULL != property );
946 // property is being used in a separate thread; queue a message to set the property
947 BakeMessage<bool>( GetEventThreadServices(), *property, value.Get<bool>() );
951 case Property::FLOAT:
953 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
954 DALI_ASSERT_DEBUG( NULL != property );
956 // property is being used in a separate thread; queue a message to set the property
957 BakeMessage<float>( GetEventThreadServices(), *property, value.Get<float>() );
961 case Property::INTEGER:
963 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
964 DALI_ASSERT_DEBUG( NULL != property );
966 // property is being used in a separate thread; queue a message to set the property
967 BakeMessage<int>( GetEventThreadServices(), *property, value.Get<int>() );
971 case Property::VECTOR2:
973 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
974 DALI_ASSERT_DEBUG( NULL != property );
976 // property is being used in a separate thread; queue a message to set the property
977 BakeMessage<Vector2>( GetEventThreadServices(), *property, value.Get<Vector2>() );
981 case Property::VECTOR3:
983 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
984 DALI_ASSERT_DEBUG( NULL != property );
986 // property is being used in a separate thread; queue a message to set the property
987 BakeMessage<Vector3>( GetEventThreadServices(), *property, value.Get<Vector3>() );
991 case Property::VECTOR4:
993 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
994 DALI_ASSERT_DEBUG( NULL != property );
996 // property is being used in a separate thread; queue a message to set the property
997 BakeMessage<Vector4>( GetEventThreadServices(), *property, value.Get<Vector4>() );
1001 case Property::ROTATION:
1003 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
1004 DALI_ASSERT_DEBUG( NULL != property );
1006 // property is being used in a separate thread; queue a message to set the property
1007 BakeMessage<Quaternion>( GetEventThreadServices(), *property, value.Get<Quaternion>() );
1011 case Property::MATRIX:
1013 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
1014 DALI_ASSERT_DEBUG( NULL != property );
1016 // property is being used in a separate thread; queue a message to set the property
1017 BakeMessage<Matrix>( GetEventThreadServices(), *property, value.Get<Matrix>() );
1021 case Property::MATRIX3:
1023 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
1024 DALI_ASSERT_DEBUG( NULL != property );
1026 // property is being used in a separate thread; queue a message to set the property
1027 BakeMessage<Matrix3>( GetEventThreadServices(), *property, value.Get<Matrix3>() );
1033 // non-animatable scene graph property, do nothing
1038 const TypeInfo* Object::GetTypeInfo() const
1042 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
1043 // especially as the type-info does not change during the life-time of an application
1045 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
1046 if ( typeInfoHandle )
1048 mTypeInfo = &GetImplementation( typeInfoHandle );
1055 void Object::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
1057 // guard against constraint sending messages during core destruction
1058 if ( Stage::IsInstalled() )
1060 if( isInScenegraph )
1062 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
1063 baseConstraint.BeginRemove();
1068 void Object::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
1070 // guard against constraint sending messages during core destruction
1071 if( mConstraints && Stage::IsInstalled() )
1073 bool isInSceneGraph( NULL != GetSceneObject() );
1075 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
1076 if( it != mConstraints->end() )
1078 RemoveConstraint( *it, isInSceneGraph );
1079 mConstraints->erase( it );
1084 void Object::RemoveConstraints( unsigned int tag )
1086 // guard against constraint sending messages during core destruction
1087 if( mConstraints && Stage::IsInstalled() )
1089 bool isInSceneGraph( NULL != GetSceneObject() );
1091 ActiveConstraintIter iter( mConstraints->begin() );
1092 while(iter != mConstraints->end() )
1094 ActiveConstraintBase& constraint = GetImplementation( *iter );
1095 if( constraint.GetTag() == tag )
1097 RemoveConstraint( *iter, isInSceneGraph );
1098 iter = mConstraints->erase( iter );
1108 void Object::RemoveConstraints()
1110 // guard against constraint sending messages during core destruction
1111 if( mConstraints && Stage::IsInstalled() )
1113 // If we have nothing in the scene-graph, just clear constraint containers
1114 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
1115 if ( NULL != propertyOwner )
1117 const ActiveConstraintConstIter endIter = mConstraints->end();
1118 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1120 RemoveConstraint( *iter, true );
1124 delete mConstraints;
1125 mConstraints = NULL;
1129 void Object::SetTypeInfo( const TypeInfo* typeInfo )
1131 mTypeInfo = typeInfo;
1136 // Notification for this object's constraints
1137 // (note that the ActiveConstraint handles may outlive the Object)
1140 const ActiveConstraintConstIter endIter = mConstraints->end();
1141 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1143 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
1144 baseConstraint.OnParentDestroyed();
1148 // Notification for observers
1149 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1151 (*iter)->ObjectDestroyed(*this);
1154 delete mConstraints;
1155 delete mPropertyNotifications;
1158 CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
1160 CustomPropertyMetadata* property( NULL );
1161 int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
1162 if( arrayIndex >= 0 )
1164 if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
1166 property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
1172 AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
1174 for ( int arrayIndex = 0; arrayIndex < (int)mAnimatableProperties.Count(); arrayIndex++ )
1176 AnimatablePropertyMetadata* property = static_cast<AnimatablePropertyMetadata*>( mAnimatableProperties[ arrayIndex ] );
1177 if( property->index == index )
1185 } // namespace Internal