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(ConstString find)
73 bool operator()(const T &p) const
75 return p.second.name == mFind;
83 * Functor to find a matching property component index
86 struct PropertyComponentFinder
88 PropertyComponentFinder( Property::Index basePropertyIndex, const int find )
89 : mBasePropertyIndex( basePropertyIndex ),
94 bool operator()(const T &p) const
96 return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
101 Property::Index mBasePropertyIndex;
106 * Helper function to find the right default property with given index and return the desired detail of it
108 template< typename Parameter, typename Member >
109 inline bool GetDefaultPropertyField( const Dali::PropertyDetails* propertyTable, Property::Index count, Property::Index index, Member member, Parameter& parameter )
112 // is index inside this table (bigger than first index but smaller than first + count)
113 if( ( index >= propertyTable->enumIndex ) && ( index < ( propertyTable->enumIndex + count ) ) )
115 // return the match. we're assuming here that there is no gaps between the indices in a table
116 parameter = propertyTable[ index - propertyTable->enumIndex ].*member;
119 // should never really get here
123 // static pointer value to mark that a base class address has not been resolved
124 // 0x01 is not a valid pointer but used here to differentiate from nullptr
125 // unfortunately it cannot be constexpr as C++ does not allow them to be initialised with reinterpret_cast
126 Internal::TypeInfo* const UNRESOLVED = reinterpret_cast<Internal::TypeInfo*>( 0x1 );
129 * Helper function to resolve and return the pointer to the base type info
130 * Not a member function to avoid having to #include additional headers and to make sure this gets inlined inside this cpp
131 * @param[in/out] baseType pointer to resolve and set
132 * @param[in] typeRegistry reference to the type registry
133 * @param[in] baseTypeName string name of the base type
134 * @return true is base type exists
136 inline bool GetBaseType( Internal::TypeInfo*& baseType, TypeRegistry& typeRegistry, const std::string& baseTypeName )
138 // if greater than unresolved means we have a base type, null means no base
139 bool baseExists = ( baseType > UNRESOLVED );
140 // base only needs to be resolved once
141 if( UNRESOLVED == baseType )
143 TypeRegistry::TypeInfoPointer base = typeRegistry.GetTypeInfo( baseTypeName );
146 baseType = base.Get(); // dont pass ownership, just return raw pointer
151 // no type info found so assuming no base as all type registration is done in startup for now
158 } // unnamed namespace
160 TypeInfo::TypeInfo( const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator,
161 const Dali::PropertyDetails* defaultProperties, Property::Index defaultPropertyCount )
162 : mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ),
163 mTypeName( name ), mBaseTypeName( baseTypeName ), mCreate( creator ), mDefaultProperties( defaultProperties ),
164 mDefaultPropertyCount( defaultPropertyCount ), mCSharpType( false )
166 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
167 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
170 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::CSharpTypeInfo::CreateFunction creator)
171 : mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ),
172 mTypeName( name ), mBaseTypeName( baseTypeName ), mCSharpCreate( creator ), mCSharpType( true )
174 DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
175 DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
178 TypeInfo::~TypeInfo() = default;
180 BaseHandle TypeInfo::CreateInstance() const
188 // CSharp currently only registers one create function for all custom controls
189 // it uses the type name to decide which one to create
190 ret = *mCSharpCreate( mTypeName.c_str() );
199 BaseObject& handle = ret.GetBaseObject();
200 Object *object = dynamic_cast<Internal::Object*>(&handle);
204 object->SetTypeInfo( this );
211 bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
215 ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
217 if( iter != mActions.end() )
219 done = (iter->second)(object, actionName, properties);
224 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
226 // call base type recursively
227 done = mBaseType->DoActionTo( object, actionName, properties );
234 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
236 bool connected( false );
238 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
239 PairFinder<std::string, ConnectionPair>(signalName) );
241 if( iter != mSignalConnectors.end() )
243 connected = (iter->second)( object, connectionTracker, signalName, functor );
248 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
250 // call base type recursively
251 connected = mBaseType->ConnectSignal( object, connectionTracker, signalName, functor );
258 const std::string& TypeInfo::GetName() const
263 const std::string& TypeInfo::GetBaseName() const
265 return mBaseTypeName;
268 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
273 uint32_t TypeInfo::GetActionCount() const
275 uint32_t count = static_cast<uint32_t>( mActions.size() );
277 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
279 // call base type recursively
280 count += mBaseType->GetActionCount();
286 std::string TypeInfo::GetActionName( uint32_t index ) const
289 const uint32_t count = static_cast<uint32_t>( mActions.size() );
293 name = mActions[index].first;
297 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
299 // call base type recursively
300 return mBaseType->GetActionName( index - count );
307 uint32_t TypeInfo::GetSignalCount() const
309 uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
311 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
313 // call base type recursively
314 count += mBaseType->GetSignalCount();
320 std::string TypeInfo::GetSignalName( uint32_t index ) const
323 const uint32_t count = static_cast<uint32_t>( mSignalConnectors.size() );
327 name = mSignalConnectors[index].first;
331 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
333 // call base type recursively
334 return mBaseType->GetSignalName( index - count );
341 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
343 // Default Properties
344 if( mDefaultProperties )
346 indices.Reserve( indices.Size() + mDefaultPropertyCount );
347 for( Property::Index index = 0; index < mDefaultPropertyCount; ++index )
349 indices.PushBack( mDefaultProperties[ index ].enumIndex );
353 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
355 // call base type recursively
356 mBaseType->GetPropertyIndices( indices );
359 AppendProperties( indices, mRegisteredProperties );
362 void TypeInfo::GetChildPropertyIndices( Property::IndexContainer& indices ) const
364 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
366 // call base type recursively
367 mBaseType->GetChildPropertyIndices( indices );
370 AppendProperties( indices, mRegisteredChildProperties );
374 * Append the indices in RegisteredProperties to the given index container.
376 void TypeInfo::AppendProperties( Dali::Property::IndexContainer& indices,
377 const TypeInfo::RegisteredPropertyContainer& registeredProperties ) const
379 if ( ! registeredProperties.empty() )
381 indices.Reserve( indices.Size() + registeredProperties.size() );
383 for( auto&& elem : registeredProperties )
385 indices.PushBack( elem.first );
390 std::string_view TypeInfo::GetRegisteredPropertyName(Property::Index index) const
392 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
393 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
394 if ( iter != mRegisteredProperties.end() )
396 return iter->second.name.GetStringView();
398 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
400 // call base type recursively
401 return mBaseType->GetRegisteredPropertyName( index );
403 static std::string empty;
407 std::string_view TypeInfo::GetPropertyName(Property::Index index) const
409 std::string_view propertyName;
411 if ( mDefaultProperties && ( index < DEFAULT_PROPERTY_MAX_COUNT ) )
413 std::string_view name;
414 if( GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::name, name ) )
421 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
422 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
423 if ( iter != mRegisteredProperties.end() )
425 return iter->second.name.GetStringView();
428 // if not our property, go to parent
429 if( propertyName.empty() )
431 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
433 // call base type recursively
434 return mBaseType->GetPropertyName( index );
441 void TypeInfo::AddActionFunction(std::string actionName, Dali::TypeInfo::ActionFunction function)
443 if( nullptr == function)
445 DALI_LOG_WARNING("Action function is empty\n");
449 ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
450 PairFinder<std::string, ActionPair>(actionName));
452 if( iter == mActions.end() )
454 mActions.push_back(ActionPair(std::move(actionName), function));
458 DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
463 void TypeInfo::AddConnectorFunction(std::string signalName, Dali::TypeInfo::SignalConnectorFunction function)
465 if( nullptr == function)
467 DALI_LOG_WARNING("Connector function is empty\n");
471 ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
472 PairFinder<std::string, ConnectionPair>(signalName) );
474 if( iter == mSignalConnectors.end() )
476 mSignalConnectors.push_back(ConnectionPair(std::move(signalName), function));
480 DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
485 void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc)
487 // The setter can be empty as a property can be read-only.
489 if ( nullptr == getFunc )
491 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
495 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
496 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
498 if ( iter == mRegisteredProperties.end() )
500 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
504 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
509 void TypeInfo::AddProperty(std::string name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
512 // The setter can be empty as a property can be read-only.
514 if ( nullptr == getFunc )
516 DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
520 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
521 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
523 if ( iter == mRegisteredProperties.end() )
525 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, setFunc, getFunc, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
529 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
535 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Type type)
537 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
538 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
540 if ( iter == mRegisteredProperties.end() )
542 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
546 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
550 void TypeInfo::AddAnimatableProperty(std::string name, Property::Index index, Property::Value defaultValue)
552 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
553 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
555 if ( iter == mRegisteredProperties.end() )
557 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(defaultValue.GetType(), ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
558 mPropertyDefaultValues.push_back(PropertyDefaultValuePair(index, std::move(defaultValue)));
562 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
566 void TypeInfo::AddAnimatablePropertyComponent(std::string name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex)
568 Property::Type type = GetPropertyType( baseIndex );
569 DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
571 bool success = false;
573 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
574 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
576 if ( iter == mRegisteredProperties.end() )
578 iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
579 PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
581 if ( iter == mRegisteredProperties.end() )
583 mRegisteredProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, ConstString(name), baseIndex, componentIndex)));
588 DALI_ASSERT_ALWAYS( success && "Property component already registered" );
591 void TypeInfo::AddChildProperty(std::string name, Property::Index index, Property::Type type)
593 RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
594 PairFinder< Property::Index, RegisteredPropertyPair>(index) );
596 if ( iter == mRegisteredChildProperties.end() )
598 mRegisteredChildProperties.push_back(RegisteredPropertyPair(index, RegisteredProperty(type, ConstString(name), Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX)));
602 DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
606 uint32_t TypeInfo::GetPropertyCount() const
608 uint32_t count = mDefaultPropertyCount + static_cast<uint32_t>( mRegisteredProperties.size() );
610 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
612 // call base type recursively
613 count += mBaseType->GetPropertyCount();
619 Property::Index TypeInfo::GetPropertyIndex(ConstString name) const
621 Property::Index index = Property::INVALID_INDEX;
624 // check default properties
625 if( mDefaultProperties )
627 auto stringView = name.GetStringView();
628 for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex )
630 if(mDefaultProperties[tableIndex].name == stringView)
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(ConstString 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 std::string_view 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.GetStringView();
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 );
739 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
741 Property::Type type( Property::NONE );
743 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
744 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
746 if ( iter != mRegisteredChildProperties.end() )
748 type = iter->second.type;
750 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
752 // call base type recursively
753 type = mBaseType->GetChildPropertyType( index );
757 DALI_LOG_ERROR( "Property index %d not found\n", index );
763 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
765 bool writable = false;
769 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
771 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::writable, writable );
773 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
775 writable = true; // animatable property is writable
780 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
781 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
782 if ( iter != mRegisteredProperties.end() )
784 writable = iter->second.setFunc ? true : false;
789 // if not found, continue to base
792 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
794 // call base type recursively
795 writable = mBaseType->IsPropertyWritable( index );
799 DALI_LOG_ERROR( "Property index %d not found\n", index );
806 bool TypeInfo::IsPropertyAnimatable( Property::Index index ) const
808 bool animatable = false;
812 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
814 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::animatable, animatable );
816 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
818 // Type Registry event-thread only properties are not animatable.
822 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
828 // if not found, continue to base
831 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
833 // call base type recursively
834 animatable = mBaseType->IsPropertyAnimatable( index );
838 DALI_LOG_ERROR( "Property index %d not found\n", index );
845 bool TypeInfo::IsPropertyAConstraintInput( Property::Index index ) const
847 bool constraintInput = false;
851 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
853 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::constraintInput, constraintInput );
855 else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) )
857 // Type Registry event-thread only properties cannot be used as constraint input
858 constraintInput = false;
861 else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
863 constraintInput = true;
867 // if not found, continue to base
870 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
872 // call base type recursively
873 constraintInput = mBaseType->IsPropertyAConstraintInput( index );
877 DALI_LOG_ERROR( "Property index %d not found\n", index );
881 return constraintInput;
885 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
887 Property::Type type( Property::NONE );
891 if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties )
893 found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::type, type );
897 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
898 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
900 if ( iter != mRegisteredProperties.end() )
902 if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX )
904 type = iter->second.type;
909 // If component index is set, then we should return FLOAT
910 type = Property::FLOAT;
918 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
920 // call base type recursively
921 type = mBaseType->GetPropertyType( index );
925 DALI_LOG_ERROR( "Property index %d not found\n", index );
932 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
934 PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
935 PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
936 if( iter != mPropertyDefaultValues.end() )
940 // we didn't have a value so ask base
941 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
943 // call base type recursively
944 return mBaseType->GetPropertyDefaultValue( index );
946 return Property::Value(); // return none
949 void TypeInfo::SetProperty(BaseObject* object, Property::Index index, Property::Value value) const
951 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
952 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
953 if ( iter != mRegisteredProperties.end() )
955 if( iter->second.setFunc )
959 // CSharp wants a property name not an index
960 auto name = (iter->second).name;
962 iter->second.cSharpSetFunc(object, name.GetCString(), const_cast<Property::Value*>(&value));
966 iter->second.setFunc(object, index, std::move(value));
970 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
972 // call base type recursively
973 mBaseType->SetProperty(object, index, std::move(value));
977 DALI_LOG_ERROR( "Property index %d not found\n", index );
981 void TypeInfo::SetProperty(BaseObject* object, const std::string& name, Property::Value value) const
983 RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyNameFinder<RegisteredPropertyPair>(ConstString(name)));
984 if ( iter != mRegisteredProperties.end() )
986 DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
990 // CSharp wants a property name not an index
991 iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value ));
995 iter->second.setFunc(object, iter->first, std::move(value));
998 else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1000 // call base type recursively
1001 mBaseType->SetProperty(object, name, std::move(value));
1005 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1009 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
1011 RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
1012 PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
1013 if( iter != mRegisteredProperties.end() )
1015 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1017 // CSharp wants a property name not an index
1018 // CSharp callback can't return an object by value, it can only return a pointer
1019 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1020 auto name = (iter->second).name;
1022 return *(iter->second.cSharpGetFunc(const_cast<BaseObject*>(object), name.GetCString()));
1026 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1027 return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
1031 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1033 // call base type recursively
1034 return mBaseType->GetProperty( object, index );
1037 DALI_LOG_ERROR( "Property index %d not found\n", index );
1038 return Property::Value();
1041 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
1043 RegisteredPropertyContainer::const_iterator iter = find_if(mRegisteredProperties.begin(), mRegisteredProperties.end(), PropertyNameFinder<RegisteredPropertyPair>(ConstString(name)));
1045 if( iter != mRegisteredProperties.end() )
1047 if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
1049 // CSharp wants a property name not an index
1050 // CSharp callback can't return an object by value, it can only return a pointer
1051 // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value
1052 return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() ));
1057 // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
1058 return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
1062 if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) )
1064 // call base type recursively
1065 return mBaseType->GetProperty( object, name );
1068 DALI_LOG_ERROR( "Property %s not found", name.c_str() );
1069 return Property::Value();
1072 } // namespace Internal