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/update/common/uniform-map.h>
30 #include <dali/internal/event/animation/active-constraint-base.h>
31 #include <dali/internal/event/animation/constraint-impl.h>
32 #include <dali/internal/event/common/stage-impl.h>
33 #include <dali/internal/event/common/property-notification-impl.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; // Object provides this capability
48 typedef Dali::Vector<Object::Observer*>::Iterator ObserverIter;
49 typedef Dali::Vector<Object::Observer*>::ConstIterator ConstObserverIter;
51 #if defined(DEBUG_ENABLED)
52 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_OBJECT" );
54 } // unnamed namespace
57 : mEventThreadServices( *Stage::GetCurrent() ),
60 mPropertyNotifications( NULL )
64 void Object::AddObserver(Observer& observer)
66 // make sure an observer doesn't observe the same object twice
67 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ObjectDestroyed()
68 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
70 mObservers.PushBack( &observer );
73 void Object::RemoveObserver(Observer& observer)
75 // Find the observer...
76 const ConstObserverIter endIter = mObservers.End();
77 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
79 if( (*iter) == &observer)
81 mObservers.Erase( iter );
85 DALI_ASSERT_DEBUG(endIter != mObservers.End());
88 void Object::OnSceneObjectAdd()
90 // Notification for this object's constraints
93 const ActiveConstraintConstIter endIter = mConstraints->end();
94 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
96 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
97 baseConstraint.OnParentSceneObjectAdded();
101 // Notification for observers
102 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
104 (*iter)->SceneObjectAdded(*this);
107 // enable property notifications in scene graph
108 EnablePropertyNotifications();
111 void Object::OnSceneObjectRemove()
113 // Notification for this object's constraints
116 const ActiveConstraintConstIter endIter = mConstraints->end();
117 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
119 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
120 baseConstraint.OnParentSceneObjectRemoved();
124 // Notification for observers
125 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
127 (*iter)->SceneObjectRemoved(*this);
130 // disable property notifications in scene graph
131 DisablePropertyNotifications();
134 int Object::GetPropertyComponentIndex( Property::Index index ) const
136 return Property::INVALID_COMPONENT_INDEX;
139 bool Object::Supports( Capability capability ) const
141 return (capability & SUPPORTED_CAPABILITIES);
144 unsigned int Object::GetPropertyCount() const
146 unsigned int count = GetDefaultPropertyCount();
148 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
150 const TypeInfo* typeInfo( GetTypeInfo() );
153 unsigned int manual( typeInfo->GetPropertyCount() );
156 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
159 unsigned int custom( mCustomProperties.Count() );
161 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
163 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
168 std::string Object::GetPropertyName( Property::Index index ) const
170 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
172 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
174 return GetDefaultPropertyName( index );
177 if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
178 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
180 const TypeInfo* typeInfo( GetTypeInfo() );
183 return typeInfo->GetPropertyName( index );
187 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
191 CustomPropertyMetadata* custom = FindCustomProperty( index );
199 Property::Index Object::GetPropertyIndex(const std::string& name) const
201 Property::Index index = GetDefaultPropertyIndex( name );
203 if(index == Property::INVALID_INDEX)
205 const TypeInfo* typeInfo( GetTypeInfo() );
208 index = typeInfo->GetPropertyIndex( name );
209 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
211 // check whether the animatable property is registered already, if not then register one.
212 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
213 if(!animatableProperty)
215 const TypeInfo* typeInfo( GetTypeInfo() );
218 index = RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index)));
225 if( (index == Property::INVALID_INDEX)&&( mCustomProperties.Count() > 0 ) )
227 Property::Index count = PROPERTY_CUSTOM_START_INDEX;
228 const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
229 for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
231 CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
232 if ( custom->name == name )
243 bool Object::IsPropertyWritable( Property::Index index ) const
245 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
247 bool writable = false;
249 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
251 writable = IsDefaultPropertyWritable( index );
253 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
255 const TypeInfo* typeInfo( GetTypeInfo() );
258 writable = typeInfo->IsPropertyWritable( index );
262 DALI_ASSERT_ALWAYS( ! "Invalid property index" );
265 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
267 // Type Registry scene-graph properties are writable.
272 CustomPropertyMetadata* custom = FindCustomProperty( index );
275 writable = custom->IsWritable();
282 bool Object::IsPropertyAnimatable( Property::Index index ) const
284 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
286 bool animatable = false;
288 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
290 animatable = IsDefaultPropertyAnimatable( index );
292 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
294 // Type Registry event-thread only properties are not animatable.
297 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
299 // Type Registry scene-graph properties are animatable.
304 CustomPropertyMetadata* custom = FindCustomProperty( index );
307 animatable = custom->IsAnimatable();
314 bool Object::IsPropertyAConstraintInput( Property::Index index ) const
316 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
318 bool isConstraintInput = false;
320 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
322 isConstraintInput = IsDefaultPropertyAConstraintInput( index );
324 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
326 // Type Registry event-thread only properties cannot be used as an input to a constraint.
327 isConstraintInput = false;
329 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
331 // scene graph properties can be used as input to a constraint.
332 isConstraintInput = true;
336 CustomPropertyMetadata* custom = FindCustomProperty( index );
339 // ... custom properties can be used as input to a constraint.
340 isConstraintInput = true;
344 return isConstraintInput;
347 Property::Type Object::GetPropertyType( Property::Index index ) const
349 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
351 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
353 return GetDefaultPropertyType( index );
356 if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
357 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
359 const TypeInfo* typeInfo( GetTypeInfo() );
362 return typeInfo->GetPropertyType( index );
366 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
370 CustomPropertyMetadata* custom = FindCustomProperty( index );
375 return Property::NONE;
378 void Object::SetProperty( Property::Index index, const Property::Value& propertyValue )
380 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
382 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
384 SetDefaultProperty( index, propertyValue );
386 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
388 const TypeInfo* typeInfo( GetTypeInfo() );
391 typeInfo->SetProperty( this, index, propertyValue );
395 DALI_LOG_ERROR("Cannot find property index\n");
398 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
400 // check whether the animatable property is registered already, if not then register one.
401 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
402 if(!animatableProperty)
404 const TypeInfo* typeInfo( GetTypeInfo() );
405 if (typeInfo && Property::INVALID_INDEX == RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, propertyValue))
407 DALI_LOG_ERROR("Cannot register property\n");
411 DALI_LOG_ERROR("Cannot find property index\n");
416 // set the scene graph property value
417 SetSceneGraphProperty( index, *animatableProperty, propertyValue );
422 CustomPropertyMetadata* custom = FindCustomProperty( index );
425 if( custom->IsAnimatable() )
427 // set the scene graph property value
428 SetSceneGraphProperty( index, *custom, propertyValue );
430 else if( custom->IsWritable() )
432 custom->value = propertyValue;
433 OnPropertySet(index, propertyValue);
435 // trying to set value on read only property is no-op
439 DALI_LOG_ERROR("Invalid property index\n");
444 Property::Value Object::GetProperty(Property::Index index) const
446 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
448 Property::Value value;
450 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
452 value = GetDefaultProperty( index );
454 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
456 const TypeInfo* typeInfo( GetTypeInfo() );
459 value = typeInfo->GetProperty( this, index );
463 DALI_LOG_ERROR("Cannot find property index\n");
466 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
468 // check whether the animatable property is registered already, if not then register one.
469 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
470 if(!animatableProperty)
472 const TypeInfo* typeInfo( GetTypeInfo() );
475 if(Property::INVALID_INDEX != RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index))))
477 value = Property::Value(typeInfo->GetPropertyType(index)); // Return an initialized property value according to the type
481 DALI_LOG_ERROR("Cannot register property\n");
486 DALI_LOG_ERROR("Cannot find property index\n");
491 // get the animatable property value
492 value = GetPropertyValue( animatableProperty );
495 else if(mCustomProperties.Count() > 0)
497 CustomPropertyMetadata* custom = FindCustomProperty( index );
500 // get the custom property value
501 value = GetPropertyValue( custom );
505 DALI_LOG_ERROR("Invalid property index\n");
512 void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
516 // Default Properties
517 GetDefaultPropertyIndices( indices );
520 const TypeInfo* typeInfo( GetTypeInfo() );
523 typeInfo->GetPropertyIndices( indices );
527 if ( mCustomProperties.Count() > 0 )
529 indices.reserve( indices.size() + mCustomProperties.Count() );
531 PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin();
532 const PropertyMetadataLookup::ConstIterator endIter = mCustomProperties.End();
534 for ( ; iter != endIter; ++iter, ++i )
536 indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
541 Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
543 // Create a new property
544 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
546 switch ( propertyValue.GetType() )
548 case Property::BOOLEAN:
550 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
554 case Property::FLOAT:
556 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
560 case Property::INTEGER:
562 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
566 case Property::VECTOR2:
568 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
572 case Property::VECTOR3:
574 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
578 case Property::VECTOR4:
580 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
584 case Property::MATRIX:
586 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
590 case Property::MATRIX3:
592 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
596 case Property::ROTATION:
598 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
602 case Property::UNSIGNED_INTEGER:
603 case Property::RECTANGLE:
604 case Property::STRING:
605 case Property::ARRAY:
608 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
609 DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
615 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
616 DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
621 // get the scene property owner from derived class
622 const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
623 // we can only pass properties to scene graph side if there is a scene object
624 if( scenePropertyOwner )
626 // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
627 const PropertyBase* property = newProperty.Get();
628 if(index >= PROPERTY_CUSTOM_START_INDEX)
630 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
634 mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( propertyValue.GetType(), property ) );
637 // queue a message to add the property
638 InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *scenePropertyOwner, newProperty.Release() ); // Message takes ownership
640 // notify the derived class (optional) method in case it needs to do some more work on the new property
641 // note! have to use the local pointer as OwnerPointer now points to NULL as it handed over its ownership
642 NotifyScenePropertyInstalled( *property, name, index );
648 // property was orphaned and killed so return invalid index
649 return Property::INVALID_INDEX;
653 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
655 return RegisterSceneGraphProperty(name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue);
658 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
660 Property::Index index = Property::INVALID_INDEX;
662 if(Property::ANIMATABLE == accessMode)
664 index = RegisterProperty(name, propertyValue);
668 // Add entry to the property lookup
669 index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
670 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
676 Dali::PropertyNotification Object::AddPropertyNotification(Property::Index index,
678 const Dali::PropertyCondition& condition)
680 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
682 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
684 DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
686 else if ( mCustomProperties.Count() > 0 )
688 CustomPropertyMetadata* custom = FindCustomProperty( index );
689 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
690 DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
694 Dali::Handle self(this);
695 Property target( self, index );
697 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
698 Dali::PropertyNotification propertyNotification(internal.Get());
700 if( !mPropertyNotifications )
702 mPropertyNotifications = new PropertyNotificationContainer;
704 mPropertyNotifications->push_back(propertyNotification);
706 return propertyNotification;
709 void Object::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
711 if( mPropertyNotifications )
713 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
714 while(iter != mPropertyNotifications->end() )
716 if(*iter == propertyNotification)
718 mPropertyNotifications->erase(iter);
719 // As we can't ensure all references are removed, we can just disable
721 GetImplementation(propertyNotification).Disable();
729 void Object::RemovePropertyNotifications()
731 if( mPropertyNotifications )
733 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
734 while(iter != mPropertyNotifications->end() )
736 // As we can't ensure all references are removed, we can just disable
738 GetImplementation(*iter).Disable();
742 mPropertyNotifications->clear();
746 void Object::EnablePropertyNotifications()
748 if( mPropertyNotifications )
750 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
751 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
753 for( ; iter != endIter; ++iter )
755 GetImplementation(*iter).Enable();
760 void Object::DisablePropertyNotifications()
762 if( mPropertyNotifications )
764 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
765 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
767 for( ; iter != endIter; ++iter )
769 GetImplementation(*iter).Disable();
774 void Object::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
776 // Get the address of the property if it's a scene property
777 const PropertyInputImpl* propertyPtr = GetSceneObjectInputProperty( propertyIndex );
779 // Check instead for newly registered properties
780 if( propertyPtr == NULL )
782 PropertyMetadata* animatable = FindAnimatableProperty( propertyIndex );
783 if( animatable != NULL )
785 propertyPtr = animatable->GetSceneGraphProperty();
789 if( propertyPtr == NULL )
791 PropertyMetadata* custom = FindCustomProperty( propertyIndex );
794 propertyPtr = custom->GetSceneGraphProperty();
798 // @todo MESH_REWORK Store mappings for unstaged objects?
800 if( propertyPtr != NULL )
802 const SceneGraph::PropertyOwner* sceneObject = GetPropertyOwner();
804 if( sceneObject != NULL )
806 SceneGraph::UniformPropertyMapping* map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
807 // Message takes ownership of Uniform map (and will delete it after copy)
808 AddUniformMapMessage( GetEventThreadServices(), *sceneObject, map);
812 // @todo MESH_REWORK FIXME Need to store something that can be sent to the scene
813 // object when staged.
814 DALI_ASSERT_ALWAYS(0 && "MESH_REWORK - Need to store property whilst off-stage" );
819 void Object::RemoveUniformMapping( const std::string& uniformName )
821 const SceneGraph::PropertyOwner* sceneObject = GetSceneObject();
822 RemoveUniformMapMessage( GetEventThreadServices(), *sceneObject, uniformName);
825 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint )
827 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Handle() ) );
830 Dali::ActiveConstraint Object::ApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
832 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
835 ActiveConstraintBase* Object::DoApplyConstraint( Constraint& constraint, Dali::Handle weightObject )
837 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
838 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
840 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
844 Object& weightObjectImpl = GetImplementation( weightObject );
845 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
847 if( Property::INVALID_INDEX != weightIndex )
849 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
855 mConstraints = new ActiveConstraintContainer;
857 mConstraints->push_back( activeConstraint );
859 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
861 return activeConstraintImpl;
864 Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
866 Property::Value value;
868 DALI_ASSERT_ALWAYS( entry && "Invalid property metadata" );
870 if( !entry->IsAnimatable() )
872 value = entry->value;
876 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
878 switch ( entry->type )
880 case Property::BOOLEAN:
882 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->GetSceneGraphProperty() );
883 DALI_ASSERT_DEBUG( NULL != property );
885 value = (*property)[ bufferIndex ];
889 case Property::FLOAT:
891 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->GetSceneGraphProperty() );
892 DALI_ASSERT_DEBUG( NULL != property );
894 value = (*property)[ bufferIndex ];
898 case Property::INTEGER:
900 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->GetSceneGraphProperty() );
901 DALI_ASSERT_DEBUG( NULL != property );
903 value = (*property)[ bufferIndex ];
907 case Property::VECTOR2:
909 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->GetSceneGraphProperty() );
910 DALI_ASSERT_DEBUG( NULL != property );
912 value = (*property)[ bufferIndex ];
916 case Property::VECTOR3:
918 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->GetSceneGraphProperty() );
919 DALI_ASSERT_DEBUG( NULL != property );
921 value = (*property)[ bufferIndex ];
925 case Property::VECTOR4:
927 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->GetSceneGraphProperty() );
928 DALI_ASSERT_DEBUG( NULL != property );
930 value = (*property)[ bufferIndex ];
934 case Property::MATRIX:
936 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->GetSceneGraphProperty() );
937 DALI_ASSERT_DEBUG( NULL != property );
939 value = (*property)[ bufferIndex ];
943 case Property::MATRIX3:
945 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->GetSceneGraphProperty() );
946 DALI_ASSERT_DEBUG( NULL != property );
948 value = (*property)[ bufferIndex ];
952 case Property::ROTATION:
954 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->GetSceneGraphProperty() );
955 DALI_ASSERT_DEBUG( NULL != property );
957 value = (*property)[ bufferIndex ];
963 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
972 void Object::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
974 switch ( entry.type )
976 case Property::BOOLEAN:
978 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
979 DALI_ASSERT_DEBUG( NULL != property );
981 // property is being used in a separate thread; queue a message to set the property
982 BakeMessage<bool>( GetEventThreadServices(), *property, value.Get<bool>() );
986 case Property::FLOAT:
988 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
989 DALI_ASSERT_DEBUG( NULL != property );
991 // property is being used in a separate thread; queue a message to set the property
992 BakeMessage<float>( GetEventThreadServices(), *property, value.Get<float>() );
996 case Property::INTEGER:
998 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
999 DALI_ASSERT_DEBUG( NULL != property );
1001 // property is being used in a separate thread; queue a message to set the property
1002 BakeMessage<int>( GetEventThreadServices(), *property, value.Get<int>() );
1006 case Property::VECTOR2:
1008 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
1009 DALI_ASSERT_DEBUG( NULL != property );
1011 // property is being used in a separate thread; queue a message to set the property
1012 BakeMessage<Vector2>( GetEventThreadServices(), *property, value.Get<Vector2>() );
1016 case Property::VECTOR3:
1018 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
1019 DALI_ASSERT_DEBUG( NULL != property );
1021 // property is being used in a separate thread; queue a message to set the property
1022 BakeMessage<Vector3>( GetEventThreadServices(), *property, value.Get<Vector3>() );
1026 case Property::VECTOR4:
1028 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
1029 DALI_ASSERT_DEBUG( NULL != property );
1031 // property is being used in a separate thread; queue a message to set the property
1032 BakeMessage<Vector4>( GetEventThreadServices(), *property, value.Get<Vector4>() );
1036 case Property::ROTATION:
1038 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
1039 DALI_ASSERT_DEBUG( NULL != property );
1041 // property is being used in a separate thread; queue a message to set the property
1042 BakeMessage<Quaternion>( GetEventThreadServices(), *property, value.Get<Quaternion>() );
1046 case Property::MATRIX:
1048 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
1049 DALI_ASSERT_DEBUG( NULL != property );
1051 // property is being used in a separate thread; queue a message to set the property
1052 BakeMessage<Matrix>( GetEventThreadServices(), *property, value.Get<Matrix>() );
1056 case Property::MATRIX3:
1058 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
1059 DALI_ASSERT_DEBUG( NULL != property );
1061 // property is being used in a separate thread; queue a message to set the property
1062 BakeMessage<Matrix3>( GetEventThreadServices(), *property, value.Get<Matrix3>() );
1068 // non-animatable scene graph property, do nothing
1073 const TypeInfo* Object::GetTypeInfo() const
1077 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
1078 // especially as the type-info does not change during the life-time of an application
1080 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
1081 if ( typeInfoHandle )
1083 mTypeInfo = &GetImplementation( typeInfoHandle );
1090 void Object::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
1092 // guard against constraint sending messages during core destruction
1093 if ( Stage::IsInstalled() )
1095 if( isInScenegraph )
1097 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
1098 baseConstraint.BeginRemove();
1103 void Object::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
1105 // guard against constraint sending messages during core destruction
1106 if( mConstraints && Stage::IsInstalled() )
1108 bool isInSceneGraph( NULL != GetSceneObject() );
1110 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
1111 if( it != mConstraints->end() )
1113 RemoveConstraint( *it, isInSceneGraph );
1114 mConstraints->erase( it );
1119 void Object::RemoveConstraints( unsigned int tag )
1121 // guard against constraint sending messages during core destruction
1122 if( mConstraints && Stage::IsInstalled() )
1124 bool isInSceneGraph( NULL != GetSceneObject() );
1126 ActiveConstraintIter iter( mConstraints->begin() );
1127 while(iter != mConstraints->end() )
1129 ActiveConstraintBase& constraint = GetImplementation( *iter );
1130 if( constraint.GetTag() == tag )
1132 RemoveConstraint( *iter, isInSceneGraph );
1133 iter = mConstraints->erase( iter );
1143 void Object::RemoveConstraints()
1145 // guard against constraint sending messages during core destruction
1146 if( mConstraints && Stage::IsInstalled() )
1148 // If we have nothing in the scene-graph, just clear constraint containers
1149 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
1150 if ( NULL != propertyOwner )
1152 const ActiveConstraintConstIter endIter = mConstraints->end();
1153 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1155 RemoveConstraint( *iter, true );
1159 delete mConstraints;
1160 mConstraints = NULL;
1164 void Object::SetTypeInfo( const TypeInfo* typeInfo )
1166 mTypeInfo = typeInfo;
1171 // Notification for this object's constraints
1172 // (note that the ActiveConstraint handles may outlive the Object)
1175 const ActiveConstraintConstIter endIter = mConstraints->end();
1176 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1178 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
1179 baseConstraint.OnParentDestroyed();
1183 // Notification for observers
1184 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1186 (*iter)->ObjectDestroyed(*this);
1189 delete mConstraints;
1190 delete mPropertyNotifications;
1193 CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
1195 CustomPropertyMetadata* property( NULL );
1196 int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
1197 if( arrayIndex >= 0 )
1199 if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
1201 property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
1207 AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
1209 AnimatablePropertyMetadata* property( NULL );
1210 int arrayIndex = index - ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX;
1211 if( arrayIndex >= 0 )
1213 if( arrayIndex < (int)mAnimatableProperties.Count() )
1215 property = static_cast<AnimatablePropertyMetadata*>(mAnimatableProperties[ arrayIndex ]);
1221 } // namespace Internal