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() = default;
181 BaseHandle TypeInfo::CreateInstance() const
189 // CSharp currently only registers one create function for all custom controls
190 // it uses the type name to decide which one to create
191 ret = *mCSharpCreate( mTypeName.c_str() );
200 BaseObject& handle = ret.GetBaseObject();
201 Object *object = dynamic_cast<Internal::Object*>(&handle);
205 object->SetTypeInfo( this );
212 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
216 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
218 if( iter != mActions.end() )
220 done = (iter->second)(object, actionName, properties);
225 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
227 // call base type recursively
228 done = mBaseType->DoActionTo( object, actionName, properties );
235 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
237 bool connected( false );
239 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
240 PairFinder<std::string, ConnectionPair>(signalName) );
242 if( iter != mSignalConnectors.end() )
244 connected = (iter->second)( object, connectionTracker, signalName, functor );
249 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
251 // call base type recursively
252 connected = mBaseType->ConnectSignal( object, connectionTracker, signalName, functor );
259 const std::string& TypeInfo::GetName() const
264 const std::string& TypeInfo::GetBaseName() const
266 return mBaseTypeName;
269 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
274 uint32_t TypeInfo::GetActionCount() const
276 uint32_t count = static_cast<uint32_t>( mActions.size() );
278 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
280 // call base type recursively
281 count += mBaseType->GetActionCount();
287 std::string TypeInfo::GetActionName( uint32_t index ) const
290 const uint32_t count = static_cast<uint32_t>( mActions.size() );
294 name = mActions[index].first;
298 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
300 // call base type recursively
301 return mBaseType->GetActionName( index - count );
308 uint32_t TypeInfo::GetSignalCount() const
310 uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
312 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
314 // call base type recursively
315 count += mBaseType->GetSignalCount();
321 std::string TypeInfo::GetSignalName( uint32_t index ) const
324 const uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
328 name = mSignalConnectors[index].first;
332 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
334 // call base type recursively
335 return mBaseType->GetSignalName( index - count );
342 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
344 // Default Properties
345 if( mDefaultProperties )
347 indices.Reserve( indices.Size() + mDefaultPropertyCount );
348 for( Property::Index index = 0; index < mDefaultPropertyCount; ++index )
350 indices.PushBack( mDefaultProperties[ index ].enumIndex );
354 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
356 // call base type recursively
357 mBaseType->GetPropertyIndices( indices );
360 AppendProperties( indices, mRegisteredProperties );
363 void TypeInfo::GetChildPropertyIndices( Property::IndexContainer& indices ) const
365 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
367 // call base type recursively
368 mBaseType->GetChildPropertyIndices( indices );
371 AppendProperties( indices, mRegisteredChildProperties );
375 * Append the indices in RegisteredProperties to the given index container.
377 void TypeInfo::AppendProperties( Dali::Property::IndexContainer& indices,
378 const TypeInfo::RegisteredPropertyContainer& registeredProperties ) const
380 if ( ! registeredProperties.empty() )
382 indices.Reserve( indices.Size() + registeredProperties.size() );
384 for( auto&& elem : registeredProperties )
386 indices.PushBack( elem.first );
391 const std::string& TypeInfo::GetRegisteredPropertyName( Property::Index index ) const
393 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
394 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
395 if ( iter != mRegisteredProperties.end() )
397 return iter->second.name;
399 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
401 // call base type recursively
402 return mBaseType->GetRegisteredPropertyName( index );
404 static std::string empty;
408 std::string TypeInfo::GetPropertyName( Property::Index index ) const
410 std::string propertyName;
412 if ( mDefaultProperties && ( index < DEFAULT_PROPERTY_MAX_COUNT ) )
414 std::string_view name;
415 if( GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::name, name ) )
422 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
423 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
424 if ( iter != mRegisteredProperties.end() )
426 return iter->second.name;
429 // if not our property, go to parent
430 if( propertyName.empty() )
432 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
434 // call base type recursively
435 return mBaseType->GetPropertyName( index );
442 void TypeInfo::AddActionFunction(std::string actionName, Dali::TypeInfo::ActionFunction function)
444 if( nullptr == function)
446 DALI_LOG_WARNING("Action function is empty\n");
450 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
451 PairFinder<std::string, ActionPair>(actionName));
453 if( iter == mActions.end() )
455 mActions.push_back(ActionPair(std::move(actionName), function));
459 DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
464 void TypeInfo::AddConnectorFunction(std::string signalName, Dali::TypeInfo::SignalConnectorFunction function)
466 if( nullptr == function)
468 DALI_LOG_WARNING("Connector function is empty\n");
472 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
473 PairFinder<std::string, ConnectionPair>(signalName) );
475 if( iter == mSignalConnectors.end() )
477 mSignalConnectors.push_back(ConnectionPair(std::move(signalName), function));
481 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
486 void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc)
488 // The setter can be empty as a property can be read-only.
490 if ( nullptr == getFunc )
492 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
496 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
497 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
499 if ( iter == mRegisteredProperties.end() )
501 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
505 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
510 void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
513 // The setter can be empty as a property can be read-only.
515 if ( nullptr == getFunc )
517 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
521 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
522 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
524 if ( iter == mRegisteredProperties.end() )
526 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
530 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
536 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Type type)
538 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
539 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
541 if ( iter == mRegisteredProperties.end() )
543 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
547 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
551 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Value defaultValue)
553 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
554 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
556 if ( iter == mRegisteredProperties.end() )
558 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(defaultValue.GetType(), std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
559 mPropertyDefaultValues.push_back(PropertyDefaultValuePair(index, std::move(defaultValue)));
563 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
567 void TypeInfo::AddAnimatablePropertyComponent(std::string name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex)
569 Property::Type type = GetPropertyType( baseIndex );
570 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
572 bool success = false;
574 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
575 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
577 if ( iter == mRegisteredProperties.end() )
579 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
580 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
582 if ( iter == mRegisteredProperties.end() )
584 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), baseIndex, componentIndex)));
589 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
592 void TypeInfo::AddChildProperty(std::string name, Property::Index index, Property::Type type)
594 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
595 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
597 if ( iter == mRegisteredChildProperties.end() )
599 mRegisteredChildProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, std::move(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
603 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
607 uint32_t TypeInfo::GetPropertyCount() const
609 uint32_t count = mDefaultPropertyCount + static_cast<uint32_t>( mRegisteredProperties.size() );
611 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
613 // call base type recursively
614 count += mBaseType->GetPropertyCount();
620 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
622 Property::Index index = Property::INVALID_INDEX;
625 // check default properties
626 if( mDefaultProperties )
628 for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex )
630 if(mDefaultProperties[tableIndex].name == name)
632 index = mDefaultProperties[ tableIndex ].enumIndex;
640 // Slow but should not be done that often
641 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
642 PropertyNameFinder< RegisteredPropertyPair >( name ) );
643 if ( iter != mRegisteredProperties.end() )
647 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
649 // call base type recursively
650 index = mBaseType->GetPropertyIndex( name );
657 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
659 Property::Index basePropertyIndex = Property::INVALID_INDEX;
661 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
662 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
664 if ( iter != mRegisteredProperties.end() )
666 basePropertyIndex = iter->second.basePropertyIndex;
668 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
670 // call base type recursively
671 basePropertyIndex = mBaseType->GetBasePropertyIndex( index );
674 return basePropertyIndex;
677 int32_t TypeInfo::GetComponentIndex( Property::Index index ) const
679 int componentIndex = Property::INVALID_COMPONENT_INDEX;
681 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
682 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
684 if ( iter != mRegisteredProperties.end() )
686 componentIndex = iter->second.componentIndex;
688 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
690 // call base type recursively
691 componentIndex = mBaseType->GetComponentIndex( index );
694 return componentIndex;
697 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
699 Property::Index index = Property::INVALID_INDEX;
701 // Slow but should not be done that often
702 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
703 PropertyNameFinder< RegisteredPropertyPair >( name ) );
705 if ( iter != mRegisteredChildProperties.end() )
709 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
711 // call base type recursively
712 index = mBaseType->GetChildPropertyIndex( name );
718 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
720 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
721 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
723 if ( iter != mRegisteredChildProperties.end() )
725 return iter->second.name;
728 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
730 // call base type recursively
731 return mBaseType->GetChildPropertyName( index );
734 DALI_LOG_ERROR( "Property index %d not found\n", index );
736 static std::string empty;
740 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
742 Property::Type type( Property::NONE );
744 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
745 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
747 if ( iter != mRegisteredChildProperties.end() )
749 type = iter->second.type;
751 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
753 // call base type recursively
754 type = mBaseType->GetChildPropertyType( index );
758 DALI_LOG_ERROR( "Property index %d not found\n", index );
764 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
766 bool writable = false;
770 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
772 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::writable, writable );
774 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
776 writable = true; // animatable property is writable
781 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
782 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
783 if ( iter != mRegisteredProperties.end() )
785 writable = iter->second.setFunc ? true : false;
790 // if not found, continue to base
793 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
795 // call base type recursively
796 writable = mBaseType->IsPropertyWritable( index );
800 DALI_LOG_ERROR( "Property index %d not found\n", index );
807 bool TypeInfo::IsPropertyAnimatable( Property::Index index ) const
809 bool animatable = false;
813 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
815 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::animatable, animatable );
817 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
819 // Type Registry event-thread only properties are not animatable.
823 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
829 // if not found, continue to base
832 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
834 // call base type recursively
835 animatable = mBaseType->IsPropertyAnimatable( index );
839 DALI_LOG_ERROR( "Property index %d not found\n", index );
846 bool TypeInfo::IsPropertyAConstraintInput( Property::Index index ) const
848 bool constraintInput = false;
852 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
854 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::constraintInput, constraintInput );
856 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
858 // Type Registry event-thread only properties cannot be used as constraint input
859 constraintInput = false;
862 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
864 constraintInput = true;
868 // if not found, continue to base
871 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
873 // call base type recursively
874 constraintInput = mBaseType->IsPropertyAConstraintInput( index );
878 DALI_LOG_ERROR( "Property index %d not found\n", index );
882 return constraintInput;
886 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
888 Property::Type type( Property::NONE );
892 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
894 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::type, type );
898 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
899 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
901 if ( iter != mRegisteredProperties.end() )
903 if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX )
905 type = iter->second.type;
910 // If component index is set, then we should return FLOAT
911 type = Property::FLOAT;
919 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
921 // call base type recursively
922 type = mBaseType->GetPropertyType( index );
926 DALI_LOG_ERROR( "Property index %d not found\n", index );
933 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
935 PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
936 PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
937 if( iter != mPropertyDefaultValues.end() )
941 // we didn't have a value so ask base
942 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
944 // call base type recursively
945 return mBaseType->GetPropertyDefaultValue( index );
947 return Property::Value(); // return none
950 void TypeInfo::SetProperty(BaseObject* object, Property::Index index, Property::Value value) const
952 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
953 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
954 if ( iter != mRegisteredProperties.end() )
956 if( iter->second.setFunc )
960 // CSharp wants a property name not an index
961 const std::string& name = (iter->second).name;
963 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value) );
967 iter->second.setFunc(object, index, std::move(value));
971 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
973 // call base type recursively
974 mBaseType->SetProperty(object, index, std::move(value));
978 DALI_LOG_ERROR( "Property index %d not found\n", index );
982 void TypeInfo::SetProperty(BaseObject* object, const std::string& name, Property::Value value) const
984 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
985 PropertyNameFinder< RegisteredPropertyPair >( name ) );
986 if ( iter != mRegisteredProperties.end() )
988 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
992 // CSharp wants a property name not an index
993 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value ));
997 iter->second.setFunc(object, iter->first, std::move(value));
1000 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1002 // call base type recursively
1003 mBaseType->SetProperty(object, name, std::move(value));
1007 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1011 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
1013 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1014 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
1015 if( iter != mRegisteredProperties.end() )
1017 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1019 // CSharp wants a property name not an index
1020 // CSharp callback can't return an object by value, it can only return a pointer
1021 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1022 const std::string& name = (iter->second).name;
1024 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str()) );
1029 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1030 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
1034 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1036 // call base type recursively
1037 return mBaseType->GetProperty( object, index );
1040 DALI_LOG_ERROR( "Property index %d not found\n", index );
1041 return Property::Value();
1044 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
1046 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1047 PropertyNameFinder< RegisteredPropertyPair >( name ) );
1051 if( iter != mRegisteredProperties.end() )
1053 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1055 // CSharp wants a property name not an index
1056 // CSharp callback can't return an object by value, it can only return a pointer
1057 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1058 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() ));
1063 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1064 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
1068 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1070 // call base type recursively
1071 return mBaseType->GetProperty( object, name );
1074 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1075 return Property::Value();
1078 } // namespace Internal