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/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 mPropertyNotifications( NULL )
67 void ProxyObject::AddObserver(Observer& observer)
69 // make sure an observer doesn't observe the same object twice
70 // otherwise it will get multiple calls to OnSceneObjectAdd(), OnSceneObjectRemove() and ProxyDestroyed()
71 DALI_ASSERT_DEBUG( mObservers.End() == std::find( mObservers.Begin(), mObservers.End(), &observer));
73 mObservers.PushBack( &observer );
76 void ProxyObject::RemoveObserver(Observer& observer)
78 // Find the observer...
79 const ConstObserverIter endIter = mObservers.End();
80 for( ObserverIter iter = mObservers.Begin(); iter != endIter; ++iter)
82 if( (*iter) == &observer)
84 mObservers.Erase( iter );
88 DALI_ASSERT_DEBUG(endIter != mObservers.End());
91 void ProxyObject::OnSceneObjectAdd()
93 // Notification for this object's constraints
96 const ActiveConstraintConstIter endIter = mConstraints->end();
97 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
99 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
100 baseConstraint.OnParentSceneObjectAdded();
104 // Notification for observers
105 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter)
107 (*iter)->SceneObjectAdded(*this);
110 // enable property notifications in scene graph
111 EnablePropertyNotifications();
114 void ProxyObject::OnSceneObjectRemove()
116 // Notification for this object's constraints
119 const ActiveConstraintConstIter endIter = mConstraints->end();
120 for ( ActiveConstraintIter iter = mConstraints->begin(); endIter != iter; ++iter )
122 ActiveConstraintBase& baseConstraint = GetImplementation( *iter );
123 baseConstraint.OnParentSceneObjectRemoved();
127 // Notification for observers
128 for( ConstObserverIter iter = mObservers.Begin(), endIter = mObservers.End(); iter != endIter; ++iter )
130 (*iter)->SceneObjectRemoved(*this);
133 // disable property notifications in scene graph
134 DisablePropertyNotifications();
137 int ProxyObject::GetPropertyComponentIndex( Property::Index index ) const
139 return Property::INVALID_COMPONENT_INDEX;
142 bool ProxyObject::Supports( Capability capability ) const
144 return (capability & SUPPORTED_CAPABILITIES);
147 unsigned int ProxyObject::GetPropertyCount() const
149 unsigned int count = GetDefaultPropertyCount();
151 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Default Properties: %d\n", count );
153 const TypeInfo* typeInfo( GetTypeInfo() );
156 unsigned int manual( typeInfo->GetPropertyCount() );
159 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Manual Properties: %d\n", manual );
162 if( mCustomProperties )
164 unsigned int custom( mCustomProperties->size() );
167 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Custom Properties: %d\n", custom );
170 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Total Properties: %d\n", count );
175 const std::string& ProxyObject::GetPropertyName( Property::Index index ) const
177 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index out of bounds" );
179 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
181 return GetDefaultPropertyName( index );
184 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
186 const TypeInfo* typeInfo( GetTypeInfo() );
189 return typeInfo->GetPropertyName( index );
193 DALI_ASSERT_ALWAYS( ! "Property index is invalid" );
197 if( mCustomProperties )
199 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
200 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Property index is invalid" );
202 return entry->second.name;
204 return EMPTY_PROPERTY_NAME;
207 Property::Index ProxyObject::GetPropertyIndex(const std::string& name) const
209 Property::Index index = GetDefaultPropertyIndex( name );
211 if ( index == Property::INVALID_INDEX )
213 const TypeInfo* typeInfo( GetTypeInfo() );
216 index = typeInfo->GetPropertyIndex( name );
220 if( index == Property::INVALID_INDEX && mCustomProperties )
222 // This is slow, but we're not (supposed to be) using property names frequently
223 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); mCustomProperties->end() != iter; ++iter )
225 if (iter->second.name == name)
236 bool ProxyObject::IsPropertyWritable( Property::Index index ) const
238 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
240 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
242 return IsDefaultPropertyWritable( index );
245 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
247 const TypeInfo* typeInfo( GetTypeInfo() );
250 return typeInfo->IsPropertyWritable( index );
254 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
258 if( mCustomProperties)
260 // Check that the index is valid
261 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
262 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
264 return entry->second.IsWritable();
269 bool ProxyObject::IsPropertyAnimatable( Property::Index index ) const
271 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
273 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
275 return IsDefaultPropertyAnimatable( index );
278 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
280 // Type Registry event-thread only properties are not animatable.
284 if( mCustomProperties )
286 // Check custom property
287 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
288 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
290 return entry->second.IsAnimatable();
295 bool ProxyObject::IsPropertyAConstraintInput(Property::Index index) const
297 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds");
299 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
301 return IsDefaultPropertyAConstraintInput( index );
304 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
306 // Type Registry event-thread only properties cannot be used as an input to a constraint.
310 if( mCustomProperties )
312 // Check custom property
313 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
314 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
316 // ... custom properties can be used as input to a constraint.
322 Property::Type ProxyObject::GetPropertyType( Property::Index index ) const
324 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
326 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
328 return GetDefaultPropertyType( index );
331 if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
333 const TypeInfo* typeInfo( GetTypeInfo() );
336 return typeInfo->GetPropertyType( index );
340 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
344 if( mCustomProperties )
346 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
347 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find Property index" );
349 return entry->second.type;
351 return Property::NONE;
354 void ProxyObject::SetProperty( Property::Index index, const Property::Value& propertyValue )
356 DALI_ASSERT_ALWAYS(index > Property::INVALID_INDEX && "Property index is out of bounds" );
358 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
360 DALI_ASSERT_ALWAYS( IsDefaultPropertyWritable(index) && "Property is read-only" );
362 SetDefaultProperty( index, propertyValue );
364 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
366 const TypeInfo* typeInfo( GetTypeInfo() );
369 typeInfo->SetProperty( this, index, propertyValue );
373 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
376 else if( mCustomProperties )
378 CustomPropertyLookup::iterator entry = mCustomProperties->find( index );
379 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
380 DALI_ASSERT_ALWAYS( entry->second.IsWritable() && "Property is read-only" );
382 // this is only relevant for non animatable properties
383 if(entry->second.IsWritable())
385 entry->second.value = propertyValue;
388 SetCustomProperty(index, entry->second, propertyValue);
392 Property::Value ProxyObject::GetProperty(Property::Index index) const
394 DALI_ASSERT_ALWAYS( index > Property::INVALID_INDEX && "Property index is out of bounds" );
396 Property::Value value;
398 if ( index < DEFAULT_PROPERTY_MAX_COUNT )
400 value = GetDefaultProperty( index );
402 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
404 const TypeInfo* typeInfo( GetTypeInfo() );
407 value = typeInfo->GetProperty( this, index );
411 DALI_ASSERT_ALWAYS( ! "Cannot find property index" );
414 else if( mCustomProperties )
416 CustomPropertyLookup::const_iterator entry = mCustomProperties->find( index );
417 DALI_ASSERT_ALWAYS( mCustomProperties->end() != entry && "Cannot find property index" );
419 if( !entry->second.IsAnimatable() )
421 value = entry->second.value;
425 BufferIndex bufferIndex( Stage::GetCurrent()->GetEventBufferIndex() );
427 switch ( entry->second.type )
429 case Property::BOOLEAN:
431 const AnimatableProperty<bool>* property = dynamic_cast< const AnimatableProperty<bool>* >( entry->second.GetSceneGraphProperty() );
432 DALI_ASSERT_DEBUG( NULL != property );
434 value = (*property)[ bufferIndex ];
438 case Property::FLOAT:
440 const AnimatableProperty<float>* property = dynamic_cast< const AnimatableProperty<float>* >( entry->second.GetSceneGraphProperty() );
441 DALI_ASSERT_DEBUG( NULL != property );
443 value = (*property)[ bufferIndex ];
447 case Property::INTEGER:
449 const AnimatableProperty<int>* property = dynamic_cast< const AnimatableProperty<int>* >( entry->second.GetSceneGraphProperty() );
450 DALI_ASSERT_DEBUG( NULL != property );
452 value = (*property)[ bufferIndex ];
456 case Property::VECTOR2:
458 const AnimatableProperty<Vector2>* property = dynamic_cast< const AnimatableProperty<Vector2>* >( entry->second.GetSceneGraphProperty() );
459 DALI_ASSERT_DEBUG( NULL != property );
461 value = (*property)[ bufferIndex ];
465 case Property::VECTOR3:
467 const AnimatableProperty<Vector3>* property = dynamic_cast< const AnimatableProperty<Vector3>* >( entry->second.GetSceneGraphProperty() );
468 DALI_ASSERT_DEBUG( NULL != property );
470 value = (*property)[ bufferIndex ];
474 case Property::VECTOR4:
476 const AnimatableProperty<Vector4>* property = dynamic_cast< const AnimatableProperty<Vector4>* >( entry->second.GetSceneGraphProperty() );
477 DALI_ASSERT_DEBUG( NULL != property );
479 value = (*property)[ bufferIndex ];
483 case Property::MATRIX:
485 const AnimatableProperty<Matrix>* property = dynamic_cast< const AnimatableProperty<Matrix>* >( entry->second.GetSceneGraphProperty() );
486 DALI_ASSERT_DEBUG( NULL != property );
488 value = (*property)[ bufferIndex ];
492 case Property::MATRIX3:
494 const AnimatableProperty<Matrix3>* property = dynamic_cast< const AnimatableProperty<Matrix3>* >( entry->second.GetSceneGraphProperty() );
495 DALI_ASSERT_DEBUG( NULL != property );
497 value = (*property)[ bufferIndex ];
501 case Property::ROTATION:
503 const AnimatableProperty<Quaternion>* property = dynamic_cast< const AnimatableProperty<Quaternion>* >( entry->second.GetSceneGraphProperty() );
504 DALI_ASSERT_DEBUG( NULL != property );
506 value = (*property)[ bufferIndex ];
512 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
523 void ProxyObject::GetPropertyIndices( Property::IndexContainer& indices ) const
527 // Default Properties
528 GetDefaultPropertyIndices( indices );
531 const TypeInfo* typeInfo( GetTypeInfo() );
534 typeInfo->GetPropertyIndices( indices );
538 if ( mCustomProperties )
540 indices.reserve( indices.size() + mCustomProperties->size() );
542 const CustomPropertyLookup::const_iterator endIter = mCustomProperties->end();
543 for ( CustomPropertyLookup::const_iterator iter = mCustomProperties->begin(); iter != endIter; ++iter )
545 indices.push_back( iter->first );
550 Property::Index ProxyObject::RegisterProperty( std::string name, const Property::Value& propertyValue)
552 // Assert that property name is unused
553 DALI_ASSERT_ALWAYS( Property::INVALID_INDEX == GetPropertyIndex(name) && "Property index is out of bounds" );
555 // Create a new property
556 Dali::Internal::OwnerPointer<PropertyBase> newProperty;
558 switch ( propertyValue.GetType() )
560 case Property::BOOLEAN:
562 newProperty = new AnimatableProperty<bool>( propertyValue.Get<bool>() );
566 case Property::FLOAT:
568 newProperty = new AnimatableProperty<float>( propertyValue.Get<float>() );
572 case Property::INTEGER:
574 newProperty = new AnimatableProperty<int>( propertyValue.Get<int>() );
578 case Property::VECTOR2:
580 newProperty = new AnimatableProperty<Vector2>( propertyValue.Get<Vector2>() );
584 case Property::VECTOR3:
586 newProperty = new AnimatableProperty<Vector3>( propertyValue.Get<Vector3>() );
590 case Property::VECTOR4:
592 newProperty = new AnimatableProperty<Vector4>( propertyValue.Get<Vector4>() );
596 case Property::MATRIX:
598 newProperty = new AnimatableProperty<Matrix>( propertyValue.Get<Matrix>() );
602 case Property::MATRIX3:
604 newProperty = new AnimatableProperty<Matrix3>( propertyValue.Get<Matrix3>() );
608 case Property::ROTATION:
610 newProperty = new AnimatableProperty<Quaternion>( propertyValue.Get<Quaternion>() );
614 case Property::UNSIGNED_INTEGER:
615 case Property::RECTANGLE:
616 case Property::STRING:
617 case Property::ARRAY:
620 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
621 DALI_ASSERT_ALWAYS( false && "PropertyType is not animatable" );
627 DALI_LOG_WARNING( "Property Type %d\n", propertyValue.GetType() );
628 DALI_ASSERT_ALWAYS( false && "PropertyType enumeration is out of bounds" );
633 // Default properties start from index zero
634 if ( 0u == mNextCustomPropertyIndex )
636 mNextCustomPropertyIndex = PROPERTY_CUSTOM_START_INDEX;
639 // Add entry to the property lookup
640 const Property::Index index = mNextCustomPropertyIndex++;
642 CustomPropertyLookup::const_iterator entry = GetCustomPropertyLookup().find( index );
643 DALI_ASSERT_ALWAYS( mCustomProperties->end() == entry && "Custom property already registered" );
645 (*mCustomProperties)[ index ] = CustomProperty( name, propertyValue.GetType(), newProperty.Get() );
647 // The derived class now passes ownership of this new property to a scene-object
648 // TODO: change this so that OwnerPointer is passed all the way as owership passing cannot be done with a reference
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 const AnimatableProperty<bool>* property = dynamic_cast< const 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 const AnimatableProperty<float>* property = dynamic_cast< const 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 const AnimatableProperty<int>* property = dynamic_cast< const 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 const AnimatableProperty<Vector2>* property = dynamic_cast< const 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 const AnimatableProperty<Vector3>* property = dynamic_cast< const 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 const AnimatableProperty<Vector4>* property = dynamic_cast< const 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 const AnimatableProperty<Quaternion>* property = dynamic_cast< const 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 const AnimatableProperty<Matrix>* property = dynamic_cast< const 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 const AnimatableProperty<Matrix3>* property = dynamic_cast< const 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