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 std::string_view name;
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(std::string actionName, Dali::TypeInfo::ActionFunction function)
446 if( nullptr == 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(std::move(actionName), function));
461 DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
466 void TypeInfo::AddConnectorFunction(std::string signalName, Dali::TypeInfo::SignalConnectorFunction function)
468 if( nullptr == 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(std::move(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(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 ( nullptr == 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, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
507 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
512 void TypeInfo::AddProperty(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 ( nullptr == 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, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
532 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
538 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Type type)
540 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
541 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
543 if ( iter == mRegisteredProperties.end() )
545 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
549 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
553 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Value defaultValue)
555 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
556 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
558 if ( iter == mRegisteredProperties.end() )
560 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(defaultValue.GetType(), std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
561 mPropertyDefaultValues.push_back(PropertyDefaultValuePair(index, std::move(defaultValue)));
565 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
569 void TypeInfo::AddAnimatablePropertyComponent(std::string name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex)
571 Property::Type type = GetPropertyType( baseIndex );
572 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
574 bool success = false;
576 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
577 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
579 if ( iter == mRegisteredProperties.end() )
581 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
582 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
584 if ( iter == mRegisteredProperties.end() )
586 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), baseIndex, componentIndex)));
591 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
594 void TypeInfo::AddChildProperty(std::string name, Property::Index index, Property::Type type)
596 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
597 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
599 if ( iter == mRegisteredChildProperties.end() )
601 mRegisteredChildProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
605 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
609 uint32_t TypeInfo::GetPropertyCount() const
611 uint32_t count = mDefaultPropertyCount + static_cast<uint32_t>( mRegisteredProperties.size() );
613 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
615 // call base type recursively
616 count += mBaseType->GetPropertyCount();
622 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
624 Property::Index index = Property::INVALID_INDEX;
627 // check default properties
628 if( mDefaultProperties )
630 for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex )
632 if(mDefaultProperties[tableIndex].name == name)
634 index = mDefaultProperties[ tableIndex ].enumIndex;
642 // Slow but should not be done that often
643 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
644 PropertyNameFinder< RegisteredPropertyPair >( name ) );
645 if ( iter != mRegisteredProperties.end() )
649 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
651 // call base type recursively
652 index = mBaseType->GetPropertyIndex( name );
659 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
661 Property::Index basePropertyIndex = Property::INVALID_INDEX;
663 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
664 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
666 if ( iter != mRegisteredProperties.end() )
668 basePropertyIndex = iter->second.basePropertyIndex;
670 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
672 // call base type recursively
673 basePropertyIndex = mBaseType->GetBasePropertyIndex( index );
676 return basePropertyIndex;
679 int32_t TypeInfo::GetComponentIndex( Property::Index index ) const
681 int componentIndex = Property::INVALID_COMPONENT_INDEX;
683 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
684 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
686 if ( iter != mRegisteredProperties.end() )
688 componentIndex = iter->second.componentIndex;
690 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
692 // call base type recursively
693 componentIndex = mBaseType->GetComponentIndex( index );
696 return componentIndex;
699 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
701 Property::Index index = Property::INVALID_INDEX;
703 // Slow but should not be done that often
704 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
705 PropertyNameFinder< RegisteredPropertyPair >( name ) );
707 if ( iter != mRegisteredChildProperties.end() )
711 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
713 // call base type recursively
714 index = mBaseType->GetChildPropertyIndex( name );
720 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
722 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
723 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
725 if ( iter != mRegisteredChildProperties.end() )
727 return iter->second.name;
730 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
732 // call base type recursively
733 return mBaseType->GetChildPropertyName( index );
736 DALI_LOG_ERROR( "Property index %d not found\n", index );
738 static std::string empty;
742 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
744 Property::Type type( Property::NONE );
746 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
747 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
749 if ( iter != mRegisteredChildProperties.end() )
751 type = iter->second.type;
753 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
755 // call base type recursively
756 type = mBaseType->GetChildPropertyType( index );
760 DALI_LOG_ERROR( "Property index %d not found\n", index );
766 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
768 bool writable = false;
772 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
774 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::writable, writable );
776 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
778 writable = true; // animatable property is writable
783 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
784 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
785 if ( iter != mRegisteredProperties.end() )
787 writable = iter->second.setFunc ? true : false;
792 // if not found, continue to base
795 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
797 // call base type recursively
798 writable = mBaseType->IsPropertyWritable( index );
802 DALI_LOG_ERROR( "Property index %d not found\n", index );
809 bool TypeInfo::IsPropertyAnimatable( Property::Index index ) const
811 bool animatable = false;
815 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
817 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::animatable, animatable );
819 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
821 // Type Registry event-thread only properties are not animatable.
825 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
831 // if not found, continue to base
834 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
836 // call base type recursively
837 animatable = mBaseType->IsPropertyAnimatable( index );
841 DALI_LOG_ERROR( "Property index %d not found\n", index );
848 bool TypeInfo::IsPropertyAConstraintInput( Property::Index index ) const
850 bool constraintInput = false;
854 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
856 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::constraintInput, constraintInput );
858 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
860 // Type Registry event-thread only properties cannot be used as constraint input
861 constraintInput = false;
864 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
866 constraintInput = true;
870 // if not found, continue to base
873 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
875 // call base type recursively
876 constraintInput = mBaseType->IsPropertyAConstraintInput( index );
880 DALI_LOG_ERROR( "Property index %d not found\n", index );
884 return constraintInput;
888 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
890 Property::Type type( Property::NONE );
894 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
896 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::type, type );
900 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
901 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
903 if ( iter != mRegisteredProperties.end() )
905 if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX )
907 type = iter->second.type;
912 // If component index is set, then we should return FLOAT
913 type = Property::FLOAT;
921 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
923 // call base type recursively
924 type = mBaseType->GetPropertyType( index );
928 DALI_LOG_ERROR( "Property index %d not found\n", index );
935 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
937 PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
938 PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
939 if( iter != mPropertyDefaultValues.end() )
943 // we didn't have a value so ask base
944 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
946 // call base type recursively
947 return mBaseType->GetPropertyDefaultValue( index );
949 return Property::Value(); // return none
952 void TypeInfo::SetProperty(BaseObject* object, Property::Index index, Property::Value value) const
954 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
955 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
956 if ( iter != mRegisteredProperties.end() )
958 if( iter->second.setFunc )
962 // CSharp wants a property name not an index
963 const std::string& name = (iter->second).name;
965 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value) );
969 iter->second.setFunc(object, index, std::move(value));
973 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
975 // call base type recursively
976 mBaseType->SetProperty(object, index, std::move(value));
980 DALI_LOG_ERROR( "Property index %d not found\n", index );
984 void TypeInfo::SetProperty(BaseObject* object, const std::string& name, Property::Value value) const
986 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
987 PropertyNameFinder< RegisteredPropertyPair >( name ) );
988 if ( iter != mRegisteredProperties.end() )
990 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
994 // CSharp wants a property name not an index
995 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value ));
999 iter->second.setFunc(object, iter->first, std::move(value));
1002 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1004 // call base type recursively
1005 mBaseType->SetProperty(object, name, std::move(value));
1009 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1013 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
1015 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1016 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
1017 if( iter != mRegisteredProperties.end() )
1019 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1021 // CSharp wants a property name not an index
1022 // CSharp callback can't return an object by value, it can only return a pointer
1023 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1024 const std::string& name = (iter->second).name;
1026 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str()) );
1031 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1032 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
1036 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1038 // call base type recursively
1039 return mBaseType->GetProperty( object, index );
1042 DALI_LOG_ERROR( "Property index %d not found\n", index );
1043 return Property::Value();
1046 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
1048 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1049 PropertyNameFinder< RegisteredPropertyPair >( name ) );
1053 if( iter != mRegisteredProperties.end() )
1055 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1057 // CSharp wants a property name not an index
1058 // CSharp callback can't return an object by value, it can only return a pointer
1059 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1060 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() ));
1065 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1066 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
1070 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1072 // call base type recursively
1073 return mBaseType->GetProperty( object, name );
1076 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1077 return Property::Value();
1080 } // namespace Internal