2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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.
18 #include <dali/internal/event/common/type-registry-impl.h>
27 #include <dali/internal/event/common/thread-local-storage.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/base-handle.h>
30 #include <dali/internal/event/actors/custom-actor-internal.h>
32 #include <dali/integration-api/debug.h>
37 #if defined(DEBUG_ENABLED)
38 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TYPE_REGISTRY");
41 std::vector<std::string> SplitString(const std::string &s, char delim, std::vector<std::string> &elems)
43 std::stringstream ss(s);
45 while(std::getline(ss, item, delim))
47 elems.push_back(item);
52 const int Demangle(const char* symbol, std::vector<std::string> &resolved)
56 char* res = abi::__cxa_demangle(symbol, NULL, NULL, &status);
58 const char* const demangled_name = (status==0)?res:symbol;
60 std::string sDemangled(demangled_name);
64 SplitString(sDemangled, ':', resolved);
66 return resolved.size();
69 const std::string DemangleShortName(const char *symbol)
71 std::vector<std::string> resolved;
73 Demangle(symbol, resolved);
75 if(resolved.size() > 0)
77 return resolved[ resolved.size() - 1 ];
81 return std::string(symbol);
91 extern std::string Demangle(const char* symbol);
96 TypeRegistry *TypeRegistry::Get()
98 static TypeRegistry *_reg(new TypeRegistry());
99 DALI_ASSERT_DEBUG(_reg);
103 TypeRegistry::TypeRegistry()
108 TypeRegistry::~TypeRegistry()
110 mRegistryLut.clear();
113 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::string &uniqueTypeName )
117 RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
119 if( iter != mRegistryLut.end() )
125 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str());
131 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType )
135 std::string typeName = DemangleShortName(registerType.name());
137 RegistryMap::iterator iter = mRegistryLut.find(typeName);
139 if( iter != mRegistryLut.end() )
145 DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", registerType.name());
151 Dali::TypeRegistry::NameContainer TypeRegistry::GetTypeNames() const
153 Dali::TypeRegistry::NameContainer ret;
155 for(RegistryMap::const_iterator iter = mRegistryLut.begin(); iter != mRegistryLut.end(); ++iter)
157 ret.push_back(iter->first);
163 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
164 Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
166 std::string uniqueTypeName = DemangleShortName(theTypeInfo.name());
168 return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
171 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
172 Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
176 std::string baseTypeName = DemangleShortName(baseTypeInfo.name());
178 RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
180 if( iter == mRegistryLut.end() )
182 mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
184 DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
188 DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
189 DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
192 if( callCreateOnInit )
194 mInitFunctions.push_back(createInstance);
200 void TypeRegistry::CallInitFunctions(void) const
202 for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
208 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
210 return DemangleShortName( registerType.name() );
213 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunctionV2 func )
215 RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
217 if( iter != mRegistryLut.end() )
219 DALI_ASSERT_DEBUG(iter->second);
221 GetImplementation(iter->second).AddConnectorFunction( name, func );
225 bool TypeRegistry::RegisterAction( TypeRegistration ®istered, const std::string &name, Dali::TypeInfo::ActionFunction f)
227 RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
229 if( iter != mRegistryLut.end() )
231 DALI_ASSERT_DEBUG(iter->second);
233 GetImplementation(iter->second).AddActionFunction( name, f );
243 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
245 RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
247 if( iter != mRegistryLut.end() )
249 DALI_ASSERT_DEBUG(iter->second);
251 GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
259 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
263 Dali::TypeInfo type = GetTypeInfo( object );
267 if(GetImplementation(type).DoActionTo(object, actionName, properties))
272 type = GetTypeInfo( type.GetBaseName() );
278 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
280 bool connected( false );
282 Dali::TypeInfo type = GetTypeInfo( object );
286 connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
291 type = GetTypeInfo( type.GetBaseName() );
296 // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
303 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
307 // test for custom actor which has another indirection to get to the type hiearchy we're after
308 const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
312 type = GetTypeInfo( typeid( pCustom->GetImplementation() ) );
316 type = GetTypeInfo( typeid( *pBaseObject ) );
322 } // namespace Internal