2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/event/common/proxy-object.h>
25 #include <dali/public-api/object/property-index.h>
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/event/common/stage-impl.h>
28 #include <dali/internal/update/common/animatable-property.h>
29 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
30 #include <dali/internal/update/common/property-owner-messages.h>
31 #include <dali/internal/event/animation/active-constraint-base.h>
32 #include <dali/internal/event/animation/constraint-impl.h>
33 #include <dali/internal/event/common/property-notification-impl.h>
34 #include <dali/internal/event/common/property-index-ranges.h>
35 #include <dali/internal/event/common/type-registry-impl.h>
37 using Dali::Internal::SceneGraph::AnimatableProperty;
38 using Dali::Internal::SceneGraph::PropertyBase;
46 namespace // unnamed namespace
48 const int SUPPORTED_CAPABILITIES = Dali::Handle::DYNAMIC_PROPERTIES; // ProxyObject provides this capability
49 typedef Dali::Vector<ProxyObject::Observer*>::Iterator ObserverIter;
50 typedef Dali::Vector<ProxyObject::Observer*>::ConstIterator ConstObserverIter;
52 static std::string EMPTY_PROPERTY_NAME;
54 #if defined(DEBUG_ENABLED)
55 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PROXY_OBJECT" );
57 } // unnamed namespace
59 ProxyObject::ProxyObject()
60 : mNextCustomPropertyIndex( 0u ),
61 mCustomProperties( NULL ),
64 mPropertyNotifications( NULL )
68 void ProxyObject::AddObserver(Observer& observer)
70 // make sure an observer doesn't observe the same object twice
71 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ProxyDestroyed()
72 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
74 mObservers.PushBack( &observer );
77 void ProxyObject::RemoveObserver(Observer& observer)
79 // Find the observer...
80 const ConstObserverIter endIter = mObservers.End();
81 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
83 if( (*iter) == &observer)
85 mObservers.Erase( iter );
89 DALI_ASSERT_DEBUG(endIter != mObservers.End());
92 void ProxyObject::OnSceneObjectAdd()
94 // Notification for this object's constraints
97 const ActiveConstraintConstIter endIter = mConstraints->end();
98 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
100 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
101 baseConstraint.OnParentSceneObjectAdded();
105 // Notification for observers
106 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
108 (*iter)->SceneObjectAdded(*this);
111 // enable property notifications in scene graph
112 EnablePropertyNotifications();
115 void ProxyObject::OnSceneObjectRemove()
117 // Notification for this object's constraints
120 const ActiveConstraintConstIter endIter = mConstraints->end();
121 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
123 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
124 baseConstraint.OnParentSceneObjectRemoved();
128 // Notification for observers
129 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
131 (*iter)->SceneObjectRemoved(*this);
134 // disable property notifications in scene graph
135 DisablePropertyNotifications();
138 int ProxyObject::GetPropertyComponentIndex( Property::Index index ) const
140 return Property::INVALID_COMPONENT_INDEX;
143 bool ProxyObject::Supports( Capability capability ) const
145 return (capability & SUPPORTED_CAPABILITIES);
148 unsigned int ProxyObject::GetPropertyCount() const
150 unsigned int count = GetDefaultPropertyCount();
152 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
154 const TypeInfo* typeInfo( GetTypeInfo() );
157 unsigned int manual( typeInfo->GetPropertyCount() );
160 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
163 if( mCustomProperties )
165 unsigned int custom( mCustomProperties->size() );
168 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
171 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
176 const std::string& ProxyObject::GetPropertyName( Property::Index index ) const
178 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
180 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
182 return GetDefaultPropertyName( index );
185 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
187 const TypeInfo* typeInfo( GetTypeInfo() );
190 return typeInfo->GetPropertyName( index );
194 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
198 if( mCustomProperties )
200 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
201 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Property index is invalid" );
203 return entry->second.name;
205 return EMPTY_PROPERTY_NAME;
208 Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
210 Property::Index index = GetDefaultPropertyIndex( name );
212 if ( index == Property::INVALID_INDEX )
214 const TypeInfo* typeInfo( GetTypeInfo() );
217 index = typeInfo->GetPropertyIndex( name );
221 if( index == Property::INVALID_INDEX && mCustomProperties )
223 // This is slow, but we're not (supposed to be) using property names frequently
224 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
226 if (iter->second.name == name)
237 bool ProxyObject::IsPropertyWritable( Property::Index index ) const
239 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
241 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
243 return IsDefaultPropertyWritable( index );
246 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
248 const TypeInfo* typeInfo( GetTypeInfo() );
251 return typeInfo->IsPropertyWritable( index );
255 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
259 if( mCustomProperties)
261 // Check that the index is valid
262 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
263 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
265 return entry->second.IsWritable();
270 bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
272 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
274 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
276 return IsDefaultPropertyAnimatable( index );
279 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
281 // Type Registry event-thread only properties are not animatable.
285 if( mCustomProperties )
287 // Check custom property
288 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
289 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
291 return entry->second.IsAnimatable();
296 bool ProxyObject::IsPropertyAConstraintInput(Property::Index index) const
298 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
300 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
302 return IsDefaultPropertyAConstraintInput( index );
305 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
307 // Type Registry event-thread only properties cannot be used as an input to a constraint.
311 if( mCustomProperties )
313 // Check custom property
314 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
315 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
317 // ... custom properties can be used as input to a constraint.
323 Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
325 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
327 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
329 return GetDefaultPropertyType( index );
332 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
334 const TypeInfo* typeInfo( GetTypeInfo() );
337 return typeInfo->GetPropertyType( index );
341 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
345 if( mCustomProperties )
347 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
348 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find Property index" );
350 return entry->second.type;
352 return Property::NONE;
355 void ProxyObject::SetProperty( Property::Index index, const Property::Value& propertyValue )
357 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
359 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
361 DALI_ASSERT_ALWAYS( IsDefaultPropertyWritable(index) && "Property is read-only" );
363 SetDefaultProperty( index, propertyValue );
365 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
367 const TypeInfo* typeInfo( GetTypeInfo() );
370 typeInfo->SetProperty( this, index, propertyValue );
374 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
377 else if( mCustomProperties )
379 CustomPropertyLookup::iterator entry = mCustomProperties->find( index );
380 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
381 DALI_ASSERT_ALWAYS( entry->second.IsWritable() && "Property is read-only" );
383 // this is only relevant for non animatable properties
384 if(entry->second.IsWritable())
386 entry->second.value = propertyValue;
389 SetCustomProperty(index, entry->second, propertyValue);
393 Property::Value ProxyObject::GetProperty(Property::Index index) const
395 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
397 Property::Value value;
399 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
401 value = GetDefaultProperty( index );
403 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
405 const TypeInfo* typeInfo( GetTypeInfo() );
408 value = typeInfo->GetProperty( this, index );
412 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
415 else if( mCustomProperties )
417 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
418 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
420 if( !entry->second.IsAnimatable() )
422 value = entry->second.value;
426 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
428 switch ( entry->second.type )
430 case Property::BOOLEAN:
432 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry->second.GetSceneGraphProperty() );
433 DALI_ASSERT_DEBUG( NULL != property );
435 value = (*property)[ bufferIndex ];
439 case Property::FLOAT:
441 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry->second.GetSceneGraphProperty() );
442 DALI_ASSERT_DEBUG( NULL != property );
444 value = (*property)[ bufferIndex ];
448 case Property::INTEGER:
450 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry->second.GetSceneGraphProperty() );
451 DALI_ASSERT_DEBUG( NULL != property );
453 value = (*property)[ bufferIndex ];
457 case Property::VECTOR2:
459 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry->second.GetSceneGraphProperty() );
460 DALI_ASSERT_DEBUG( NULL != property );
462 value = (*property)[ bufferIndex ];
466 case Property::VECTOR3:
468 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry->second.GetSceneGraphProperty() );
469 DALI_ASSERT_DEBUG( NULL != property );
471 value = (*property)[ bufferIndex ];
475 case Property::VECTOR4:
477 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry->second.GetSceneGraphProperty() );
478 DALI_ASSERT_DEBUG( NULL != property );
480 value = (*property)[ bufferIndex ];
484 case Property::MATRIX:
486 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry->second.GetSceneGraphProperty() );
487 DALI_ASSERT_DEBUG( NULL != property );
489 value = (*property)[ bufferIndex ];
493 case Property::MATRIX3:
495 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry->second.GetSceneGraphProperty() );
496 DALI_ASSERT_DEBUG( NULL != property );
498 value = (*property)[ bufferIndex ];
502 case Property::ROTATION:
504 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry->second.GetSceneGraphProperty() );
505 DALI_ASSERT_DEBUG( NULL != property );
507 value = (*property)[ bufferIndex ];
513 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
524 void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
528 // Default Properties
529 GetDefaultPropertyIndices( indices );
532 const TypeInfo* typeInfo( GetTypeInfo() );
535 typeInfo->GetPropertyIndices( indices );
539 if ( mCustomProperties )
541 indices.reserve( indices.size() + mCustomProperties->size() );
543 const CustomPropertyLookup::const_iterator endIter = mCustomProperties->end();
544 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); iter != endIter; ++iter )
546 indices.push_back( iter->first );
551 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue)
553 // Assert that property name is unused
554 DALI_ASSERT_ALWAYS( Property::INVALID_INDEX == GetPropertyIndex(name) && "Property index is out of bounds" );
556 // Create a new property
557 std::auto_ptr<PropertyBase> newProperty;
559 switch ( propertyValue.GetType() )
561 case Property::BOOLEAN:
563 newProperty.reset(new AnimatableProperty<bool>( propertyValue.Get<bool>()));
567 case Property::FLOAT:
569 newProperty.reset(new AnimatableProperty<float>( propertyValue.Get<float>()));
573 case Property::INTEGER:
575 newProperty.reset(new AnimatableProperty<int>( propertyValue.Get<int>()));
579 case Property::VECTOR2:
581 newProperty.reset(new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>()));
585 case Property::VECTOR3:
587 newProperty.reset(new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>()));
591 case Property::VECTOR4:
593 newProperty.reset(new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>()));
597 case Property::MATRIX:
599 newProperty.reset(new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>()));
603 case Property::MATRIX3:
605 newProperty.reset(new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>()));
609 case Property::ROTATION:
611 newProperty.reset(new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>()));
615 case Property::UNSIGNED_INTEGER:
616 case Property::RECTANGLE:
617 case Property::STRING:
618 case Property::ARRAY:
621 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
622 DALI_ASSERT_ALWAYS( false && "PropertyType is not animatable" );
628 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
629 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
634 // Default properties start from index zero
635 if ( 0u == mNextCustomPropertyIndex )
637 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
640 // Add entry to the property lookup
641 const Property::Index index = mNextCustomPropertyIndex++;
643 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
644 DALI_ASSERT_ALWAYS( mCustomProperties->end() == entry && "Custom property already registered" );
646 (*mCustomProperties)[ index ] = CustomProperty( name, propertyValue.GetType(), newProperty.get() );
648 // The derived class now passes ownership of this new property to a scene-object
649 InstallSceneObjectProperty( *(newProperty.release()), name, index );
654 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue, Property::AccessMode accessMode)
656 Property::Index index = Property::INVALID_INDEX;
658 if(Property::ANIMATABLE == accessMode)
660 index = RegisterProperty(name, propertyValue);
664 // Default properties start from index zero
665 if ( 0u == mNextCustomPropertyIndex )
667 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
670 // Add entry to the property lookup
671 index = mNextCustomPropertyIndex++;
672 GetCustomPropertyLookup()[ index ] = CustomProperty( name, propertyValue, accessMode );
678 Dali::PropertyNotification ProxyObject::AddPropertyNotification(Property::Index index,
680 const Dali::PropertyCondition& condition)
682 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
684 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
686 DALI_ASSERT_ALWAYS( false && "Property notification added to non animatable property." );
688 else if ( mCustomProperties )
690 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
691 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
693 DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "Property notification added to non animatable property (currently not suppported )");
697 Dali::Handle self(this);
698 Property target( self, index );
700 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
701 Dali::PropertyNotification propertyNotification(internal.Get());
703 if( !mPropertyNotifications )
705 mPropertyNotifications = new PropertyNotificationContainer;
707 mPropertyNotifications->push_back(propertyNotification);
709 return propertyNotification;
712 void ProxyObject::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
714 if( mPropertyNotifications )
716 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
717 while(iter != mPropertyNotifications->end() )
719 if(*iter == propertyNotification)
721 mPropertyNotifications->erase(iter);
722 // As we can't ensure all references are removed, we can just disable
724 GetImplementation(propertyNotification).Disable();
732 void ProxyObject::RemovePropertyNotifications()
734 if( mPropertyNotifications )
736 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
737 while(iter != mPropertyNotifications->end() )
739 // As we can't ensure all references are removed, we can just disable
741 GetImplementation(*iter).Disable();
745 mPropertyNotifications->clear();
749 void ProxyObject::EnablePropertyNotifications()
751 if( mPropertyNotifications )
753 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
754 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
756 for( ; iter != endIter; ++iter )
758 GetImplementation(*iter).Enable();
763 void ProxyObject::DisablePropertyNotifications()
765 if( mPropertyNotifications )
767 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
768 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
770 for( ; iter != endIter; ++iter )
772 GetImplementation(*iter).Disable();
777 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint )
779 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Constrainable() ) );
782 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
784 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
787 ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
789 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
790 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
792 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
796 ProxyObject& weightObjectImpl = GetImplementation( weightObject );
797 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
799 if( Property::INVALID_INDEX != weightIndex )
801 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
807 mConstraints = new ActiveConstraintContainer;
809 mConstraints->push_back( activeConstraint );
811 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
813 return activeConstraintImpl;
816 void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
818 if( entry.IsAnimatable() )
820 switch ( entry.type )
822 case Property::BOOLEAN:
824 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
825 DALI_ASSERT_DEBUG( NULL != property );
827 // property is being used in a separate thread; queue a message to set the property
828 BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
832 case Property::FLOAT:
834 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
835 DALI_ASSERT_DEBUG( NULL != property );
837 // property is being used in a separate thread; queue a message to set the property
838 BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
842 case Property::INTEGER:
844 AnimatableProperty<int>* property = dynamic_cast< AnimatableProperty<int>* >( entry.GetSceneGraphProperty() );
845 DALI_ASSERT_DEBUG( NULL != property );
847 // property is being used in a separate thread; queue a message to set the property
848 BakeMessage<int>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<int>() );
852 case Property::VECTOR2:
854 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
855 DALI_ASSERT_DEBUG( NULL != property );
857 // property is being used in a separate thread; queue a message to set the property
858 BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
862 case Property::VECTOR3:
864 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
865 DALI_ASSERT_DEBUG( NULL != property );
867 // property is being used in a separate thread; queue a message to set the property
868 BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
872 case Property::VECTOR4:
874 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
875 DALI_ASSERT_DEBUG( NULL != property );
877 // property is being used in a separate thread; queue a message to set the property
878 BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
882 case Property::ROTATION:
884 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
885 DALI_ASSERT_DEBUG( NULL != property );
887 // property is being used in a separate thread; queue a message to set the property
888 BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
892 case Property::MATRIX:
894 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
895 DALI_ASSERT_DEBUG( NULL != property );
897 // property is being used in a separate thread; queue a message to set the property
898 BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
902 case Property::MATRIX3:
904 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
905 DALI_ASSERT_DEBUG( NULL != property );
907 // property is being used in a separate thread; queue a message to set the property
908 BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
914 DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds"); // should not come here
921 CustomPropertyLookup& ProxyObject::GetCustomPropertyLookup() const
924 if( !mCustomProperties )
926 mCustomProperties = new CustomPropertyLookup;
928 return *mCustomProperties;
931 const TypeInfo* ProxyObject::GetTypeInfo() const
935 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
936 // especially as the type-info does not change during the life-time of an application
938 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
939 if ( typeInfoHandle )
941 mTypeInfo = &GetImplementation( typeInfoHandle );
948 void ProxyObject::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
950 // guard against constraint sending messages during core destruction
951 if ( Stage::IsInstalled() )
955 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
956 baseConstraint.BeginRemove();
961 void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
963 // guard against constraint sending messages during core destruction
964 if( mConstraints && Stage::IsInstalled() )
966 bool isInSceneGraph( NULL != GetSceneObject() );
968 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
969 if( it != mConstraints->end() )
971 RemoveConstraint( *it, isInSceneGraph );
972 mConstraints->erase( it );
977 void ProxyObject::RemoveConstraints( unsigned int tag )
979 // guard against constraint sending messages during core destruction
980 if( mConstraints && Stage::IsInstalled() )
982 bool isInSceneGraph( NULL != GetSceneObject() );
984 ActiveConstraintIter iter( mConstraints->begin() );
985 while(iter != mConstraints->end() )
987 ActiveConstraintBase& constraint = GetImplementation( *iter );
988 if( constraint.GetTag() == tag )
990 RemoveConstraint( *iter, isInSceneGraph );
991 iter = mConstraints->erase( iter );
1001 void ProxyObject::RemoveConstraints()
1003 // guard against constraint sending messages during core destruction
1004 if( mConstraints && Stage::IsInstalled() )
1006 // If we have nothing in the scene-graph, just clear constraint containers
1007 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
1008 if ( NULL != propertyOwner )
1010 const ActiveConstraintConstIter endIter = mConstraints->end();
1011 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1013 RemoveConstraint( *iter, true );
1017 delete mConstraints;
1018 mConstraints = NULL;
1022 void ProxyObject::SetTypeInfo( const TypeInfo* typeInfo )
1024 mTypeInfo = typeInfo;
1027 ProxyObject::~ProxyObject()
1029 // Notification for this object's constraints
1030 // (note that the ActiveConstraint handles may outlive the ProxyObject)
1033 const ActiveConstraintConstIter endIter = mConstraints->end();
1034 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1036 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
1037 baseConstraint.OnParentDestroyed();
1041 // Notification for observers
1042 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1044 (*iter)->ProxyDestroyed(*this);
1047 delete mCustomProperties;
1048 delete mConstraints;
1049 delete mPropertyNotifications;
1052 } // namespace Internal