2 * Copyright (c) 2018 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/type-info-impl.h>
22 #include <algorithm> // std::find_if
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/event/common/type-registry-impl.h>
28 #include <dali/internal/event/common/object-impl.h>
36 * Functor to find by given type for vector of pairs
38 template <typename S, typename T>
41 PairFinder(const S& find)
46 bool operator()(const T& p) const
48 return p.first == mFind;
57 * Functor to find a matching property name
60 struct PropertyNameFinder
62 PropertyNameFinder( const std::string& find )
67 bool operator()(const T &p) const
69 return p.second.name == mFind;
74 const std::string& mFind;
78 * Functor to find a matching property component index
81 struct PropertyComponentFinder
83 PropertyComponentFinder( Dali::Property::Index basePropertyIndex, const int find )
84 : mBasePropertyIndex( basePropertyIndex ),
89 bool operator()(const T &p) const
91 return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
96 Dali::Property::Index mBasePropertyIndex;
108 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator)
109 : mTypeName(name), mBaseTypeName(baseTypeName), mCSharpType(false), mCreate(creator)
111 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
112 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
115 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::CSharpTypeInfo::CreateFunction creator)
116 : mTypeName(name), mBaseTypeName(baseTypeName), mCSharpType(true), mCSharpCreate(creator)
118 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
119 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
122 TypeInfo::~TypeInfo()
126 BaseHandle TypeInfo::CreateInstance() const
134 // CSharp currently only registers one create function for all custom controls
135 // it uses the type name to decide which one to create
136 ret = *mCSharpCreate( mTypeName.c_str() );
145 BaseObject& handle = ret.GetBaseObject();
146 Object *object = dynamic_cast<Internal::Object*>(&handle);
150 object->SetTypeInfo( this );
157 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
161 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
163 if( iter != mActions.end() )
165 done = (iter->second)(object, actionName, properties);
169 DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
174 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
177 done = GetImplementation(base).DoActionTo(object, actionName, properties);
182 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
189 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
191 bool connected( false );
193 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
194 PairFinder<std::string, ConnectionPair>(signalName) );
196 if( iter != mSignalConnectors.end() )
198 connected = (iter->second)( object, connectionTracker, signalName, functor );
204 const std::string& TypeInfo::GetName() const
209 const std::string& TypeInfo::GetBaseName() const
211 return mBaseTypeName;
214 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
219 size_t TypeInfo::GetActionCount() const
221 size_t count = mActions.size();
223 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
226 count += GetImplementation(base).mActions.size();
227 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
233 std::string TypeInfo::GetActionName(size_t index) const
237 if( index < mActions.size() )
239 name = mActions[index].first;
243 size_t count = mActions.size();
245 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
248 size_t baseCount = GetImplementation(base).mActions.size();
250 if( index < count + baseCount )
252 name = GetImplementation(base).mActions[ index - count ].first;
258 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
265 size_t TypeInfo::GetSignalCount() const
267 size_t count = mSignalConnectors.size();
269 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
272 count += GetImplementation(base).mSignalConnectors.size();
273 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
279 std::string TypeInfo::GetSignalName(size_t index) const
283 if( index < mSignalConnectors.size() )
285 name = mSignalConnectors[index].first;
289 size_t count = mSignalConnectors.size();
291 Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
294 size_t baseCount = GetImplementation(base).mSignalConnectors.size();
296 if( index < count + baseCount )
298 name = GetImplementation(base).mSignalConnectors[ index - count ].first;
304 base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
311 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
313 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
316 const TypeInfo& baseImpl( GetImplementation( base ) );
317 baseImpl.GetPropertyIndices( indices );
320 AppendProperties( indices, mRegisteredProperties );
323 void TypeInfo::GetChildPropertyIndices( Property::IndexContainer& indices ) const
325 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
328 const TypeInfo& baseImpl( GetImplementation( base ) );
329 baseImpl.GetChildPropertyIndices( indices );
332 AppendProperties( indices, mRegisteredChildProperties );
336 * Append the indices in RegisteredProperties to the given index container.
338 void TypeInfo::AppendProperties( Dali::Property::IndexContainer& indices,
339 const TypeInfo::RegisteredPropertyContainer& registeredProperties ) const
341 if ( ! registeredProperties.empty() )
343 indices.Reserve( indices.Size() + registeredProperties.size() );
345 for( auto&& elem : registeredProperties )
347 indices.PushBack( elem.first );
352 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
354 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
355 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
357 if ( iter != mRegisteredProperties.end() )
359 return iter->second.name;
362 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
365 return GetImplementation(base).GetPropertyName( index );
368 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
371 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
373 if( NULL == function)
375 DALI_LOG_WARNING("Action function is empty\n");
379 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
380 PairFinder<std::string, ActionPair>(actionName));
382 if( iter == mActions.end() )
384 mActions.push_back( ActionPair( actionName, function ) );
388 DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
393 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
395 if( NULL == function)
397 DALI_LOG_WARNING("Connector function is empty\n");
401 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
402 PairFinder<std::string, ConnectionPair>(signalName) );
404 if( iter == mSignalConnectors.end() )
406 mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
410 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
415 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
417 // The setter can be empty as a property can be read-only.
419 if ( NULL == getFunc )
421 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
425 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
426 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
428 if ( iter == mRegisteredProperties.end() )
430 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
434 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
439 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
442 // The setter can be empty as a property can be read-only.
444 if ( NULL == getFunc )
446 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
450 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
451 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
453 if ( iter == mRegisteredProperties.end() )
455 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
459 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
466 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
468 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
469 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
471 if ( iter == mRegisteredProperties.end() )
473 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
477 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
481 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue )
483 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
484 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
486 if ( iter == mRegisteredProperties.end() )
488 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
489 mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) );
493 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
497 void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
499 Property::Type type = GetPropertyType( baseIndex );
500 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
502 bool success = false;
504 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
505 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
507 if ( iter == mRegisteredProperties.end() )
509 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
510 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
512 if ( iter == mRegisteredProperties.end() )
514 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, baseIndex, componentIndex ) ) );
519 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
522 void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type )
524 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
525 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
527 if ( iter == mRegisteredChildProperties.end() )
529 mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
533 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
537 uint32_t TypeInfo::GetPropertyCount() const
539 uint32_t count = static_cast<uint32_t>( mRegisteredProperties.size() );
541 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
544 const TypeInfo& baseImpl( GetImplementation(base) );
545 count += static_cast<uint32_t>( baseImpl.mRegisteredProperties.size() );
546 base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
552 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
554 Property::Index index = Property::INVALID_INDEX;
556 // Slow but should not be done that often
557 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
558 PropertyNameFinder< RegisteredPropertyPair >( name ) );
560 if ( iter != mRegisteredProperties.end() )
566 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
569 index = GetImplementation(base).GetPropertyIndex( name );
576 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
578 Property::Index basePropertyIndex = Property::INVALID_INDEX;
580 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
581 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
583 if ( iter != mRegisteredProperties.end() )
585 basePropertyIndex = iter->second.basePropertyIndex;
589 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
592 basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index );
596 return basePropertyIndex;
599 int TypeInfo::GetComponentIndex( Property::Index index ) const
601 int componentIndex = Property::INVALID_COMPONENT_INDEX;
603 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
604 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
606 if ( iter != mRegisteredProperties.end() )
608 componentIndex = iter->second.componentIndex;
612 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
615 componentIndex = GetImplementation(base).GetComponentIndex( index );
619 return componentIndex;
622 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
624 Property::Index index = Property::INVALID_INDEX;
626 // Slow but should not be done that often
627 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
628 PropertyNameFinder< RegisteredPropertyPair >( name ) );
630 if ( iter != mRegisteredChildProperties.end() )
636 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
639 index = GetImplementation(base).GetChildPropertyIndex( name );
646 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
648 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
649 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
651 if ( iter != mRegisteredChildProperties.end() )
653 return iter->second.name;
656 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
659 return GetImplementation(base).GetChildPropertyName( index );
662 DALI_LOG_WARNING("Cannot find property index");
664 static std::string emptyString;
668 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
670 Property::Type type( Property::NONE );
672 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
673 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
675 if ( iter != mRegisteredChildProperties.end() )
677 type = iter->second.type;
681 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
684 type = GetImplementation(base).GetChildPropertyType( index );
688 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
695 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
697 bool writable( false );
699 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
700 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
702 if ( iter != mRegisteredProperties.end() )
704 if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
706 writable = true; // animatable property is writable
710 writable = iter->second.setFunc ? true : false;
715 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
718 writable = GetImplementation(base).IsPropertyWritable( index );
722 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
729 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
731 Property::Type type( Property::NONE );
733 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
734 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
736 if ( iter != mRegisteredProperties.end() )
738 if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX )
740 type = iter->second.type;
744 // If component index is set, then we should return FLOAT
745 type = Property::FLOAT;
750 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
753 type = GetImplementation(base).GetPropertyType( index );
757 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
764 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
766 PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
767 PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
768 if( iter != mPropertyDefaultValues.end() )
774 return Property::Value( GetPropertyType( index ) );
778 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
780 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
781 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
782 if ( iter != mRegisteredProperties.end() )
784 if( iter->second.setFunc )
788 // CSharp wants a property name not an index
789 const std::string& name = (iter->second).name;
791 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value) );
795 iter->second.setFunc( object, index, value );
801 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
804 GetImplementation(base).SetProperty( object, index, value );
808 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
813 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
815 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
816 PropertyNameFinder< RegisteredPropertyPair >( name ) );
817 if ( iter != mRegisteredProperties.end() )
819 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
823 // CSharp wants a property name not an index
824 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value ));
828 iter->second.setFunc( object, iter->first, value );
833 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
836 GetImplementation(base).SetProperty( object, name, value );
840 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
845 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
847 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
848 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
849 if( iter != mRegisteredProperties.end() )
851 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
853 // CSharp wants a property name not an index
854 // CSharp callback can't return an object by value, it can only return a pointer
855 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
856 const std::string& name = (iter->second).name;
858 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str()) );
863 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
864 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
868 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
871 return GetImplementation( base ).GetProperty( object, index );
874 DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
877 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
879 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
880 PropertyNameFinder< RegisteredPropertyPair >( name ) );
884 if( iter != mRegisteredProperties.end() )
886 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
888 // CSharp wants a property name not an index
889 // CSharp callback can't return an object by value, it can only return a pointer
890 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
891 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() ));
896 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
897 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
901 Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
904 return GetImplementation( base ).GetProperty( object, name );
907 DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
910 } // namespace Internal