X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fcommon%2Ftype-info-impl.cpp;h=65f63fc36929069b3141cff2cb32217775c27b40;hb=aee2350a06fac17860817a0e84ff97a4553dbbaa;hp=7efff5237323b896b122f1bde6844f6b6d6732ce;hpb=b1ce4d4fcd7c85330c5fe99465c78bb8b9c42244;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/common/type-info-impl.cpp b/dali/internal/event/common/type-info-impl.cpp index 7efff52..65f63fc 100644 --- a/dali/internal/event/common/type-info-impl.cpp +++ b/dali/internal/event/common/type-info-impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd. + * Copyright (c) 2018 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,12 @@ using std::find_if; +namespace Dali +{ + +namespace Internal +{ + namespace { @@ -80,7 +86,7 @@ private: template struct PropertyComponentFinder { - PropertyComponentFinder( Dali::Property::Index basePropertyIndex, const int find ) + PropertyComponentFinder( Property::Index basePropertyIndex, const int find ) : mBasePropertyIndex( basePropertyIndex ), mFind( find ) { @@ -93,20 +99,78 @@ struct PropertyComponentFinder private: - Dali::Property::Index mBasePropertyIndex; + Property::Index mBasePropertyIndex; const int mFind; }; -} // namespace anon +/** + * Helper function to find the right default property with given index and return the desired detail of it + */ +template< typename Parameter, typename Member > +inline bool GetDefaultPropertyField( const Dali::PropertyDetails* propertyTable, Property::Index count, Property::Index index, Member member, Parameter& parameter ) +{ + bool found = false; + // is index inside this table (bigger than first index but smaller than first + count) + if( ( index >= propertyTable->enumIndex ) && ( index < ( propertyTable->enumIndex + count ) ) ) + { + // return the match. we're assuming here that there is no gaps between the indices in a table + parameter = propertyTable[ index - propertyTable->enumIndex ].*member; + found = true; + } + // should never really get here + return found; +} + +// static pointer value to mark that a base class address has not been resolved +// 0x01 is not a valid pointer but used here to differentiate from nullptr +// unfortunately it cannot be constexpr as C++ does not allow them to be initialised with reinterpret_cast +Internal::TypeInfo* const UNRESOLVED = reinterpret_cast( 0x1 ); -namespace Dali +/** + * Helper function to resolve and return the pointer to the base type info + * Not a member function to avoid having to #include additional headers and to make sure this gets inlined inside this cpp + * @param[in/out] baseType pointer to resolve and set + * @param[in] typeRegistry reference to the type registry + * @param[in] baseTypeName string name of the base type + * @return true is base type exists + */ +inline bool GetBaseType( Internal::TypeInfo*& baseType, TypeRegistry& typeRegistry, const std::string& baseTypeName ) { + // if greater than unresolved means we have a base type, null means no base + bool baseExists = ( baseType > UNRESOLVED ); + // base only needs to be resolved once + if( UNRESOLVED == baseType ) + { + TypeRegistry::TypeInfoPointer base = typeRegistry.GetTypeInfo( baseTypeName ); + if( base ) + { + baseType = base.Get(); // dont pass ownership, just return raw pointer + baseExists = true; + } + else + { + // no type info found so assuming no base as all type registration is done in startup for now + baseType = nullptr; + } + } + return baseExists; +} -namespace Internal +} // unnamed namespace + +TypeInfo::TypeInfo( const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator, + const Dali::PropertyDetails* defaultProperties, Property::Index defaultPropertyCount ) +: mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ), + mTypeName( name ), mBaseTypeName( baseTypeName ), mCreate( creator ), mDefaultProperties( defaultProperties ), + mDefaultPropertyCount( defaultPropertyCount ), mCSharpType( false ) { + DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name"); + DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name"); +} -TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator) - : mTypeName(name), mBaseTypeName(baseTypeName), mCreate(creator) +TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::CSharpTypeInfo::CreateFunction creator) +: mTypeRegistry( *TypeRegistry::Get() ), mBaseType( UNRESOLVED ), + mTypeName( name ), mBaseTypeName( baseTypeName ), mCSharpCreate( creator ), mCSharpType( true ) { DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name"); DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name"); @@ -122,7 +186,16 @@ BaseHandle TypeInfo::CreateInstance() const if(mCreate) { - ret = mCreate(); + if ( mCSharpType ) + { + // CSharp currently only registers one create function for all custom controls + // it uses the type name to decide which one to create + ret = *mCSharpCreate( mTypeName.c_str() ); + } + else + { + ret = mCreate(); + } if ( ret ) { @@ -138,7 +211,7 @@ BaseHandle TypeInfo::CreateInstance() const return ret; } - bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties) +bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties) { bool done = false; @@ -148,22 +221,13 @@ BaseHandle TypeInfo::CreateInstance() const { done = (iter->second)(object, actionName, properties); } - else - { - DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str()); - } - if(!done) + if( !done ) { - Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName ); - while( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - done = GetImplementation(base).DoActionTo(object, actionName, properties); - if( done ) - { - break; - } - base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() ); + // call base type recursively + done = mBaseType->DoActionTo( object, actionName, properties ); } } @@ -182,6 +246,15 @@ bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* co connected = (iter->second)( object, connectionTracker, signalName, functor ); } + if( !connected ) + { + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + connected = mBaseType->ConnectSignal( object, connectionTracker, signalName, functor ); + } + } + return connected; } @@ -204,11 +277,10 @@ size_t TypeInfo::GetActionCount() const { size_t count = mActions.size(); - Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName ); - while( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - count += GetImplementation(base).mActions.size(); - base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() ); + // call base type recursively + count += mBaseType->GetActionCount(); } return count; @@ -217,29 +289,18 @@ size_t TypeInfo::GetActionCount() const std::string TypeInfo::GetActionName(size_t index) const { std::string name; + const size_t count = mActions.size(); - if( index < mActions.size() ) + if( index < count ) { name = mActions[index].first; } else { - size_t count = mActions.size(); - - Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName ); - while( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - size_t baseCount = GetImplementation(base).mActions.size(); - - if( index < count + baseCount ) - { - name = GetImplementation(base).mActions[ index - count ].first; - break; - } - - count += baseCount; - - base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() ); + // call base type recursively + return mBaseType->GetActionName( index - count ); } } @@ -250,11 +311,10 @@ size_t TypeInfo::GetSignalCount() const { size_t count = mSignalConnectors.size(); - Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName ); - while( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - count += GetImplementation(base).mSignalConnectors.size(); - base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() ); + // call base type recursively + count += mBaseType->GetSignalCount(); } return count; @@ -263,89 +323,122 @@ size_t TypeInfo::GetSignalCount() const std::string TypeInfo::GetSignalName(size_t index) const { std::string name; + const size_t count = mSignalConnectors.size(); - if( index < mSignalConnectors.size() ) + if( index < count ) { name = mSignalConnectors[index].first; } else { - size_t count = mSignalConnectors.size(); - - Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName ); - while( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - size_t baseCount = GetImplementation(base).mSignalConnectors.size(); - - if( index < count + baseCount ) - { - name = GetImplementation(base).mSignalConnectors[ index - count ].first; - break; - } - - count += baseCount; - - base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() ); + // call base type recursively + return mBaseType->GetSignalName( index - count ); } } return name; } -std::string TypeInfo::GetPropertyName(size_t index) const +void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const { - std::string name; - Property::IndexContainer indices; - - GetPropertyIndices(indices); + // Default Properties + if( mDefaultProperties ) + { + indices.Reserve( indices.Size() + mDefaultPropertyCount ); + for( Property::Index index = 0; index < mDefaultPropertyCount; ++index ) + { + indices.PushBack( mDefaultProperties[ index ].enumIndex ); + } + } - if( index < indices.Size() ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - name = GetPropertyName( indices[index] ); + // call base type recursively + mBaseType->GetPropertyIndices( indices ); } - return name; + AppendProperties( indices, mRegisteredProperties ); } - -void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const +void TypeInfo::GetChildPropertyIndices( Property::IndexContainer& indices ) const { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - const TypeInfo& baseImpl( GetImplementation( base ) ); - baseImpl.GetPropertyIndices( indices ); + // call base type recursively + mBaseType->GetChildPropertyIndices( indices ); } - if ( ! mRegisteredProperties.empty() ) + AppendProperties( indices, mRegisteredChildProperties ); +} + +/** + * Append the indices in RegisteredProperties to the given index container. + */ +void TypeInfo::AppendProperties( Dali::Property::IndexContainer& indices, + const TypeInfo::RegisteredPropertyContainer& registeredProperties ) const +{ + if ( ! registeredProperties.empty() ) { - indices.Reserve( indices.Size() + mRegisteredProperties.size() ); + indices.Reserve( indices.Size() + registeredProperties.size() ); - const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end(); - for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter ) + for( auto&& elem : registeredProperties ) { - indices.PushBack( iter->first ); + indices.PushBack( elem.first ); } } } -const std::string& TypeInfo::GetPropertyName( Property::Index index ) const +const std::string& TypeInfo::GetRegisteredPropertyName( Property::Index index ) const { RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); - if ( iter != mRegisteredProperties.end() ) { return iter->second.name; } + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + return mBaseType->GetRegisteredPropertyName( index ); + } + static std::string empty; + return empty; +} - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) +std::string TypeInfo::GetPropertyName( Property::Index index ) const +{ + std::string propertyName; + // default or custom + if ( mDefaultProperties && ( index < DEFAULT_PROPERTY_MAX_COUNT ) ) { - return GetImplementation(base).GetPropertyName( index ); + const char* name = nullptr; + if( GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::name, name ) ) + { + propertyName = name; + } + } + else + { + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + if ( iter != mRegisteredProperties.end() ) + { + return iter->second.name; + } + } + // if not our property, go to parent + if( propertyName.empty() ) + { + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + return mBaseType->GetPropertyName( index ); + } } - DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object + return propertyName; } void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function ) @@ -365,7 +458,7 @@ void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo: } else { - DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str()); + DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str()); } } } @@ -387,7 +480,7 @@ void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeIn } else { - DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str()); + DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str()); } } } @@ -416,6 +509,33 @@ void TypeInfo::AddProperty( const std::string& name, Property::Index index, Prop } } +void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc) +{ + + // The setter can be empty as a property can be read-only. + + if ( NULL == getFunc ) + { + DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" ); + } + else + { + RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair>(index) ); + + if ( iter == mRegisteredProperties.end() ) + { + mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) ); + } + else + { + DALI_ASSERT_ALWAYS( ! "Property index already added to Type" ); + } + } + +} + + void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type ) { RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), @@ -423,7 +543,23 @@ void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index i if ( iter == mRegisteredProperties.end() ) { - mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) ); + mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) ); + } + else + { + DALI_ASSERT_ALWAYS( ! "Property index already added to Type" ); + } +} + +void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue ) +{ + RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair>(index) ); + + if ( iter == mRegisteredProperties.end() ) + { + mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) ); + mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) ); } else { @@ -431,7 +567,7 @@ void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index i } } -void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex ) +void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, uint32_t componentIndex ) { Property::Type type = GetPropertyType( baseIndex ); DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" ); @@ -448,7 +584,7 @@ void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property if ( iter == mRegisteredProperties.end() ) { - mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, baseIndex, componentIndex ) ) ); + mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, baseIndex, componentIndex ) ) ); success = true; } } @@ -456,16 +592,29 @@ void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property DALI_ASSERT_ALWAYS( success && "Property component already registered" ); } -size_t TypeInfo::GetPropertyCount() const +void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type ) { - size_t count( mRegisteredProperties.size() ); + RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair>(index) ); - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - while ( base ) + if ( iter == mRegisteredChildProperties.end() ) + { + mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) ); + } + else { - const TypeInfo& baseImpl( GetImplementation(base) ); - count += baseImpl.mRegisteredProperties.size(); - base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName ); + DALI_ASSERT_ALWAYS( ! "Property index already added to Type" ); + } +} + +uint32_t TypeInfo::GetPropertyCount() const +{ + uint32_t count = mDefaultPropertyCount + static_cast( mRegisteredProperties.size() ); + + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + count += mBaseType->GetPropertyCount(); } return count; @@ -474,21 +623,34 @@ size_t TypeInfo::GetPropertyCount() const Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const { Property::Index index = Property::INVALID_INDEX; + bool found = false; - // Slow but should not be done that often - RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), - PropertyNameFinder< RegisteredPropertyPair >( name ) ); - - if ( iter != mRegisteredProperties.end() ) + // check default properties + if( mDefaultProperties ) { - index = iter->first; + for( Property::Index tableIndex = 0; tableIndex < mDefaultPropertyCount; ++tableIndex ) + { + if( 0 == name.compare( mDefaultProperties[ tableIndex ].name ) ) + { + index = mDefaultProperties[ tableIndex ].enumIndex; + found = true; + break; + } + } } - else + if( !found ) { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + // Slow but should not be done that often + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PropertyNameFinder< RegisteredPropertyPair >( name ) ); + if ( iter != mRegisteredProperties.end() ) { - index = GetImplementation(base).GetPropertyIndex( name ); + index = iter->first; + } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + index = mBaseType->GetPropertyIndex( name ); } } @@ -506,13 +668,10 @@ Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const { basePropertyIndex = iter->second.basePropertyIndex; } - else + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) - { - basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index ); - } + // call base type recursively + basePropertyIndex = mBaseType->GetBasePropertyIndex( index ); } return basePropertyIndex; @@ -529,79 +688,265 @@ int TypeInfo::GetComponentIndex( Property::Index index ) const { componentIndex = iter->second.componentIndex; } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + componentIndex = mBaseType->GetComponentIndex( index ); + } + + return componentIndex; +} + +Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const +{ + Property::Index index = Property::INVALID_INDEX; + + // Slow but should not be done that often + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), + PropertyNameFinder< RegisteredPropertyPair >( name ) ); + + if ( iter != mRegisteredChildProperties.end() ) + { + index = iter->first; + } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + index = mBaseType->GetChildPropertyIndex( name ); + } + + return index; +} + +const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const +{ + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + + if ( iter != mRegisteredChildProperties.end() ) + { + return iter->second.name; + } + + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + return mBaseType->GetChildPropertyName( index ); + } + + DALI_LOG_ERROR( "Property index %d not found\n", index ); + + static std::string empty; + return empty; +} + +Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const +{ + Property::Type type( Property::NONE ); + + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + + if ( iter != mRegisteredChildProperties.end() ) + { + type = iter->second.type; + } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + type = mBaseType->GetChildPropertyType( index ); + } + else + { + DALI_LOG_ERROR( "Property index %d not found\n", index ); + } + + return type; +} + +bool TypeInfo::IsPropertyWritable( Property::Index index ) const +{ + bool writable = false; + bool found = false; + + // default property? + if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties ) + { + found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::writable, writable ); + } + else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) + { + writable = true; // animatable property is writable + found = true; + } else { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + if ( iter != mRegisteredProperties.end() ) { - componentIndex = GetImplementation(base).GetComponentIndex( index ); + writable = iter->second.setFunc ? true : false; + found = true; } } - return componentIndex; + // if not found, continue to base + if( !found ) + { + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + writable = mBaseType->IsPropertyWritable( index ); + } + else + { + DALI_LOG_ERROR( "Property index %d not found\n", index ); + } + } + + return writable; } -bool TypeInfo::IsPropertyWritable( Property::Index index ) const +bool TypeInfo::IsPropertyAnimatable( Property::Index index ) const { - bool writable( false ); + bool animatable = false; + bool found = false; - RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), - PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + // default property? + if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties ) + { + found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::animatable, animatable ); + } + else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) ) + { + // Type Registry event-thread only properties are not animatable. + animatable = false; + found = true; + } + else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) + { + animatable = true; + found = true; + } - if ( iter != mRegisteredProperties.end() ) + // if not found, continue to base + if( !found ) { - if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - writable = true; // animatable property is writable + // call base type recursively + animatable = mBaseType->IsPropertyAnimatable( index ); } else { - writable = iter->second.setFunc ? true : false; + DALI_LOG_ERROR( "Property index %d not found\n", index ); } } - else + + return animatable; +} + +bool TypeInfo::IsPropertyAConstraintInput( Property::Index index ) const +{ + bool constraintInput = false; + bool found = false; + + // default property? + if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties ) + { + found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::constraintInput, constraintInput ); + } + else if ( ( index >= PROPERTY_REGISTRATION_START_INDEX ) && ( index <= PROPERTY_REGISTRATION_MAX_INDEX ) ) { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + // Type Registry event-thread only properties cannot be used as constraint input + constraintInput = false; + found = true; + } + else if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) ) + { + constraintInput = true; + found = true; + } + + // if not found, continue to base + if( !found ) + { + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - writable = GetImplementation(base).IsPropertyWritable( index ); + // call base type recursively + constraintInput = mBaseType->IsPropertyAConstraintInput( index ); } else { - DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object + DALI_LOG_ERROR( "Property index %d not found\n", index ); } } - return writable; + return constraintInput; } + Property::Type TypeInfo::GetPropertyType( Property::Index index ) const { Property::Type type( Property::NONE ); + bool found = false; - RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), - PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); - - if ( iter != mRegisteredProperties.end() ) + // default property? + if ( ( index < DEFAULT_PROPERTY_MAX_COUNT ) && mDefaultProperties ) { - type = iter->second.type; + found = GetDefaultPropertyField( mDefaultProperties, mDefaultPropertyCount,index, &Dali::PropertyDetails::type, type ); } else { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), + PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); + + if ( iter != mRegisteredProperties.end() ) { - type = GetImplementation(base).GetPropertyType( index ); + if( iter->second.componentIndex == Property::INVALID_COMPONENT_INDEX ) + { + type = iter->second.type; + found = true; + } + else + { + // If component index is set, then we should return FLOAT + type = Property::FLOAT; + found = true; + } + } + } + + if( !found ) + { + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + type = mBaseType->GetPropertyType( index ); } else { - DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object + DALI_LOG_ERROR( "Property index %d not found\n", index ); } } return type; } +Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const +{ + PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(), + PairFinder< Property::Index, PropertyDefaultValuePair >( index ) ); + if( iter != mPropertyDefaultValues.end() ) + { + return iter->second; + } + else + { + return Property::Value( GetPropertyType( index ) ); + } +} + void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const { RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), @@ -610,20 +955,27 @@ void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Pro { if( iter->second.setFunc ) { - iter->second.setFunc( object, index, value ); + if( mCSharpType ) + { + // CSharp wants a property name not an index + const std::string& name = (iter->second).name; + + iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value) ); + } + else + { + iter->second.setFunc( object, index, value ); + } } } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + mBaseType->SetProperty( object, index, value ); + } else { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) - { - GetImplementation(base).SetProperty( object, index, value ); - } - else - { - DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object - } + DALI_LOG_ERROR( "Property index %d not found\n", index ); } } @@ -634,20 +986,26 @@ void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const P if ( iter != mRegisteredProperties.end() ) { DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" ); - iter->second.setFunc( object, iter->first, value ); - } - else - { - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + + if( mCSharpType ) { - GetImplementation(base).SetProperty( object, name, value ); + // CSharp wants a property name not an index + iter->second.cSharpSetFunc( object,name.c_str(), const_cast< Property::Value* >(&value )); } else { - DALI_ASSERT_ALWAYS( ! "Cannot find property name" ); + iter->second.setFunc( object, iter->first, value ); } } + else if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) + { + // call base type recursively + mBaseType->SetProperty( object, name, value ); + } + else + { + DALI_LOG_ERROR( "Property %s not found", name.c_str() ); + } } Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const @@ -656,36 +1014,65 @@ Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index PairFinder< Property::Index, RegisteredPropertyPair >( index ) ); if( iter != mRegisteredProperties.end() ) { - // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object - return iter->second.getFunc( const_cast< BaseObject* >( object ), index ); + if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value + { + // CSharp wants a property name not an index + // CSharp callback can't return an object by value, it can only return a pointer + // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value + const std::string& name = (iter->second).name; + + return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str()) ); + + } + else + { + // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object + return iter->second.getFunc( const_cast< BaseObject* >( object ), index ); + } } - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - return GetImplementation( base ).GetProperty( object, index ); + // call base type recursively + return mBaseType->GetProperty( object, index ); } - DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object + DALI_LOG_ERROR( "Property index %d not found\n", index ); + return Property::Value(); } Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const { RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(), - PropertyNameFinder< RegisteredPropertyPair >( name ) ); + PropertyNameFinder< RegisteredPropertyPair >( name ) ); + + + if( iter != mRegisteredProperties.end() ) { - // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object - return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first ); + if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value + { + // CSharp wants a property name not an index + // CSharp callback can't return an object by value, it can only return a pointer + // CSharp has ownership of the pointer contents, which is fine because we are returning by from this function by value + return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), name.c_str() )); + + } + else + { + // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object + return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first ); + } } - Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName ); - if ( base ) + if( GetBaseType( mBaseType, mTypeRegistry, mBaseTypeName ) ) { - return GetImplementation( base ).GetProperty( object, name ); + // call base type recursively + return mBaseType->GetProperty( object, name ); } - DALI_ASSERT_ALWAYS( ! "Cannot find property name" ); + DALI_LOG_ERROR( "Property %s not found", name.c_str() ); + return Property::Value(); } } // namespace Internal