2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/event/common/proxy-object.h>
24 #include <dali/public-api/object/property-index.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/internal/event/common/stage-impl.h>
27 #include <dali/internal/update/common/animatable-property.h>
28 #include <dali/internal/update/animation/scene-graph-constraint-base.h>
29 #include <dali/internal/update/common/property-owner-messages.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/property-notification-impl.h>
33 #include <dali/internal/event/common/property-index-ranges.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; // ProxyObject provides this capability
48 typedef Dali::Vector<ProxyObject::Observer*>::Iterator ObserverIter;
49 typedef Dali::Vector<ProxyObject::Observer*>::ConstIterator ConstObserverIter;
51 static std::string EMPTY_PROPERTY_NAME;
53 #if defined(DEBUG_ENABLED)
54 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_PROXY_OBJECT" );
56 } // unnamed namespace
58 ProxyObject::ProxyObject()
59 : mNextCustomPropertyIndex( 0u ),
60 mCustomProperties( NULL ),
63 mRemovedConstraints( 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 observers
95 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
97 (*iter)->SceneObjectAdded(*this);
100 // enable property notifications in scene graph
101 EnablePropertyNotifications();
104 void ProxyObject::OnSceneObjectRemove()
106 // Notification for observers
107 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
109 (*iter)->SceneObjectRemoved(*this);
112 // disable property notifications in scene graph
113 DisablePropertyNotifications();
116 int ProxyObject::GetPropertyComponentIndex( Property::Index index ) const
118 return Property::INVALID_COMPONENT_INDEX;
121 bool ProxyObject::Supports( Capability capability ) const
123 return (capability & SUPPORTED_CAPABILITIES);
126 unsigned int ProxyObject::GetPropertyCount() const
128 unsigned int count = GetDefaultPropertyCount();
130 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
132 TypeInfo* typeInfo( GetTypeInfo() );
135 unsigned int manual( typeInfo->GetPropertyCount() );
138 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
141 if( mCustomProperties )
143 unsigned int custom( mCustomProperties->size() );
146 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
149 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
154 const std::string& ProxyObject::GetPropertyName( Property::Index index ) const
156 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
158 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
160 return GetDefaultPropertyName( index );
163 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
165 TypeInfo* typeInfo( GetTypeInfo() );
168 return typeInfo->GetPropertyName( index );
172 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
176 if( mCustomProperties )
178 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
179 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Property index is invalid" );
181 return entry->second.name;
183 return EMPTY_PROPERTY_NAME;
186 Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
188 Property::Index index = GetDefaultPropertyIndex( name );
190 if ( index == Property::INVALID_INDEX )
192 TypeInfo* typeInfo( GetTypeInfo() );
195 index = typeInfo->GetPropertyIndex( name );
199 if( index == Property::INVALID_INDEX && mCustomProperties )
201 // This is slow, but we're not (supposed to be) using property names frequently
202 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
204 if (iter->second.name == name)
215 bool ProxyObject::IsPropertyWritable( Property::Index index ) const
217 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
219 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
221 return IsDefaultPropertyWritable( index );
224 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
226 TypeInfo* typeInfo( GetTypeInfo() );
229 return typeInfo->IsPropertyWritable( index );
233 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
237 if( mCustomProperties)
239 // Check that the index is valid
240 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
241 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
243 return entry->second.IsWritable();
248 bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
250 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
252 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
254 return IsDefaultPropertyAnimatable( index );
257 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
259 // Type Registry event-thread only properties are not animatable.
263 if( mCustomProperties )
265 // Check custom property
266 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
267 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
269 return entry->second.IsAnimatable();
274 bool ProxyObject::IsPropertyAConstraintInput(Property::Index index) const
276 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
278 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
280 return IsDefaultPropertyAConstraintInput( index );
283 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
285 // Type Registry event-thread only properties cannot be used as an input to a constraint.
289 if( mCustomProperties )
291 // Check custom property
292 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
293 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
295 // ... custom properties can be used as input to a constraint.
301 Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
303 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
305 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
307 return GetDefaultPropertyType( index );
310 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
312 TypeInfo* typeInfo( GetTypeInfo() );
315 return typeInfo->GetPropertyType( index );
319 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
323 if( mCustomProperties )
325 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
326 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find Property index" );
328 return entry->second.type;
330 return Property::NONE;
333 void ProxyObject::SetProperty( Property::Index index, const Property::Value& propertyValue )
335 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
337 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
339 DALI_ASSERT_ALWAYS( IsDefaultPropertyWritable(index) && "Property is read-only" );
341 SetDefaultProperty( index, propertyValue );
343 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
345 TypeInfo* typeInfo( GetTypeInfo() );
348 typeInfo->SetProperty( this, index, propertyValue );
352 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
355 else if( mCustomProperties )
357 CustomPropertyLookup::iterator entry = mCustomProperties->find( index );
358 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
359 DALI_ASSERT_ALWAYS( entry->second.IsWritable() && "Property is read-only" );
361 // this is only relevant for non animatable properties
362 if(entry->second.IsWritable())
364 entry->second.value = propertyValue;
367 SetCustomProperty(index, entry->second, propertyValue);
371 Property::Value ProxyObject::GetProperty(Property::Index index) const
373 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
375 Property::Value value;
377 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
379 value = GetDefaultProperty( index );
381 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
383 TypeInfo* typeInfo( GetTypeInfo() );
386 value = typeInfo->GetProperty( this, index );
390 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
393 else if( mCustomProperties )
395 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
396 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
398 if( !entry->second.IsAnimatable() )
400 value = entry->second.value;
404 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
406 switch ( entry->second.type )
408 case Property::BOOLEAN:
410 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry->second.GetSceneGraphProperty() );
411 DALI_ASSERT_DEBUG( NULL != property );
413 value = (*property)[ bufferIndex ];
417 case Property::FLOAT:
419 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry->second.GetSceneGraphProperty() );
420 DALI_ASSERT_DEBUG( NULL != property );
422 value = (*property)[ bufferIndex ];
426 case Property::VECTOR2:
428 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry->second.GetSceneGraphProperty() );
429 DALI_ASSERT_DEBUG( NULL != property );
431 value = (*property)[ bufferIndex ];
435 case Property::VECTOR3:
437 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry->second.GetSceneGraphProperty() );
438 DALI_ASSERT_DEBUG( NULL != property );
440 value = (*property)[ bufferIndex ];
444 case Property::VECTOR4:
446 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry->second.GetSceneGraphProperty() );
447 DALI_ASSERT_DEBUG( NULL != property );
449 value = (*property)[ bufferIndex ];
453 case Property::MATRIX:
455 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry->second.GetSceneGraphProperty() );
456 DALI_ASSERT_DEBUG( NULL != property );
458 value = (*property)[ bufferIndex ];
462 case Property::MATRIX3:
464 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry->second.GetSceneGraphProperty() );
465 DALI_ASSERT_DEBUG( NULL != property );
467 value = (*property)[ bufferIndex ];
471 case Property::ROTATION:
473 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry->second.GetSceneGraphProperty() );
474 DALI_ASSERT_DEBUG( NULL != property );
476 value = (*property)[ bufferIndex ];
482 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
493 void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
497 // Default Properties
498 GetDefaultPropertyIndices( indices );
501 TypeInfo* typeInfo( GetTypeInfo() );
504 typeInfo->GetPropertyIndices( indices );
508 if ( mCustomProperties )
510 indices.reserve( indices.size() + mCustomProperties->size() );
512 const CustomPropertyLookup::const_iterator endIter = mCustomProperties->end();
513 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); iter != endIter; ++iter )
515 indices.push_back( iter->first );
520 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue)
522 // Assert that property name is unused
523 DALI_ASSERT_ALWAYS( Property::INVALID_INDEX == GetPropertyIndex(name) && "Property index is out of bounds" );
525 // Create a new property
526 std::auto_ptr<PropertyBase> newProperty;
528 switch ( propertyValue.GetType() )
530 case Property::BOOLEAN:
532 newProperty.reset(new AnimatableProperty<bool>( propertyValue.Get<bool>()));
536 case Property::FLOAT:
538 newProperty.reset(new AnimatableProperty<float>( propertyValue.Get<float>()));
542 case Property::VECTOR2:
544 newProperty.reset(new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>()));
548 case Property::VECTOR3:
550 newProperty.reset(new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>()));
554 case Property::VECTOR4:
556 newProperty.reset(new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>()));
560 case Property::MATRIX:
562 newProperty.reset(new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>()));
566 case Property::MATRIX3:
568 newProperty.reset(new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>()));
572 case Property::ROTATION:
574 newProperty.reset(new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>()));
580 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
581 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
586 // Default properties start from index zero
587 if ( 0u == mNextCustomPropertyIndex )
589 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
592 // Add entry to the property lookup
593 const Property::Index index = mNextCustomPropertyIndex++;
595 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
596 DALI_ASSERT_ALWAYS( mCustomProperties->end() == entry && "Custom property already registered" );
598 (*mCustomProperties)[ index ] = CustomProperty( name, propertyValue.GetType(), newProperty.get() );
600 // The derived class now passes ownership of this new property to a scene-object
601 InstallSceneObjectProperty( *(newProperty.release()), name, index );
606 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue, Property::AccessMode accessMode)
608 Property::Index index = Property::INVALID_INDEX;
610 if(Property::ANIMATABLE == accessMode)
612 index = RegisterProperty(name, propertyValue);
616 // Default properties start from index zero
617 if ( 0u == mNextCustomPropertyIndex )
619 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
622 // Add entry to the property lookup
623 index = mNextCustomPropertyIndex++;
624 GetCustomPropertyLookup()[ index ] = CustomProperty( name, propertyValue, accessMode );
630 Dali::PropertyNotification ProxyObject::AddPropertyNotification(Property::Index index,
632 const Dali::PropertyCondition& condition)
634 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
636 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
638 DALI_ASSERT_ALWAYS( false && "Property notification added to non animatable property." );
640 else if ( mCustomProperties )
642 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
643 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
645 DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "Property notification added to non animatable property (currently not suppported )");
649 Dali::Handle self(this);
650 Property target( self, index );
652 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
653 Dali::PropertyNotification propertyNotification(internal.Get());
655 if( !mPropertyNotifications )
657 mPropertyNotifications = new PropertyNotificationContainer;
659 mPropertyNotifications->push_back(propertyNotification);
661 return propertyNotification;
664 void ProxyObject::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
666 if( mPropertyNotifications )
668 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
669 while(iter != mPropertyNotifications->end() )
671 if(*iter == propertyNotification)
673 mPropertyNotifications->erase(iter);
674 // As we can't ensure all references are removed, we can just disable
676 GetImplementation(propertyNotification).Disable();
684 void ProxyObject::RemovePropertyNotifications()
686 if( mPropertyNotifications )
688 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
689 while(iter != mPropertyNotifications->end() )
691 // As we can't ensure all references are removed, we can just disable
693 GetImplementation(*iter).Disable();
697 mPropertyNotifications->clear();
701 void ProxyObject::EnablePropertyNotifications()
703 if( mPropertyNotifications )
705 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
706 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
708 for( ; iter != endIter; ++iter )
710 GetImplementation(*iter).Enable();
715 void ProxyObject::DisablePropertyNotifications()
717 if( mPropertyNotifications )
719 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
720 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
722 for( ; iter != endIter; ++iter )
724 GetImplementation(*iter).Disable();
729 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint )
731 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Constrainable() ) );
734 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
736 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
739 ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
741 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
742 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
744 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
748 ProxyObject& weightObjectImpl = GetImplementation( weightObject );
749 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
751 if( Property::INVALID_INDEX != weightIndex )
753 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
759 mConstraints = new ActiveConstraintContainer;
761 mConstraints->push_back( activeConstraint );
763 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
765 return activeConstraintImpl;
768 void ProxyObject::DeleteRemovedConstraints()
770 if( ! mRemovedConstraints )
775 // Discard constraints which are fully removed
776 for ( ActiveConstraintIter iter = mRemovedConstraints->begin(); mRemovedConstraints->end() != iter ;)
778 if ( !( GetImplementation( *iter ).IsRemoving() ) )
780 iter = mRemovedConstraints->erase( iter );
789 void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
791 switch ( entry.type )
793 case Property::BOOLEAN:
795 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
796 DALI_ASSERT_DEBUG( NULL != property );
798 // property is being used in a separate thread; queue a message to set the property
799 BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
803 case Property::FLOAT:
805 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
806 DALI_ASSERT_DEBUG( NULL != property );
808 // property is being used in a separate thread; queue a message to set the property
809 BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
813 case Property::VECTOR2:
815 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
816 DALI_ASSERT_DEBUG( NULL != property );
818 // property is being used in a separate thread; queue a message to set the property
819 BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
823 case Property::VECTOR3:
825 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
826 DALI_ASSERT_DEBUG( NULL != property );
828 // property is being used in a separate thread; queue a message to set the property
829 BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
833 case Property::VECTOR4:
835 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
836 DALI_ASSERT_DEBUG( NULL != property );
838 // property is being used in a separate thread; queue a message to set the property
839 BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
843 case Property::ROTATION:
845 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
846 DALI_ASSERT_DEBUG( NULL != property );
848 // property is being used in a separate thread; queue a message to set the property
849 BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
853 case Property::MATRIX:
855 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
856 DALI_ASSERT_DEBUG( NULL != property );
858 // property is being used in a separate thread; queue a message to set the property
859 BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
863 case Property::MATRIX3:
865 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
866 DALI_ASSERT_DEBUG( NULL != property );
868 // property is being used in a separate thread; queue a message to set the property
869 BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
875 DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds"); // should not come here
881 CustomPropertyLookup& ProxyObject::GetCustomPropertyLookup() const
884 if( !mCustomProperties )
886 mCustomProperties = new CustomPropertyLookup;
888 return *mCustomProperties;
891 TypeInfo* ProxyObject::GetTypeInfo() const
895 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
896 // especially as the type-info does not change during the life-time of an application
898 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
899 if ( typeInfoHandle )
901 mTypeInfo = &GetImplementation( typeInfoHandle );
908 void ProxyObject::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
912 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
913 baseConstraint.BeginRemove();
914 if ( baseConstraint.IsRemoving() )
916 if( !mRemovedConstraints )
918 mRemovedConstraints = new ActiveConstraintContainer;
920 // Wait for remove animation before destroying active-constraints
921 mRemovedConstraints->push_back( constraint );
924 else if( mRemovedConstraints )
926 delete mRemovedConstraints;
927 mRemovedConstraints = NULL;
932 void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
936 bool isInSceneGraph( NULL != GetSceneObject() );
939 DeleteRemovedConstraints();
942 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
943 if( it != mConstraints->end() )
945 RemoveConstraint( *it, isInSceneGraph );
946 mConstraints->erase( it );
954 void ProxyObject::RemoveConstraints( unsigned int tag )
958 bool isInSceneGraph( NULL != GetSceneObject() );
961 DeleteRemovedConstraints();
964 ActiveConstraintIter iter( mConstraints->begin() );
965 while(iter != mConstraints->end() )
967 ActiveConstraintBase& constraint = GetImplementation( *iter );
968 if( constraint.GetTag() == tag )
970 RemoveConstraint( *iter, isInSceneGraph );
971 iter = mConstraints->erase( iter );
981 void ProxyObject::RemoveConstraints()
985 // If we have nothing in the scene-graph, just clear constraint containers
986 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
987 if ( NULL == propertyOwner )
989 delete mRemovedConstraints;
990 mRemovedConstraints = NULL;
994 // Discard constraints which are fully removed
995 DeleteRemovedConstraints();
997 const ActiveConstraintConstIter endIter = mConstraints->end();
998 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1000 RemoveConstraint( *iter, true );
1004 delete mConstraints;
1005 mConstraints = NULL;
1009 void ProxyObject::SetTypeInfo( TypeInfo* typeInfo )
1011 mTypeInfo = typeInfo;
1014 ProxyObject::~ProxyObject()
1016 // Notification for observers
1017 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1019 (*iter)->ProxyDestroyed(*this);
1022 delete mCustomProperties;
1023 delete mConstraints;
1024 delete mRemovedConstraints;
1025 delete mPropertyNotifications;
1028 } // namespace Internal