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/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 observers
90 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
92 (*iter)->SceneObjectAdded(*this);
95 // enable property notifications in scene graph
96 EnablePropertyNotifications();
99 void Object::OnSceneObjectRemove()
101 // Notification for observers
102 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
104 (*iter)->SceneObjectRemoved(*this);
107 // disable property notifications in scene graph
108 DisablePropertyNotifications();
111 int Object::GetPropertyComponentIndex( Property::Index index ) const
113 return Property::INVALID_COMPONENT_INDEX;
116 bool Object::Supports( Capability capability ) const
118 return (capability & SUPPORTED_CAPABILITIES);
121 unsigned int Object::GetPropertyCount() const
123 unsigned int count = GetDefaultPropertyCount();
125 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
127 const TypeInfo* typeInfo( GetTypeInfo() );
130 unsigned int manual( typeInfo->GetPropertyCount() );
133 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
136 unsigned int custom( mCustomProperties.Count() );
138 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
140 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
145 std::string Object::GetPropertyName( Property::Index index ) const
147 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
149 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
151 return GetDefaultPropertyName( index );
154 if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
155 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
157 const TypeInfo* typeInfo( GetTypeInfo() );
160 return typeInfo->GetPropertyName( index );
164 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
168 CustomPropertyMetadata* custom = FindCustomProperty( index );
176 Property::Index Object::GetPropertyIndex(const std::string& name) const
178 Property::Index index = GetDefaultPropertyIndex( name );
180 if(index == Property::INVALID_INDEX)
182 const TypeInfo* typeInfo( GetTypeInfo() );
185 index = typeInfo->GetPropertyIndex( name );
186 if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
188 // check whether the animatable property is registered already, if not then register one.
189 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
190 if(!animatableProperty)
192 const TypeInfo* typeInfo( GetTypeInfo() );
195 index = RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index)));
202 if( (index == Property::INVALID_INDEX)&&( mCustomProperties.Count() > 0 ) )
204 Property::Index count = PROPERTY_CUSTOM_START_INDEX;
205 const PropertyMetadataLookup::ConstIterator end = mCustomProperties.End();
206 for( PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin(); iter != end; ++iter, ++count )
208 CustomPropertyMetadata* custom = static_cast<CustomPropertyMetadata*>(*iter);
209 if ( custom->name == name )
220 bool Object::IsPropertyWritable( Property::Index index ) const
222 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
224 bool writable = false;
226 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
228 writable = IsDefaultPropertyWritable( index );
230 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
232 const TypeInfo* typeInfo( GetTypeInfo() );
235 writable = typeInfo->IsPropertyWritable( index );
239 DALI_ASSERT_ALWAYS( ! "Invalid property index" );
242 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
244 // Type Registry scene-graph properties are writable.
249 CustomPropertyMetadata* custom = FindCustomProperty( index );
252 writable = custom->IsWritable();
259 bool Object::IsPropertyAnimatable( Property::Index index ) const
261 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
263 bool animatable = false;
265 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
267 animatable = IsDefaultPropertyAnimatable( index );
269 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
271 // Type Registry event-thread only properties are not animatable.
274 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
276 // Type Registry scene-graph properties are animatable.
281 CustomPropertyMetadata* custom = FindCustomProperty( index );
284 animatable = custom->IsAnimatable();
291 bool Object::IsPropertyAConstraintInput( Property::Index index ) const
293 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
295 bool isConstraintInput = false;
297 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
299 isConstraintInput = IsDefaultPropertyAConstraintInput( index );
301 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
303 // Type Registry event-thread only properties cannot be used as an input to a constraint.
304 isConstraintInput = false;
306 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
308 // scene graph properties can be used as input to a constraint.
309 isConstraintInput = true;
313 CustomPropertyMetadata* custom = FindCustomProperty( index );
316 // ... custom properties can be used as input to a constraint.
317 isConstraintInput = true;
321 return isConstraintInput;
324 Property::Type Object::GetPropertyType( Property::Index index ) const
326 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
328 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
330 return GetDefaultPropertyType( index );
333 if ( ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
334 || ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) )
336 const TypeInfo* typeInfo( GetTypeInfo() );
339 return typeInfo->GetPropertyType( index );
343 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
347 CustomPropertyMetadata* custom = FindCustomProperty( index );
352 return Property::NONE;
355 void Object::SetProperty( Property::Index index, const Property::Value& propertyValue )
357 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
359 bool propertySet( true );
361 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
363 SetDefaultProperty( index, propertyValue );
365 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
367 const TypeInfo* typeInfo( GetTypeInfo() );
368 typeInfo->SetProperty( this, index, propertyValue );
370 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
372 // check whether the animatable property is registered already, if not then register one.
373 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
374 if(!animatableProperty)
376 const TypeInfo* typeInfo( GetTypeInfo() );
377 if ( Property::INVALID_INDEX == RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, propertyValue ) )
379 DALI_LOG_ERROR("Cannot register property\n");
385 // set the scene graph property value
386 SetSceneGraphProperty( index, *animatableProperty, propertyValue );
391 CustomPropertyMetadata* custom = FindCustomProperty( index );
394 if( custom->IsAnimatable() )
396 // set the scene graph property value
397 SetSceneGraphProperty( index, *custom, propertyValue );
399 else if( custom->IsWritable() )
401 custom->value = propertyValue;
405 // trying to set value on read only property is no-op
411 DALI_LOG_ERROR("Invalid property index\n");
416 // Let derived classes know that a property has been set
417 // TODO: We should not call this for read-only properties, SetDefaultProperty() && TypeInfo::SetProperty() should return a bool, which would be true if the property is set
420 OnPropertySet(index, propertyValue);
424 Property::Value Object::GetProperty(Property::Index index) const
426 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
428 Property::Value value;
430 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
432 value = GetDefaultProperty( index );
434 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
436 const TypeInfo* typeInfo( GetTypeInfo() );
439 value = typeInfo->GetProperty( this, index );
443 DALI_LOG_ERROR("Cannot find property index\n");
446 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
448 // check whether the animatable property is registered already, if not then register one.
449 AnimatablePropertyMetadata* animatableProperty = FindAnimatableProperty( index );
450 if(!animatableProperty)
452 const TypeInfo* typeInfo( GetTypeInfo() );
455 if(Property::INVALID_INDEX != RegisterSceneGraphProperty(typeInfo->GetPropertyName(index), index, Property::Value(typeInfo->GetPropertyType(index))))
457 value = Property::Value(typeInfo->GetPropertyType(index)); // Return an initialized property value according to the type
461 DALI_LOG_ERROR("Cannot register property\n");
466 DALI_LOG_ERROR("Cannot find property index\n");
471 // get the animatable property value
472 value = GetPropertyValue( animatableProperty );
475 else if(mCustomProperties.Count() > 0)
477 CustomPropertyMetadata* custom = FindCustomProperty( index );
480 // get the custom property value
481 value = GetPropertyValue( custom );
485 DALI_LOG_ERROR("Invalid property index\n");
492 void Object::GetPropertyIndices( Property::IndexContainer& indices ) const
496 // Default Properties
497 GetDefaultPropertyIndices( indices );
500 const TypeInfo* typeInfo( GetTypeInfo() );
503 typeInfo->GetPropertyIndices( indices );
507 if ( mCustomProperties.Count() > 0 )
509 indices.reserve( indices.size() + mCustomProperties.Count() );
511 PropertyMetadataLookup::ConstIterator iter = mCustomProperties.Begin();
512 const PropertyMetadataLookup::ConstIterator endIter = mCustomProperties.End();
514 for ( ; iter != endIter; ++iter, ++i )
516 indices.push_back( PROPERTY_CUSTOM_START_INDEX + i );
521 Property::Index Object::RegisterSceneGraphProperty(const std::string& name, Property::Index index, const Property::Value& propertyValue) const
523 // Create a new property
524 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
526 switch ( propertyValue.GetType() )
528 case Property::BOOLEAN:
530 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
534 case Property::INTEGER:
536 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
540 case Property::UNSIGNED_INTEGER:
542 newProperty = new AnimatableProperty<unsigned int>( propertyValue.Get<unsigned int>() );
546 case Property::FLOAT:
548 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
552 case Property::VECTOR2:
554 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
558 case Property::VECTOR3:
560 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
564 case Property::VECTOR4:
566 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
570 case Property::MATRIX:
572 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
576 case Property::MATRIX3:
578 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
582 case Property::ROTATION:
584 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
588 case Property::RECTANGLE:
589 case Property::STRING:
590 case Property::ARRAY:
593 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
594 DALI_ASSERT_ALWAYS( !"PropertyType is not animatable" );
600 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
601 DALI_ASSERT_ALWAYS( !"PropertyType enumeration is out of bounds" );
606 // get the scene property owner from derived class
607 const SceneGraph::PropertyOwner* scenePropertyOwner = GetPropertyOwner();
608 // we can only pass properties to scene graph side if there is a scene object
609 if( scenePropertyOwner )
611 // keep a local pointer to the property as the OwnerPointer will pass its copy to the message
612 const PropertyBase* property = newProperty.Get();
613 if(index >= PROPERTY_CUSTOM_START_INDEX)
615 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue.GetType(), property ) );
619 mAnimatableProperties.PushBack( new AnimatablePropertyMetadata( index, propertyValue.GetType(), property ) );
622 // queue a message to add the property
623 InstallCustomPropertyMessage( const_cast<EventThreadServices&>(GetEventThreadServices()), *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 );
633 // property was orphaned and killed so return invalid index
634 return Property::INVALID_INDEX;
638 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue)
640 return RegisterSceneGraphProperty(name, PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count(), propertyValue);
643 Property::Index Object::RegisterProperty( const std::string& name, const Property::Value& propertyValue, Property::AccessMode accessMode)
645 Property::Index index = Property::INVALID_INDEX;
647 if(Property::ANIMATABLE == accessMode)
649 index = RegisterProperty(name, propertyValue);
653 // Add entry to the property lookup
654 index = PROPERTY_CUSTOM_START_INDEX + mCustomProperties.Count();
655 mCustomProperties.PushBack( new CustomPropertyMetadata( name, propertyValue, accessMode ) );
661 Dali::PropertyNotification Object::AddPropertyNotification(Property::Index index,
663 const Dali::PropertyCondition& condition)
665 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
667 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
669 DALI_ASSERT_ALWAYS( false && "Property notification added to event side only property." );
671 else if ( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
673 // check whether the animatable property is registered already, if not then register one.
674 AnimatablePropertyMetadata* animatable = FindAnimatableProperty( index );
677 const TypeInfo* typeInfo( GetTypeInfo() );
680 if( Property::INVALID_INDEX != RegisterSceneGraphProperty( typeInfo->GetPropertyName( index ), index, Property::Value( typeInfo->GetPropertyType( index ) ) ) )
682 animatable = FindAnimatableProperty( index );
686 DALI_ASSERT_ALWAYS( animatable && "Property index is invalid" );
688 else if ( mCustomProperties.Count() > 0 )
690 CustomPropertyMetadata* custom = FindCustomProperty( index );
691 DALI_ASSERT_ALWAYS( custom && "Invalid property index" );
692 DALI_ASSERT_ALWAYS( custom->IsAnimatable() && "Property notification added to event side only property." );
696 Dali::Handle self(this);
697 Property target( self, index );
699 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
700 Dali::PropertyNotification propertyNotification(internal.Get());
702 if( !mPropertyNotifications )
704 mPropertyNotifications = new PropertyNotificationContainer;
706 mPropertyNotifications->push_back(propertyNotification);
708 return propertyNotification;
711 void Object::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
713 if( mPropertyNotifications )
715 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
716 while(iter != mPropertyNotifications->end() )
718 if(*iter == propertyNotification)
720 mPropertyNotifications->erase(iter);
721 // As we can't ensure all references are removed, we can just disable
723 GetImplementation(propertyNotification).Disable();
731 void Object::RemovePropertyNotifications()
733 if( mPropertyNotifications )
735 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
736 while(iter != mPropertyNotifications->end() )
738 // As we can't ensure all references are removed, we can just disable
740 GetImplementation(*iter).Disable();
744 mPropertyNotifications->clear();
748 void Object::EnablePropertyNotifications()
750 if( mPropertyNotifications )
752 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
753 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
755 for( ; iter != endIter; ++iter )
757 GetImplementation(*iter).Enable();
762 void Object::DisablePropertyNotifications()
764 if( mPropertyNotifications )
766 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
767 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
769 for( ; iter != endIter; ++iter )
771 GetImplementation(*iter).Disable();
776 void Object::AddUniformMapping( Property::Index propertyIndex, const std::string& uniformName )
778 // Get the address of the property if it's a scene property
779 const PropertyInputImpl* propertyPtr = GetSceneObjectInputProperty( propertyIndex );
781 // Check instead for newly registered properties
782 if( propertyPtr == NULL )
784 PropertyMetadata* animatable = FindAnimatableProperty( propertyIndex );
785 if( animatable != NULL )
787 propertyPtr = animatable->GetSceneGraphProperty();
791 if( propertyPtr == NULL )
793 PropertyMetadata* custom = FindCustomProperty( propertyIndex );
796 propertyPtr = custom->GetSceneGraphProperty();
800 // @todo MESH_REWORK Store mappings for unstaged objects?
802 if( propertyPtr != NULL )
804 const SceneGraph::PropertyOwner* sceneObject = GetPropertyOwner();
806 if( sceneObject != NULL )
808 SceneGraph::UniformPropertyMapping* map = new SceneGraph::UniformPropertyMapping( uniformName, propertyPtr );
809 // Message takes ownership of Uniform map (and will delete it after copy)
810 AddUniformMapMessage( GetEventThreadServices(), *sceneObject, map);
814 // @todo MESH_REWORK FIXME Need to store something that can be sent to the scene
815 // object when staged.
816 DALI_ASSERT_ALWAYS(0 && "MESH_REWORK - Need to store property whilst off-stage" );
821 void Object::RemoveUniformMapping( const std::string& uniformName )
823 const SceneGraph::PropertyOwner* sceneObject = GetSceneObject();
824 RemoveUniformMapMessage( GetEventThreadServices(), *sceneObject, uniformName);
827 Property::Value Object::GetPropertyValue( const PropertyMetadata* entry ) const
829 Property::Value value;
831 DALI_ASSERT_ALWAYS( entry && "Invalid property metadata" );
833 if( !entry->IsAnimatable() )
835 value = entry->value;
839 BufferIndex bufferIndex( GetEventThreadServices().GetEventBufferIndex() );
841 switch ( entry->type )
843 case Property::BOOLEAN:
845 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->GetSceneGraphProperty() );
846 DALI_ASSERT_DEBUG( NULL != property );
848 value = (*property)[ bufferIndex ];
852 case Property::INTEGER:
854 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->GetSceneGraphProperty() );
855 DALI_ASSERT_DEBUG( NULL != property );
857 value = (*property)[ bufferIndex ];
861 case Property::UNSIGNED_INTEGER:
863 const AnimatableProperty<unsigned int>* property = dynamic_cast< const AnimatableProperty<unsigned int>* >( entry->GetSceneGraphProperty() );
864 DALI_ASSERT_DEBUG( NULL != property );
866 value = (*property)[ bufferIndex ];
870 case Property::FLOAT:
872 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->GetSceneGraphProperty() );
873 DALI_ASSERT_DEBUG( NULL != property );
875 value = (*property)[ bufferIndex ];
879 case Property::VECTOR2:
881 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->GetSceneGraphProperty() );
882 DALI_ASSERT_DEBUG( NULL != property );
884 value = (*property)[ bufferIndex ];
888 case Property::VECTOR3:
890 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->GetSceneGraphProperty() );
891 DALI_ASSERT_DEBUG( NULL != property );
893 value = (*property)[ bufferIndex ];
897 case Property::VECTOR4:
899 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->GetSceneGraphProperty() );
900 DALI_ASSERT_DEBUG( NULL != property );
902 value = (*property)[ bufferIndex ];
906 case Property::MATRIX:
908 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->GetSceneGraphProperty() );
909 DALI_ASSERT_DEBUG( NULL != property );
911 value = (*property)[ bufferIndex ];
915 case Property::MATRIX3:
917 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->GetSceneGraphProperty() );
918 DALI_ASSERT_DEBUG( NULL != property );
920 value = (*property)[ bufferIndex ];
924 case Property::ROTATION:
926 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->GetSceneGraphProperty() );
927 DALI_ASSERT_DEBUG( NULL != property );
929 value = (*property)[ bufferIndex ];
935 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
944 void Object::SetSceneGraphProperty( Property::Index index, const PropertyMetadata& entry, const Property::Value& value )
946 switch ( entry.type )
948 case Property::BOOLEAN:
950 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
951 DALI_ASSERT_DEBUG( NULL != property );
953 // property is being used in a separate thread; queue a message to set the property
954 BakeMessage<bool>( GetEventThreadServices(), *property, value.Get<bool>() );
958 case Property::INTEGER:
960 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
961 DALI_ASSERT_DEBUG( NULL != property );
963 // property is being used in a separate thread; queue a message to set the property
964 BakeMessage<int>( GetEventThreadServices(), *property, value.Get<int>() );
968 case Property::UNSIGNED_INTEGER:
970 const AnimatableProperty<unsigned int>* property = dynamic_cast< const AnimatableProperty<unsigned int>* >( entry.GetSceneGraphProperty() );
971 DALI_ASSERT_DEBUG( NULL != property );
973 // property is being used in a separate thread; queue a message to set the property
974 BakeMessage<unsigned int>( GetEventThreadServices(), *property, value.Get<unsigned int>() );
978 case Property::FLOAT:
980 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
981 DALI_ASSERT_DEBUG( NULL != property );
983 // property is being used in a separate thread; queue a message to set the property
984 BakeMessage<float>( GetEventThreadServices(), *property, value.Get<float>() );
988 case Property::VECTOR2:
990 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
991 DALI_ASSERT_DEBUG( NULL != property );
993 // property is being used in a separate thread; queue a message to set the property
994 BakeMessage<Vector2>( GetEventThreadServices(), *property, value.Get<Vector2>() );
998 case Property::VECTOR3:
1000 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
1001 DALI_ASSERT_DEBUG( NULL != property );
1003 // property is being used in a separate thread; queue a message to set the property
1004 BakeMessage<Vector3>( GetEventThreadServices(), *property, value.Get<Vector3>() );
1008 case Property::VECTOR4:
1010 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
1011 DALI_ASSERT_DEBUG( NULL != property );
1013 // property is being used in a separate thread; queue a message to set the property
1014 BakeMessage<Vector4>( GetEventThreadServices(), *property, value.Get<Vector4>() );
1018 case Property::ROTATION:
1020 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
1021 DALI_ASSERT_DEBUG( NULL != property );
1023 // property is being used in a separate thread; queue a message to set the property
1024 BakeMessage<Quaternion>( GetEventThreadServices(), *property, value.Get<Quaternion>() );
1028 case Property::MATRIX:
1030 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
1031 DALI_ASSERT_DEBUG( NULL != property );
1033 // property is being used in a separate thread; queue a message to set the property
1034 BakeMessage<Matrix>( GetEventThreadServices(), *property, value.Get<Matrix>() );
1038 case Property::MATRIX3:
1040 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
1041 DALI_ASSERT_DEBUG( NULL != property );
1043 // property is being used in a separate thread; queue a message to set the property
1044 BakeMessage<Matrix3>( GetEventThreadServices(), *property, value.Get<Matrix3>() );
1050 // non-animatable scene graph property, do nothing
1055 const TypeInfo* Object::GetTypeInfo() const
1059 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
1060 // especially as the type-info does not change during the life-time of an application
1062 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
1063 if ( typeInfoHandle )
1065 mTypeInfo = &GetImplementation( typeInfoHandle );
1072 void Object::ApplyConstraint( ConstraintBase& constraint )
1076 mConstraints = new ConstraintContainer;
1078 mConstraints->push_back( Dali::Constraint( &constraint ) );
1081 void Object::RemoveConstraint( ConstraintBase& constraint )
1083 // NULL if the Constraint sources are destroyed before Constraint::Apply()
1086 ConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), Dali::Constraint( &constraint ) ) );
1087 if( it != mConstraints->end() )
1089 mConstraints->erase( it );
1094 void Object::RemoveConstraints()
1096 // guard against constraint sending messages during core destruction
1097 if( mConstraints && Stage::IsInstalled() )
1099 // If we have nothing in the scene-graph, just clear constraint containers
1100 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
1101 if ( NULL != propertyOwner )
1103 const ConstraintConstIter endIter = mConstraints->end();
1104 for ( ConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1106 GetImplementation( *iter ).RemoveInternal();
1110 delete mConstraints;
1111 mConstraints = NULL;
1115 void Object::RemoveConstraints( unsigned int tag )
1117 // guard against constraint sending messages during core destruction
1118 if( mConstraints && Stage::IsInstalled() )
1120 ConstraintIter iter( mConstraints->begin() );
1121 while(iter != mConstraints->end() )
1123 ConstraintBase& constraint = GetImplementation( *iter );
1124 if( constraint.GetTag() == tag )
1126 GetImplementation( *iter ).RemoveInternal();
1127 iter = mConstraints->erase( iter );
1135 if ( mConstraints->empty() )
1137 delete mConstraints;
1138 mConstraints = NULL;
1143 void Object::SetTypeInfo( const TypeInfo* typeInfo )
1145 mTypeInfo = typeInfo;
1150 // Notification for observers
1151 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1153 (*iter)->ObjectDestroyed(*this);
1156 delete mConstraints;
1157 delete mPropertyNotifications;
1160 CustomPropertyMetadata* Object::FindCustomProperty( Property::Index index ) const
1162 CustomPropertyMetadata* property( NULL );
1163 int arrayIndex = index - PROPERTY_CUSTOM_START_INDEX;
1164 if( arrayIndex >= 0 )
1166 if( arrayIndex < (int)mCustomProperties.Count() ) // we can only access the first 2 billion custom properties
1168 property = static_cast<CustomPropertyMetadata*>(mCustomProperties[ arrayIndex ]);
1174 AnimatablePropertyMetadata* Object::FindAnimatableProperty( Property::Index index ) const
1176 for ( int arrayIndex = 0; arrayIndex < (int)mAnimatableProperties.Count(); arrayIndex++ )
1178 AnimatablePropertyMetadata* property = static_cast<AnimatablePropertyMetadata*>( mAnimatableProperties[ arrayIndex ] );
1179 if( property->index == index )
1187 } // namespace Internal