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>
42 * Functor to find by given type for vector of pairs
44 template <typename S, typename T>
47 PairFinder(const S& find)
52 bool operator()(const T& p) const
54 return p.first == mFind;
63 * Functor to find a matching property name
66 struct PropertyNameFinder
68 PropertyNameFinder( const std::string& find )
73 bool operator()(const T &p) const
75 return p.second.name == mFind;
80 const std::string& mFind;
84 * Functor to find a matching property component index
87 struct PropertyComponentFinder
89 PropertyComponentFinder( Property::Index basePropertyIndex, const int find )
90 : mBasePropertyIndex( basePropertyIndex ),
95 bool operator()(const T &p) const
97 return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
102 Property::Index mBasePropertyIndex;
107 * Helper function to find the right default property with given index and return the desired detail of it
109 template< typename Parameter, typename Member >
110 inline bool GetDefaultPropertyField( const Dali::PropertyDetails* propertyTable, Property::Index count, Property::Index index, Member member, Parameter& parameter )
113 // is index inside this table (bigger than first index but smaller than first + count)
114 if( ( index >= propertyTable->enumIndex ) && ( index < ( propertyTable->enumIndex + count ) ) )
116 // return the match. we're assuming here that there is no gaps between the indices in a table
117 parameter = propertyTable[ index - propertyTable->enumIndex ].*member;
120 // should never really get here
124 // static pointer value to mark that a base class address has not been resolved
125 // 0x01 is not a valid pointer but used here to differentiate from nullptr
126 // unfortunately it cannot be constexpr as C++ does not allow them to be initialised with reinterpret_cast
127 Internal::TypeInfo* const UNRESOLVED = reinterpret_cast<Internal::TypeInfo*>( 0x1 );
130 * Helper function to resolve and return the pointer to the base type info
131 * Not a member function to avoid having to #include additional headers and to make sure this gets inlined inside this cpp
132 * @param[in/out] baseType pointer to resolve and set
133 * @param[in] typeRegistry reference to the type registry
134 * @param[in] baseTypeName string name of the base type
135 * @return true is base type exists
137 inline bool GetBaseType( Internal::TypeInfo*& baseType, TypeRegistry& typeRegistry, const std::string& baseTypeName )
139 // if greater than unresolved means we have a base type, null means no base
140 bool baseExists = ( baseType > UNRESOLVED );
141 // base only needs to be resolved once
142 if( UNRESOLVED == baseType )
144 TypeRegistry::TypeInfoPointer base = typeRegistry.GetTypeInfo( baseTypeName );
147 baseType = base.Get(); // dont pass ownership, just return raw pointer
152 // no type info found so assuming no base as all type registration is done in startup for now
159 } // unnamed namespace
161 TypeInfo::TypeInfo( const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator,
162 const Dali::PropertyDetails* defaultProperties, Property::Index defaultPropertyCount )
163 : mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ),
164 mTypeName( name ), mBaseTypeName( baseTypeName ), mCreate( creator ), mDefaultProperties( defaultProperties ),
165 mDefaultPropertyCount( defaultPropertyCount ), mCSharpType( false )
167 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
168 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
171 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::CSharpTypeInfo::CreateFunction creator)
172 : mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ),
173 mTypeName( name ), mBaseTypeName( baseTypeName ), mCSharpCreate( creator ), mCSharpType( true )
175 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
176 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
179 TypeInfo::~TypeInfo()
183 BaseHandle TypeInfo::CreateInstance() const
191 // CSharp currently only registers one create function for all custom controls
192 // it uses the type name to decide which one to create
193 ret = *mCSharpCreate( mTypeName.c_str() );
202 BaseObject& handle = ret.GetBaseObject();
203 Object *object = dynamic_cast<Internal::Object*>(&handle);
207 object->SetTypeInfo( this );
214 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
218 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
220 if( iter != mActions.end() )
222 done = (iter->second)(object, actionName, properties);
227 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
229 // call base type recursively
230 done = mBaseType->DoActionTo( object, actionName, properties );
237 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
239 bool connected( false );
241 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
242 PairFinder<std::string, ConnectionPair>(signalName) );
244 if( iter != mSignalConnectors.end() )
246 connected = (iter->second)( object, connectionTracker, signalName, functor );
251 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
253 // call base type recursively
254 connected = mBaseType->ConnectSignal( object, connectionTracker, signalName, functor );
261 const std::string& TypeInfo::GetName() const
266 const std::string& TypeInfo::GetBaseName() const
268 return mBaseTypeName;
271 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
276 uint32_t TypeInfo::GetActionCount() const
278 uint32_t count = static_cast<uint32_t>( mActions.size() );
280 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
282 // call base type recursively
283 count += mBaseType->GetActionCount();
289 std::string TypeInfo::GetActionName( uint32_t index ) const
292 const uint32_t count = static_cast<uint32_t>( mActions.size() );
296 name = mActions[index].first;
300 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
302 // call base type recursively
303 return mBaseType->GetActionName( index - count );
310 uint32_t TypeInfo::GetSignalCount() const
312 uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
314 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
316 // call base type recursively
317 count += mBaseType->GetSignalCount();
323 std::string TypeInfo::GetSignalName( uint32_t index ) const
326 const uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
330 name = mSignalConnectors[index].first;
334 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
336 // call base type recursively
337 return mBaseType->GetSignalName( index - count );
344 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
346 // Default Properties
347 if( mDefaultProperties )
349 indices.Reserve( indices.Size() + mDefaultPropertyCount );
350 for( Property::Index index = 0; index < mDefaultPropertyCount; ++index )
352 indices.PushBack( mDefaultProperties[ index ].enumIndex );
356 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
358 // call base type recursively
359 mBaseType->GetPropertyIndices( indices );
362 AppendProperties( indices, mRegisteredProperties );
365 void TypeInfo::GetChildPropertyIndices( Property::IndexContainer& indices ) const
367 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
369 // call base type recursively
370 mBaseType->GetChildPropertyIndices( indices );
373 AppendProperties( indices, mRegisteredChildProperties );
377 * Append the indices in RegisteredProperties to the given index container.
379 void TypeInfo::AppendProperties( Dali::Property::IndexContainer& indices,
380 const TypeInfo::RegisteredPropertyContainer& registeredProperties ) const
382 if ( ! registeredProperties.empty() )
384 indices.Reserve( indices.Size() + registeredProperties.size() );
386 for( auto&& elem : registeredProperties )
388 indices.PushBack( elem.first );
393 const std::string& TypeInfo::GetRegisteredPropertyName( Property::Index index ) const
395 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
396 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
397 if ( iter != mRegisteredProperties.end() )
399 return iter->second.name;
401 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
403 // call base type recursively
404 return mBaseType->GetRegisteredPropertyName( index );
406 static std::string empty;
410 std::string TypeInfo::GetPropertyName( Property::Index index ) const
412 std::string propertyName;
414 if ( mDefaultProperties && ( index < DEFAULT_PROPERTY_MAX_COUNT ) )
416 const char* name = nullptr;
417 if( GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::name, name ) )
424 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
425 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
426 if ( iter != mRegisteredProperties.end() )
428 return iter->second.name;
431 // if not our property, go to parent
432 if( propertyName.empty() )
434 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
436 // call base type recursively
437 return mBaseType->GetPropertyName( index );
444 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
446 if( NULL == function)
448 DALI_LOG_WARNING("Action function is empty\n");
452 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
453 PairFinder<std::string, ActionPair>(actionName));
455 if( iter == mActions.end() )
457 mActions.push_back( ActionPair( actionName, function ) );
461 DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
466 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
468 if( NULL == function)
470 DALI_LOG_WARNING("Connector function is empty\n");
474 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
475 PairFinder<std::string, ConnectionPair>(signalName) );
477 if( iter == mSignalConnectors.end() )
479 mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
483 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
488 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
490 // The setter can be empty as a property can be read-only.
492 if ( NULL == getFunc )
494 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
498 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
499 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
501 if ( iter == mRegisteredProperties.end() )
503 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
507 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
512 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
515 // The setter can be empty as a property can be read-only.
517 if ( NULL == getFunc )
519 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
523 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
524 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
526 if ( iter == mRegisteredProperties.end() )
528 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
532 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
539 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
541 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
542 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
544 if ( iter == mRegisteredProperties.end() )
546 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
550 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
554 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue )
556 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
557 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
559 if ( iter == mRegisteredProperties.end() )
561 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
562 mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) );
566 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
570 void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex )
572 Property::Type type = GetPropertyType( baseIndex );
573 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
575 bool success = false;
577 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
578 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
580 if ( iter == mRegisteredProperties.end() )
582 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
583 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
585 if ( iter == mRegisteredProperties.end() )
587 mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, baseIndex, componentIndex ) ) );
592 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
595 void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type )
597 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
598 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
600 if ( iter == mRegisteredChildProperties.end() )
602 mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
606 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
610 uint32_t TypeInfo::GetPropertyCount() const
612 uint32_t count = mDefaultPropertyCount + static_cast<uint32_t>( mRegisteredProperties.size() );
614 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
616 // call base type recursively
617 count += mBaseType->GetPropertyCount();
623 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
625 Property::Index index = Property::INVALID_INDEX;
628 // check default properties
629 if( mDefaultProperties )
631 for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex )
633 if( 0 == name.compare( mDefaultProperties[ tableIndex ].name ) )
635 index = mDefaultProperties[ tableIndex ].enumIndex;
643 // Slow but should not be done that often
644 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
645 PropertyNameFinder< RegisteredPropertyPair >( name ) );
646 if ( iter != mRegisteredProperties.end() )
650 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
652 // call base type recursively
653 index = mBaseType->GetPropertyIndex( name );
660 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
662 Property::Index basePropertyIndex = Property::INVALID_INDEX;
664 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
665 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
667 if ( iter != mRegisteredProperties.end() )
669 basePropertyIndex = iter->second.basePropertyIndex;
671 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
673 // call base type recursively
674 basePropertyIndex = mBaseType->GetBasePropertyIndex( index );
677 return basePropertyIndex;
680 int32_t TypeInfo::GetComponentIndex( Property::Index index ) const
682 int componentIndex = Property::INVALID_COMPONENT_INDEX;
684 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
685 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
687 if ( iter != mRegisteredProperties.end() )
689 componentIndex = iter->second.componentIndex;
691 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
693 // call base type recursively
694 componentIndex = mBaseType->GetComponentIndex( index );
697 return componentIndex;
700 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
702 Property::Index index = Property::INVALID_INDEX;
704 // Slow but should not be done that often
705 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
706 PropertyNameFinder< RegisteredPropertyPair >( name ) );
708 if ( iter != mRegisteredChildProperties.end() )
712 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
714 // call base type recursively
715 index = mBaseType->GetChildPropertyIndex( name );
721 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
723 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
724 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
726 if ( iter != mRegisteredChildProperties.end() )
728 return iter->second.name;
731 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
733 // call base type recursively
734 return mBaseType->GetChildPropertyName( index );
737 DALI_LOG_ERROR( "Property index %d not found\n", index );
739 static std::string empty;
743 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
745 Property::Type type( Property::NONE );
747 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
748 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
750 if ( iter != mRegisteredChildProperties.end() )
752 type = iter->second.type;
754 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
756 // call base type recursively
757 type = mBaseType->GetChildPropertyType( index );
761 DALI_LOG_ERROR( "Property index %d not found\n", index );
767 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
769 bool writable = false;
773 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
775 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::writable, writable );
777 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
779 writable = true; // animatable property is writable
784 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
785 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
786 if ( iter != mRegisteredProperties.end() )
788 writable = iter->second.setFunc ? true : false;
793 // if not found, continue to base
796 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
798 // call base type recursively
799 writable = mBaseType->IsPropertyWritable( index );
803 DALI_LOG_ERROR( "Property index %d not found\n", index );
810 bool TypeInfo::IsPropertyAnimatable( Property::Index index ) const
812 bool animatable = false;
816 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
818 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::animatable, animatable );
820 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
822 // Type Registry event-thread only properties are not animatable.
826 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
832 // if not found, continue to base
835 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
837 // call base type recursively
838 animatable = mBaseType->IsPropertyAnimatable( index );
842 DALI_LOG_ERROR( "Property index %d not found\n", index );
849 bool TypeInfo::IsPropertyAConstraintInput( Property::Index index ) const
851 bool constraintInput = false;
855 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
857 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::constraintInput, constraintInput );
859 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
861 // Type Registry event-thread only properties cannot be used as constraint input
862 constraintInput = false;
865 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
867 constraintInput = true;
871 // if not found, continue to base
874 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
876 // call base type recursively
877 constraintInput = mBaseType->IsPropertyAConstraintInput( index );
881 DALI_LOG_ERROR( "Property index %d not found\n", index );
885 return constraintInput;
889 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
891 Property::Type type( Property::NONE );
895 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
897 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::type, type );
901 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
902 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
904 if ( iter != mRegisteredProperties.end() )
906 if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX )
908 type = iter->second.type;
913 // If component index is set, then we should return FLOAT
914 type = Property::FLOAT;
922 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
924 // call base type recursively
925 type = mBaseType->GetPropertyType( index );
929 DALI_LOG_ERROR( "Property index %d not found\n", index );
936 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
938 PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
939 PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
940 if( iter != mPropertyDefaultValues.end() )
944 // we didn't have a value so ask base
945 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
947 // call base type recursively
948 return mBaseType->GetPropertyDefaultValue( index );
950 return Property::Value(); // return none
953 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
955 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
956 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
957 if ( iter != mRegisteredProperties.end() )
959 if( iter->second.setFunc )
963 // CSharp wants a property name not an index
964 const std::string& name = (iter->second).name;
966 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value) );
970 iter->second.setFunc( object, index, value );
974 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
976 // call base type recursively
977 mBaseType->SetProperty( object, index, value );
981 DALI_LOG_ERROR( "Property index %d not found\n", index );
985 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
987 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
988 PropertyNameFinder< RegisteredPropertyPair >( name ) );
989 if ( iter != mRegisteredProperties.end() )
991 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
995 // CSharp wants a property name not an index
996 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value ));
1000 iter->second.setFunc( object, iter->first, value );
1003 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1005 // call base type recursively
1006 mBaseType->SetProperty( object, name, value );
1010 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1014 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
1016 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1017 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
1018 if( iter != mRegisteredProperties.end() )
1020 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1022 // CSharp wants a property name not an index
1023 // CSharp callback can't return an object by value, it can only return a pointer
1024 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1025 const std::string& name = (iter->second).name;
1027 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str()) );
1032 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1033 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
1037 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1039 // call base type recursively
1040 return mBaseType->GetProperty( object, index );
1043 DALI_LOG_ERROR( "Property index %d not found\n", index );
1044 return Property::Value();
1047 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
1049 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1050 PropertyNameFinder< RegisteredPropertyPair >( name ) );
1054 if( iter != mRegisteredProperties.end() )
1056 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1058 // CSharp wants a property name not an index
1059 // CSharp callback can't return an object by value, it can only return a pointer
1060 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1061 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() ));
1066 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1067 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
1071 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1073 // call base type recursively
1074 return mBaseType->GetProperty( object, name );
1077 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1078 return Property::Value();
1081 } // namespace Internal