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 mRemovedConstraints( NULL ),
65 mPropertyNotifications( NULL )
69 void ProxyObject::AddObserver(Observer& observer)
71 // make sure an observer doesn't observe the same object twice
72 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ProxyDestroyed()
73 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
75 mObservers.PushBack( &observer );
78 void ProxyObject::RemoveObserver(Observer& observer)
80 // Find the observer...
81 const ConstObserverIter endIter = mObservers.End();
82 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
84 if( (*iter) == &observer)
86 mObservers.Erase( iter );
90 DALI_ASSERT_DEBUG(endIter != mObservers.End());
93 void ProxyObject::OnSceneObjectAdd()
95 // Notification for observers
96 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
98 (*iter)->SceneObjectAdded(*this);
101 // enable property notifications in scene graph
102 EnablePropertyNotifications();
105 void ProxyObject::OnSceneObjectRemove()
107 // Notification for observers
108 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
110 (*iter)->SceneObjectRemoved(*this);
113 // disable property notifications in scene graph
114 DisablePropertyNotifications();
117 int ProxyObject::GetPropertyComponentIndex( Property::Index index ) const
119 return Property::INVALID_COMPONENT_INDEX;
122 bool ProxyObject::Supports( Capability capability ) const
124 return (capability & SUPPORTED_CAPABILITIES);
127 unsigned int ProxyObject::GetPropertyCount() const
129 unsigned int count = GetDefaultPropertyCount();
131 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
133 TypeInfo* typeInfo( GetTypeInfo() );
136 unsigned int manual( typeInfo->GetPropertyCount() );
139 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
142 if( mCustomProperties )
144 unsigned int custom( mCustomProperties->size() );
147 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
150 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
155 const std::string& ProxyObject::GetPropertyName( Property::Index index ) const
157 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
159 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
161 return GetDefaultPropertyName( index );
164 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
166 TypeInfo* typeInfo( GetTypeInfo() );
169 return typeInfo->GetPropertyName( index );
173 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
177 if( mCustomProperties )
179 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
180 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Property index is invalid" );
182 return entry->second.name;
184 return EMPTY_PROPERTY_NAME;
187 Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
189 Property::Index index = GetDefaultPropertyIndex( name );
191 if ( index == Property::INVALID_INDEX )
193 TypeInfo* typeInfo( GetTypeInfo() );
196 index = typeInfo->GetPropertyIndex( name );
200 if( index == Property::INVALID_INDEX && mCustomProperties )
202 // This is slow, but we're not (supposed to be) using property names frequently
203 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
205 if (iter->second.name == name)
216 bool ProxyObject::IsPropertyWritable( Property::Index index ) const
218 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
220 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
222 return IsDefaultPropertyWritable( index );
225 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
227 TypeInfo* typeInfo( GetTypeInfo() );
230 return typeInfo->IsPropertyWritable( index );
234 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
238 if( mCustomProperties)
240 // Check that the index is valid
241 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
242 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
244 return entry->second.IsWritable();
249 bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
251 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
253 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
255 return IsDefaultPropertyAnimatable( index );
258 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
260 // Type Registry event-thread only properties are not animatable.
264 if( mCustomProperties )
266 // Check custom property
267 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
268 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
270 return entry->second.IsAnimatable();
275 bool ProxyObject::IsPropertyAConstraintInput(Property::Index index) const
277 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
279 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
281 return IsDefaultPropertyAConstraintInput( index );
284 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
286 // Type Registry event-thread only properties cannot be used as an input to a constraint.
290 if( mCustomProperties )
292 // Check custom property
293 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
294 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
296 // ... custom properties can be used as input to a constraint.
302 Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
304 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
306 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
308 return GetDefaultPropertyType( index );
311 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
313 TypeInfo* typeInfo( GetTypeInfo() );
316 return typeInfo->GetPropertyType( index );
320 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
324 if( mCustomProperties )
326 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
327 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find Property index" );
329 return entry->second.type;
331 return Property::NONE;
334 void ProxyObject::SetProperty( Property::Index index, const Property::Value& propertyValue )
336 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
338 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
340 DALI_ASSERT_ALWAYS( IsDefaultPropertyWritable(index) && "Property is read-only" );
342 SetDefaultProperty( index, propertyValue );
344 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
346 TypeInfo* typeInfo( GetTypeInfo() );
349 typeInfo->SetProperty( this, index, propertyValue );
353 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
356 else if( mCustomProperties )
358 CustomPropertyLookup::iterator entry = mCustomProperties->find( index );
359 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
360 DALI_ASSERT_ALWAYS( entry->second.IsWritable() && "Property is read-only" );
362 // this is only relevant for non animatable properties
363 if(entry->second.IsWritable())
365 entry->second.value = propertyValue;
368 SetCustomProperty(index, entry->second, propertyValue);
372 Property::Value ProxyObject::GetProperty(Property::Index index) const
374 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
376 Property::Value value;
378 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
380 value = GetDefaultProperty( index );
382 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
384 TypeInfo* typeInfo( GetTypeInfo() );
387 value = typeInfo->GetProperty( this, index );
391 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
394 else if( mCustomProperties )
396 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
397 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
399 if( !entry->second.IsAnimatable() )
401 value = entry->second.value;
405 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
407 switch ( entry->second.type )
409 case Property::BOOLEAN:
411 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry->second.GetSceneGraphProperty() );
412 DALI_ASSERT_DEBUG( NULL != property );
414 value = (*property)[ bufferIndex ];
418 case Property::FLOAT:
420 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry->second.GetSceneGraphProperty() );
421 DALI_ASSERT_DEBUG( NULL != property );
423 value = (*property)[ bufferIndex ];
427 case Property::VECTOR2:
429 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry->second.GetSceneGraphProperty() );
430 DALI_ASSERT_DEBUG( NULL != property );
432 value = (*property)[ bufferIndex ];
436 case Property::VECTOR3:
438 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry->second.GetSceneGraphProperty() );
439 DALI_ASSERT_DEBUG( NULL != property );
441 value = (*property)[ bufferIndex ];
445 case Property::VECTOR4:
447 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry->second.GetSceneGraphProperty() );
448 DALI_ASSERT_DEBUG( NULL != property );
450 value = (*property)[ bufferIndex ];
454 case Property::MATRIX:
456 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry->second.GetSceneGraphProperty() );
457 DALI_ASSERT_DEBUG( NULL != property );
459 value = (*property)[ bufferIndex ];
463 case Property::MATRIX3:
465 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry->second.GetSceneGraphProperty() );
466 DALI_ASSERT_DEBUG( NULL != property );
468 value = (*property)[ bufferIndex ];
472 case Property::ROTATION:
474 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry->second.GetSceneGraphProperty() );
475 DALI_ASSERT_DEBUG( NULL != property );
477 value = (*property)[ bufferIndex ];
483 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
494 void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
498 // Default Properties
499 GetDefaultPropertyIndices( indices );
502 TypeInfo* typeInfo( GetTypeInfo() );
505 typeInfo->GetPropertyIndices( indices );
509 if ( mCustomProperties )
511 indices.reserve( indices.size() + mCustomProperties->size() );
513 const CustomPropertyLookup::const_iterator endIter = mCustomProperties->end();
514 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); iter != endIter; ++iter )
516 indices.push_back( iter->first );
521 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue)
523 // Assert that property name is unused
524 DALI_ASSERT_ALWAYS( Property::INVALID_INDEX == GetPropertyIndex(name) && "Property index is out of bounds" );
526 // Create a new property
527 std::auto_ptr<PropertyBase> newProperty;
529 switch ( propertyValue.GetType() )
531 case Property::BOOLEAN:
533 newProperty.reset(new AnimatableProperty<bool>( propertyValue.Get<bool>()));
537 case Property::FLOAT:
539 newProperty.reset(new AnimatableProperty<float>( propertyValue.Get<float>()));
543 case Property::VECTOR2:
545 newProperty.reset(new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>()));
549 case Property::VECTOR3:
551 newProperty.reset(new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>()));
555 case Property::VECTOR4:
557 newProperty.reset(new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>()));
561 case Property::MATRIX:
563 newProperty.reset(new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>()));
567 case Property::MATRIX3:
569 newProperty.reset(new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>()));
573 case Property::ROTATION:
575 newProperty.reset(new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>()));
581 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
582 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
587 // Default properties start from index zero
588 if ( 0u == mNextCustomPropertyIndex )
590 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
593 // Add entry to the property lookup
594 const Property::Index index = mNextCustomPropertyIndex++;
596 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
597 DALI_ASSERT_ALWAYS( mCustomProperties->end() == entry && "Custom property already registered" );
599 (*mCustomProperties)[ index ] = CustomProperty( name, propertyValue.GetType(), newProperty.get() );
601 // The derived class now passes ownership of this new property to a scene-object
602 InstallSceneObjectProperty( *(newProperty.release()), name, index );
607 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue, Property::AccessMode accessMode)
609 Property::Index index = Property::INVALID_INDEX;
611 if(Property::ANIMATABLE == accessMode)
613 index = RegisterProperty(name, propertyValue);
617 // Default properties start from index zero
618 if ( 0u == mNextCustomPropertyIndex )
620 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
623 // Add entry to the property lookup
624 index = mNextCustomPropertyIndex++;
625 GetCustomPropertyLookup()[ index ] = CustomProperty( name, propertyValue, accessMode );
631 Dali::PropertyNotification ProxyObject::AddPropertyNotification(Property::Index index,
633 const Dali::PropertyCondition& condition)
635 if ( index >= DEFAULT_PROPERTY_MAX_COUNT )
637 if ( index <= PROPERTY_REGISTRATION_MAX_INDEX )
639 DALI_ASSERT_ALWAYS( false && "Property notification added to non animatable property." );
641 else if ( mCustomProperties )
643 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
644 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
646 DALI_ASSERT_ALWAYS( entry->second.IsAnimatable() && "Property notification added to non animatable property (currently not suppported )");
650 Dali::Handle self(this);
651 Property target( self, index );
653 PropertyNotificationPtr internal = PropertyNotification::New( target, componentIndex, condition );
654 Dali::PropertyNotification propertyNotification(internal.Get());
656 if( !mPropertyNotifications )
658 mPropertyNotifications = new PropertyNotificationContainer;
660 mPropertyNotifications->push_back(propertyNotification);
662 return propertyNotification;
665 void ProxyObject::RemovePropertyNotification(Dali::PropertyNotification propertyNotification)
667 if( mPropertyNotifications )
669 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
670 while(iter != mPropertyNotifications->end() )
672 if(*iter == propertyNotification)
674 mPropertyNotifications->erase(iter);
675 // As we can't ensure all references are removed, we can just disable
677 GetImplementation(propertyNotification).Disable();
685 void ProxyObject::RemovePropertyNotifications()
687 if( mPropertyNotifications )
689 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
690 while(iter != mPropertyNotifications->end() )
692 // As we can't ensure all references are removed, we can just disable
694 GetImplementation(*iter).Disable();
698 mPropertyNotifications->clear();
702 void ProxyObject::EnablePropertyNotifications()
704 if( mPropertyNotifications )
706 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
707 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
709 for( ; iter != endIter; ++iter )
711 GetImplementation(*iter).Enable();
716 void ProxyObject::DisablePropertyNotifications()
718 if( mPropertyNotifications )
720 PropertyNotificationContainerIter iter = mPropertyNotifications->begin();
721 PropertyNotificationContainerIter endIter = mPropertyNotifications->end();
723 for( ; iter != endIter; ++iter )
725 GetImplementation(*iter).Disable();
730 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint )
732 return Dali::ActiveConstraint( DoApplyConstraint( constraint, Dali::Constrainable() ) );
735 Dali::ActiveConstraint ProxyObject::ApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
737 return Dali::ActiveConstraint( DoApplyConstraint( constraint, weightObject ) );
740 ActiveConstraintBase* ProxyObject::DoApplyConstraint( Constraint& constraint, Dali::Constrainable weightObject )
742 ActiveConstraintBase* activeConstraintImpl = constraint.CreateActiveConstraint();
743 DALI_ASSERT_DEBUG( NULL != activeConstraintImpl );
745 Dali::ActiveConstraint activeConstraint( activeConstraintImpl );
749 ProxyObject& weightObjectImpl = GetImplementation( weightObject );
750 Property::Index weightIndex = weightObjectImpl.GetPropertyIndex( "weight" );
752 if( Property::INVALID_INDEX != weightIndex )
754 activeConstraintImpl->SetCustomWeightObject( weightObjectImpl, weightIndex );
760 mConstraints = new ActiveConstraintContainer;
762 mConstraints->push_back( activeConstraint );
764 activeConstraintImpl->FirstApply( *this, constraint.GetApplyTime() );
766 return activeConstraintImpl;
769 void ProxyObject::DeleteRemovedConstraints()
771 if( ! mRemovedConstraints )
776 // Discard constraints which are fully removed
777 for ( ActiveConstraintIter iter = mRemovedConstraints->begin(); mRemovedConstraints->end() != iter ;)
779 if ( !( GetImplementation( *iter ).IsRemoving() ) )
781 iter = mRemovedConstraints->erase( iter );
790 void ProxyObject::SetCustomProperty( Property::Index index, const CustomProperty& entry, const Property::Value& value )
792 switch ( entry.type )
794 case Property::BOOLEAN:
796 AnimatableProperty<bool>* property = dynamic_cast< AnimatableProperty<bool>* >( entry.GetSceneGraphProperty() );
797 DALI_ASSERT_DEBUG( NULL != property );
799 // property is being used in a separate thread; queue a message to set the property
800 BakeMessage<bool>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<bool>() );
804 case Property::FLOAT:
806 AnimatableProperty<float>* property = dynamic_cast< AnimatableProperty<float>* >( entry.GetSceneGraphProperty() );
807 DALI_ASSERT_DEBUG( NULL != property );
809 // property is being used in a separate thread; queue a message to set the property
810 BakeMessage<float>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<float>() );
814 case Property::VECTOR2:
816 AnimatableProperty<Vector2>* property = dynamic_cast< AnimatableProperty<Vector2>* >( entry.GetSceneGraphProperty() );
817 DALI_ASSERT_DEBUG( NULL != property );
819 // property is being used in a separate thread; queue a message to set the property
820 BakeMessage<Vector2>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector2>() );
824 case Property::VECTOR3:
826 AnimatableProperty<Vector3>* property = dynamic_cast< AnimatableProperty<Vector3>* >( entry.GetSceneGraphProperty() );
827 DALI_ASSERT_DEBUG( NULL != property );
829 // property is being used in a separate thread; queue a message to set the property
830 BakeMessage<Vector3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector3>() );
834 case Property::VECTOR4:
836 AnimatableProperty<Vector4>* property = dynamic_cast< AnimatableProperty<Vector4>* >( entry.GetSceneGraphProperty() );
837 DALI_ASSERT_DEBUG( NULL != property );
839 // property is being used in a separate thread; queue a message to set the property
840 BakeMessage<Vector4>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Vector4>() );
844 case Property::ROTATION:
846 AnimatableProperty<Quaternion>* property = dynamic_cast< AnimatableProperty<Quaternion>* >( entry.GetSceneGraphProperty() );
847 DALI_ASSERT_DEBUG( NULL != property );
849 // property is being used in a separate thread; queue a message to set the property
850 BakeMessage<Quaternion>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Quaternion>() );
854 case Property::MATRIX:
856 AnimatableProperty<Matrix>* property = dynamic_cast< AnimatableProperty<Matrix>* >( entry.GetSceneGraphProperty() );
857 DALI_ASSERT_DEBUG( NULL != property );
859 // property is being used in a separate thread; queue a message to set the property
860 BakeMessage<Matrix>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix>() );
864 case Property::MATRIX3:
866 AnimatableProperty<Matrix3>* property = dynamic_cast< AnimatableProperty<Matrix3>* >( entry.GetSceneGraphProperty() );
867 DALI_ASSERT_DEBUG( NULL != property );
869 // property is being used in a separate thread; queue a message to set the property
870 BakeMessage<Matrix3>( Stage::GetCurrent()->GetUpdateInterface(), *property, value.Get<Matrix3>() );
876 DALI_ASSERT_ALWAYS(false && "Property type enumeration out of bounds"); // should not come here
882 CustomPropertyLookup& ProxyObject::GetCustomPropertyLookup() const
885 if( !mCustomProperties )
887 mCustomProperties = new CustomPropertyLookup;
889 return *mCustomProperties;
892 TypeInfo* ProxyObject::GetTypeInfo() const
896 // This uses a dynamic_cast so can be quite expensive so we only really want to do it once
897 // especially as the type-info does not change during the life-time of an application
899 Dali::TypeInfo typeInfoHandle = TypeRegistry::Get()->GetTypeInfo( this );
900 if ( typeInfoHandle )
902 mTypeInfo = &GetImplementation( typeInfoHandle );
909 void ProxyObject::RemoveConstraint( ActiveConstraint& constraint, bool isInScenegraph )
911 // guard against constraint sending messages during core destruction
912 if ( Stage::IsInstalled() )
916 ActiveConstraintBase& baseConstraint = GetImplementation( constraint );
917 baseConstraint.BeginRemove();
918 if ( baseConstraint.IsRemoving() )
920 if( !mRemovedConstraints )
922 mRemovedConstraints = new ActiveConstraintContainer;
924 // Wait for remove animation before destroying active-constraints
925 mRemovedConstraints->push_back( constraint );
928 else if( mRemovedConstraints )
930 delete mRemovedConstraints;
931 mRemovedConstraints = NULL;
936 void ProxyObject::RemoveConstraint( Dali::ActiveConstraint activeConstraint )
938 // guard against constraint sending messages during core destruction
939 if( mConstraints && Stage::IsInstalled() )
941 bool isInSceneGraph( NULL != GetSceneObject() );
944 DeleteRemovedConstraints();
947 ActiveConstraintIter it( std::find( mConstraints->begin(), mConstraints->end(), activeConstraint ) );
948 if( it != mConstraints->end() )
950 RemoveConstraint( *it, isInSceneGraph );
951 mConstraints->erase( it );
956 void ProxyObject::RemoveConstraints( unsigned int tag )
958 // guard against constraint sending messages during core destruction
959 if( mConstraints && Stage::IsInstalled() )
961 bool isInSceneGraph( NULL != GetSceneObject() );
964 DeleteRemovedConstraints();
967 ActiveConstraintIter iter( mConstraints->begin() );
968 while(iter != mConstraints->end() )
970 ActiveConstraintBase& constraint = GetImplementation( *iter );
971 if( constraint.GetTag() == tag )
973 RemoveConstraint( *iter, isInSceneGraph );
974 iter = mConstraints->erase( iter );
984 void ProxyObject::RemoveConstraints()
986 // guard against constraint sending messages during core destruction
987 if( mConstraints && Stage::IsInstalled() )
989 // If we have nothing in the scene-graph, just clear constraint containers
990 const SceneGraph::PropertyOwner* propertyOwner = GetSceneObject();
991 if ( NULL == propertyOwner )
993 delete mRemovedConstraints;
994 mRemovedConstraints = NULL;
998 // Discard constraints which are fully removed
999 DeleteRemovedConstraints();
1001 const ActiveConstraintConstIter endIter = mConstraints->end();
1002 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
1004 RemoveConstraint( *iter, true );
1008 delete mConstraints;
1009 mConstraints = NULL;
1013 void ProxyObject::SetTypeInfo( TypeInfo* typeInfo )
1015 mTypeInfo = typeInfo;
1018 ProxyObject::~ProxyObject()
1020 // Notification for observers
1021 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
1023 (*iter)->ProxyDestroyed(*this);
1026 delete mCustomProperties;
1027 delete mConstraints;
1028 delete mRemovedConstraints;
1029 delete mPropertyNotifications;
1032 } // namespace Internal