Merge "Prevent API generate warning log" into devel/master
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-registry-impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include <dali/internal/event/common/type-registry-impl.h>
20
21 // INTERNAL INCLUDES
22 #include <dali/internal/event/common/thread-local-storage.h>
23 #include <dali/public-api/object/type-registry.h>
24 #include <dali/public-api/object/base-handle.h>
25 #include <dali/internal/event/actors/custom-actor-internal.h>
26 #include <dali/internal/event/common/demangler.h>
27
28 #include <dali/integration-api/debug.h>
29
30 namespace
31 {
32
33 #if defined(DEBUG_ENABLED)
34 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TYPE_REGISTRY");
35 #endif
36
37 } // namespace anon
38
39 namespace Dali
40 {
41
42 extern std::string Demangle(const char* symbol);
43
44 namespace Internal
45 {
46
47 TypeRegistry *TypeRegistry::Get()
48 {
49   static TypeRegistry *_reg(new TypeRegistry());
50   DALI_ASSERT_DEBUG(_reg);
51   return _reg;
52 }
53
54 TypeRegistry::TypeRegistry()
55 {
56
57 }
58
59 TypeRegistry::~TypeRegistry()
60 {
61   mRegistryLut.clear();
62 }
63
64 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::string &uniqueTypeName )
65 {
66   Dali::TypeInfo ret;
67
68   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
69
70   if( iter != mRegistryLut.end() )
71   {
72     ret = iter->second;
73   }
74   else
75   {
76     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str());
77   }
78
79   return ret;
80 }
81
82 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType )
83 {
84   Dali::TypeInfo ret;
85
86   std::string typeName = DemangleClassName(registerType.name());
87
88   RegistryMap::iterator iter = mRegistryLut.find(typeName);
89
90   if( iter != mRegistryLut.end() )
91   {
92     ret = iter->second;
93   }
94   else
95   {
96     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", registerType.name());
97   }
98
99   return ret;
100 }
101
102 size_t TypeRegistry::GetTypeNameCount() const
103 {
104   return mRegistryLut.size();
105 }
106
107
108 std::string TypeRegistry::GetTypeName(size_t index) const
109 {
110   std::string name;
111
112   if( index < mRegistryLut.size() )
113   {
114     RegistryMap::const_iterator iter = mRegistryLut.begin();
115     std::advance(iter, index);
116     name = iter->first;
117   }
118
119   return name;
120 }
121
122
123 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
124                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
125 {
126   std::string uniqueTypeName  = DemangleClassName(theTypeInfo.name());
127
128   return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
129 }
130
131 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
132                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
133 {
134   bool ret = false;
135
136   std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
137
138   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
139
140   if( iter == mRegistryLut.end() )
141   {
142     mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
143     ret = true;
144     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
145   }
146   else
147   {
148     DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
149     DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
150   }
151
152   if( callCreateOnInit )
153   {
154     mInitFunctions.push_back(createInstance);
155   }
156
157   return ret;
158 }
159
160 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
161     Dali::CSharpTypeInfo::CreateFunction createInstance, bool callCreateOnInit  )
162 {
163
164   bool ret = false;
165
166   std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
167
168   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
169
170   if( iter == mRegistryLut.end() )
171   {
172     mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
173     ret = true;
174     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
175   }
176   else
177   {
178     DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
179     DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
180   }
181   if( callCreateOnInit )
182   {
183     mCSharpInitFunctions.push_back(createInstance);
184   }
185   return ret;
186
187 }
188
189 void TypeRegistry::CallInitFunctions(void) const
190 {
191   for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
192   {
193     (*iter)();
194   }
195   for( CSharpInitFunctions::const_iterator iter = mCSharpInitFunctions.begin(); iter != mCSharpInitFunctions.end(); ++iter)
196   {
197     (*iter)();
198   }
199 }
200
201 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
202 {
203   return DemangleClassName( registerType.name() );
204 }
205
206 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
207 {
208   RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
209
210   if( iter != mRegistryLut.end() )
211   {
212     DALI_ASSERT_DEBUG(iter->second);
213
214     GetImplementation(iter->second).AddConnectorFunction( name, func );
215   }
216 }
217
218 bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
219 {
220   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
221
222   if( iter != mRegistryLut.end() )
223   {
224     DALI_ASSERT_DEBUG(iter->second);
225
226     GetImplementation(iter->second).AddActionFunction( name, f );
227
228     return true;
229   }
230   else
231   {
232     return false;
233   }
234 }
235
236 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
237 {
238   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
239
240   if( iter != mRegistryLut.end() )
241   {
242     DALI_ASSERT_DEBUG(iter->second);
243
244     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
245
246     return true;
247   }
248
249   return false;
250 }
251
252 bool TypeRegistry::RegisterProperty( const std::string& objectName, const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc )
253 {
254   RegistryMap::iterator iter = mRegistryLut.find( objectName );
255
256   if( iter != mRegistryLut.end() )
257   {
258     DALI_ASSERT_DEBUG(iter->second);
259
260     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
261
262     return true;
263   }
264
265   return false;
266
267 }
268
269
270 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
271 {
272   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
273
274   if( iter != mRegistryLut.end() )
275   {
276     DALI_ASSERT_DEBUG(iter->second);
277
278     GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
279
280     return true;
281   }
282
283   return false;
284 }
285
286 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, const Property::Value& value )
287 {
288   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
289
290   if( iter != mRegistryLut.end() )
291   {
292     DALI_ASSERT_DEBUG(iter->second);
293
294     GetImplementation(iter->second).AddAnimatableProperty( name, index, value );
295
296     return true;
297   }
298
299   return false;
300 }
301
302 bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
303 {
304   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
305
306   if( iter != mRegistryLut.end() )
307   {
308     DALI_ASSERT_DEBUG(iter->second);
309
310     GetImplementation(iter->second).AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
311
312     return true;
313   }
314
315   return false;
316 }
317
318 bool TypeRegistry::RegisterChildProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
319 {
320   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
321
322   if( iter != mRegistryLut.end() )
323   {
324     DALI_ASSERT_DEBUG(iter->second);
325
326     GetImplementation(iter->second).AddChildProperty( name, index, type );
327
328     return true;
329   }
330
331   return false;
332 }
333
334 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const Property::Map &properties)
335 {
336   bool done = false;
337
338   Dali::TypeInfo type = GetTypeInfo( object );
339
340   while( type )
341   {
342     if(GetImplementation(type).DoActionTo(object, actionName, properties))
343     {
344       done = true;
345       break;
346     }
347     type = GetTypeInfo( type.GetBaseName() );
348   }
349
350   return done;
351 }
352
353 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
354 {
355   bool connected( false );
356
357   Dali::TypeInfo type = GetTypeInfo( object );
358
359   while( type )
360   {
361     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
362     if( connected )
363     {
364       break;
365     }
366     type = GetTypeInfo( type.GetBaseName() );
367   }
368
369   if( !connected )
370   {
371     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
372     delete functor;
373   }
374
375   return connected;
376 }
377
378 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
379 {
380   Dali::TypeInfo type;
381
382   // test for custom actor which has another indirection to get to the type hiearchy we're after
383   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
384
385   if(pCustom)
386   {
387     const Dali::CustomActorImpl& custom = pCustom->GetImplementation();
388     type = GetTypeInfo( typeid( custom ) );
389   }
390   else
391   {
392     type = GetTypeInfo( typeid( *pBaseObject ) );
393   }
394
395   return type;
396 }
397
398 } // namespace Internal
399
400 } // namespace Dali