X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Fevent%2Fcommon%2Ftype-registry-impl.cpp;h=9c79314ff6ebfcfb948d1b9cbc321564b9b61183;hb=f15d1ed84355ced4b6c5115b8aebb68d897cd374;hp=cd1e9c972da57d71036a5b422c108e416e85ae62;hpb=24a826711c9b42968089e6ad54faead44a5df376;p=platform%2Fcore%2Fuifw%2Fdali-core.git diff --git a/dali/internal/event/common/type-registry-impl.cpp b/dali/internal/event/common/type-registry-impl.cpp index cd1e9c9..9c79314 100644 --- a/dali/internal/event/common/type-registry-impl.cpp +++ b/dali/internal/event/common/type-registry-impl.cpp @@ -1,33 +1,29 @@ -// -// Copyright (c) 2014 Samsung Electronics Co., Ltd. -// -// Licensed under the Flora License, Version 1.0 (the License); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://floralicense.org/license/ -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an AS IS BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// +/* + * Copyright (c) 2020 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ // CLASS HEADER #include -// EXTERNAL INCLUDES -#include -#include -#include -#include - // INTERNAL INCLUDES -#include #include #include #include +#include +#include #include @@ -38,58 +34,11 @@ namespace Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TYPE_REGISTRY"); #endif -std::vector SplitString(const std::string &s, char delim, std::vector &elems) -{ - std::stringstream ss(s); - std::string item; - while(std::getline(ss, item, delim)) - { - elems.push_back(item); - } - return elems; -} - -const int Demangle(const char* symbol, std::vector &resolved) -{ - int status = -4; - - char* res = abi::__cxa_demangle(symbol, NULL, NULL, &status); - - const char* const demangled_name = (status==0)?res:symbol; - - std::string sDemangled(demangled_name); - - free(res); - - SplitString(sDemangled, ':', resolved); - - return resolved.size(); -} - -const std::string DemangleShortName(const char *symbol) -{ - std::vector resolved; - - Demangle(symbol, resolved); - - if(resolved.size() > 0) - { - return resolved[ resolved.size() - 1 ]; - } - else - { - return std::string(symbol); - } - -} - } // namespace anon namespace Dali { -extern std::string Demangle(const char* symbol); - namespace Internal { @@ -110,96 +59,122 @@ TypeRegistry::~TypeRegistry() mRegistryLut.clear(); } -Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::string &uniqueTypeName ) +TypeRegistry::TypeInfoPointer TypeRegistry::GetTypeInfo( const std::string& uniqueTypeName ) { - Dali::TypeInfo ret; - - RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName); - - if( iter != mRegistryLut.end() ) + for( auto&& iter : mRegistryLut ) { - ret = iter->second; - } - else - { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str()); + // Note! mRegistryLut contains Dali::TypeInfo handles, so cannot call GetTypeName() + // as it calls us back resulting in infinite loop (GetTypeName is in BaseHandle part) + if( iter->GetName() == uniqueTypeName ) + { + return iter; + } } + DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str() ); - return ret; + return TypeRegistry::TypeInfoPointer(); } -Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType ) +TypeRegistry::TypeInfoPointer TypeRegistry::GetTypeInfo( const std::type_info& registerType ) { - Dali::TypeInfo ret; - - std::string typeName = DemangleShortName(registerType.name()); + std::string typeName = DemangleClassName( registerType.name() ); - RegistryMap::iterator iter = mRegistryLut.find(typeName); - - if( iter != mRegistryLut.end() ) - { - ret = iter->second; - } - else - { - DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", registerType.name()); - } + return GetTypeInfo( typeName ); +} - return ret; +uint32_t TypeRegistry::GetTypeNameCount() const +{ + return static_cast( mRegistryLut.size() ); } -Dali::TypeRegistry::NameContainer TypeRegistry::GetTypeNames() const +const std::string& TypeRegistry::GetTypeName(uint32_t index) const { - Dali::TypeRegistry::NameContainer ret; + static std::string EMPTY_STRING{}; - for(RegistryMap::const_iterator iter = mRegistryLut.begin(); iter != mRegistryLut.end(); ++iter) + if( index < mRegistryLut.size() ) { - ret.push_back(iter->first); + return mRegistryLut[index]->GetName(); } - return ret; + return EMPTY_STRING; } -bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo, - Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit ) +std::string TypeRegistry::Register( const std::type_info& theTypeInfo, + const std::type_info& baseTypeInfo, + Dali::TypeInfo::CreateFunction createInstance, + bool callCreateOnInit ) { - std::string uniqueTypeName = DemangleShortName(theTypeInfo.name()); + std::string uniqueTypeName = DemangleClassName( theTypeInfo.name() ); return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit ); } -bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo, - Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit ) +std::string TypeRegistry::Register( const std::type_info& theTypeInfo, + const std::type_info& baseTypeInfo, + Dali::TypeInfo::CreateFunction createInstance, + bool callCreateOnInit, + const Dali::PropertyDetails* defaultProperties, + Property::Index defaultPropertyCount ) { - bool ret = false; + std::string uniqueTypeName = DemangleClassName( theTypeInfo.name() ); - std::string baseTypeName = DemangleShortName(baseTypeInfo.name()); + return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit, defaultProperties, defaultPropertyCount ); +} - RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName); +std::string TypeRegistry::Register(std::string uniqueTypeName, + const std::type_info& baseTypeInfo, + Dali::TypeInfo::CreateFunction createInstance, + bool callCreateOnInit, + const Dali::PropertyDetails* defaultProperties, + Property::Index defaultPropertyCount) +{ + std::string baseTypeName = DemangleClassName( baseTypeInfo.name() ); - if( iter == mRegistryLut.end() ) + // check for duplicates using uniqueTypeName + for( auto&& iter : mRegistryLut ) { - mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance)); - ret = true; - DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str()); - } - else - { - DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str()); - DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation"); + if( iter->GetName() == uniqueTypeName ) + { + DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() ); + DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" ); + return uniqueTypeName; // never actually happening due to the assert + } } + mRegistryLut.push_back( TypeRegistry::TypeInfoPointer( + new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance, defaultProperties, defaultPropertyCount ) ) ); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() ); + if( callCreateOnInit ) { mInitFunctions.push_back(createInstance); } - return ret; + return uniqueTypeName; +} + +void TypeRegistry::Register(std::string uniqueTypeName, const std::type_info& baseTypeInfo, Dali::CSharpTypeInfo::CreateFunction createInstance) +{ + std::string baseTypeName = DemangleClassName( baseTypeInfo.name() ); + + // check for duplicates using uniqueTypeName + for( auto&& iter : mRegistryLut ) + { + if( iter->GetName() == uniqueTypeName ) + { + DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() ); + DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" ); + return; // never actually happening due to the assert + } + } + + mRegistryLut.push_back( TypeRegistry::TypeInfoPointer( new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance ) ) ); + DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() ); } void TypeRegistry::CallInitFunctions(void) const { - for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter) + for( auto&& iter : mInitFunctions ) { (*iter)(); } @@ -207,69 +182,135 @@ void TypeRegistry::CallInitFunctions(void) const std::string TypeRegistry::RegistrationName( const std::type_info& registerType ) { - return DemangleShortName( registerType.name() ); + return DemangleClassName( registerType.name() ); } -void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunctionV2 func ) +void TypeRegistry::RegisterSignal(TypeRegistration& typeRegistration, std::string name, Dali::TypeInfo::SignalConnectorFunction func) { - RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() ); - - if( iter != mRegistryLut.end() ) + for( auto&& iter : mRegistryLut ) { - DALI_ASSERT_DEBUG(iter->second); - - GetImplementation(iter->second).AddConnectorFunction( name, func ); + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddConnectorFunction(std::move(name), func); + break; + } } } -bool TypeRegistry::RegisterAction( TypeRegistration ®istered, const std::string &name, Dali::TypeInfo::ActionFunction f) +bool TypeRegistry::RegisterAction(TypeRegistration& typeRegistration, std::string name, Dali::TypeInfo::ActionFunction f) { - RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() ); + for( auto&& iter : mRegistryLut ) + { + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddActionFunction(std::move(name), f); + return true; + } + } + return false; +} - if( iter != mRegistryLut.end() ) +bool TypeRegistry::RegisterProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc) +{ + for( auto&& iter : mRegistryLut ) { - DALI_ASSERT_DEBUG(iter->second); + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddProperty(std::move(name), index, type, setFunc, getFunc); + return true; + } + } - GetImplementation(iter->second).AddActionFunction( name, f ); + return false; +} - return true; +bool TypeRegistry::RegisterProperty(const std::string& objectName, std::string name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc) +{ + for( auto&& iter : mRegistryLut ) + { + if( iter->GetName() == objectName ) + { + iter->AddProperty(std::move(name), index, type, setFunc, getFunc); + return true; + } } - else + + return false; +} + +bool TypeRegistry::RegisterAnimatableProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Type type) +{ + for( auto&& iter : mRegistryLut ) { - return false; + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddAnimatableProperty(std::move(name), index, type); + return true; + } } + + return false; } -bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc ) +bool TypeRegistry::RegisterAnimatableProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Value value) { - RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() ); + for( auto&& iter : mRegistryLut ) + { + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddAnimatableProperty(std::move(name), index, std::move(value)); + return true; + } + } - if( iter != mRegistryLut.end() ) + return false; +} + +bool TypeRegistry::RegisterAnimatablePropertyComponent(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex) +{ + for( auto&& iter : mRegistryLut ) { - DALI_ASSERT_DEBUG(iter->second); + if( iter->GetName() == typeRegistration.RegisteredName() ) + { + iter->AddAnimatablePropertyComponent(std::move(name), index, baseIndex, componentIndex); + return true; + } + } - GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc ); + return false; +} - return true; +bool TypeRegistry::RegisterChildProperty(const std::string& registeredType, std::string name, Property::Index index, Property::Type type) +{ + for( auto&& iter : mRegistryLut ) + { + if( iter->GetName() == registeredType ) + { + iter->AddChildProperty(std::move(name), index, type); + return true; + } } return false; } -bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector &properties) +bool TypeRegistry::RegisterChildProperty(TypeRegistration& typeRegistration, std::string name, Property::Index index, Property::Type type) +{ + return RegisterChildProperty(typeRegistration.RegisteredName(), std::move(name), index, type); +} + +bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string& actionName, const Property::Map& properties ) { bool done = false; - Dali::TypeInfo type = GetTypeInfo( object ); + auto&& type = GetTypeInfo( object ); - while( type ) + // DoActionTo recurses through base classes + done = type->DoActionTo( object, actionName, properties ); + + if( !done ) { - if(GetImplementation(type).DoActionTo(object, actionName, properties)) - { - done = true; - break; - } - type = GetTypeInfo( type.GetBaseName() ); + DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", type->GetName().c_str(), actionName.c_str()); } return done; @@ -279,20 +320,14 @@ bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface { bool connected( false ); - Dali::TypeInfo type = GetTypeInfo( object ); + auto&& type = GetTypeInfo( object ); - while( type ) - { - connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor ); - if( connected ) - { - break; - } - type = GetTypeInfo( type.GetBaseName() ); - } + // Connect iterates through base classes + connected = type->ConnectSignal( object, connectionTracker, signalName, functor ); if( !connected ) { + DALI_LOG_WARNING("Type '%s' signal '%s' connection failed \n", type->GetName().c_str(), signalName.c_str()); // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now delete functor; } @@ -300,16 +335,23 @@ bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface return connected; } -Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject) +TypeRegistry::TypeInfoPointer TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject) { - Dali::TypeInfo type; + TypeInfoPointer type; // test for custom actor which has another indirection to get to the type hiearchy we're after const Dali::Internal::CustomActor * const pCustom = dynamic_cast(pBaseObject); - if(pCustom) + if( pCustom ) { - type = GetTypeInfo( typeid( pCustom->GetImplementation() ) ); + const Dali::CustomActorImpl& custom = pCustom->GetImplementation(); + type = GetTypeInfo( typeid( custom ) ); + if( !type ) + { + // the most derived type is a descendant of custom actor but has not registered itself + // so we'll just treat it as a custom actor for now so it "inherits" all of actors properties, actions and signals + type = GetTypeInfo( typeid( Dali::Internal::CustomActor ) ); + } } else {