[dali_1.1.18] Merge branch 'devel/master'
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-registry-impl.cpp
1 /*
2  * Copyright (c) 2015 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 void TypeRegistry::CallInitFunctions(void) const
161 {
162   for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
163   {
164     (*iter)();
165   }
166 }
167
168 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
169 {
170   return DemangleClassName( registerType.name() );
171 }
172
173 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
174 {
175   RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
176
177   if( iter != mRegistryLut.end() )
178   {
179     DALI_ASSERT_DEBUG(iter->second);
180
181     GetImplementation(iter->second).AddConnectorFunction( name, func );
182   }
183 }
184
185 bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
186 {
187   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
188
189   if( iter != mRegistryLut.end() )
190   {
191     DALI_ASSERT_DEBUG(iter->second);
192
193     GetImplementation(iter->second).AddActionFunction( name, f );
194
195     return true;
196   }
197   else
198   {
199     return false;
200   }
201 }
202
203 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
204 {
205   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
206
207   if( iter != mRegistryLut.end() )
208   {
209     DALI_ASSERT_DEBUG(iter->second);
210
211     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
212
213     return true;
214   }
215
216   return false;
217 }
218
219 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
220 {
221   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
222
223   if( iter != mRegistryLut.end() )
224   {
225     DALI_ASSERT_DEBUG(iter->second);
226
227     GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
228
229     return true;
230   }
231
232   return false;
233 }
234
235 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, const Property::Value& value )
236 {
237   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
238
239   if( iter != mRegistryLut.end() )
240   {
241     DALI_ASSERT_DEBUG(iter->second);
242
243     GetImplementation(iter->second).AddAnimatableProperty( name, index, value );
244
245     return true;
246   }
247
248   return false;
249 }
250
251 bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
252 {
253   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
254
255   if( iter != mRegistryLut.end() )
256   {
257     DALI_ASSERT_DEBUG(iter->second);
258
259     GetImplementation(iter->second).AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
260
261     return true;
262   }
263
264   return false;
265 }
266
267 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const Property::Map &properties)
268 {
269   bool done = false;
270
271   Dali::TypeInfo type = GetTypeInfo( object );
272
273   while( type )
274   {
275     if(GetImplementation(type).DoActionTo(object, actionName, properties))
276     {
277       done = true;
278       break;
279     }
280     type = GetTypeInfo( type.GetBaseName() );
281   }
282
283   return done;
284 }
285
286 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
287 {
288   bool connected( false );
289
290   Dali::TypeInfo type = GetTypeInfo( object );
291
292   while( type )
293   {
294     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
295     if( connected )
296     {
297       break;
298     }
299     type = GetTypeInfo( type.GetBaseName() );
300   }
301
302   if( !connected )
303   {
304     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
305     delete functor;
306   }
307
308   return connected;
309 }
310
311 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
312 {
313   Dali::TypeInfo type;
314
315   // test for custom actor which has another indirection to get to the type hiearchy we're after
316   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
317
318   if(pCustom)
319   {
320     const Dali::CustomActorImpl& custom = pCustom->GetImplementation();
321     type = GetTypeInfo( typeid( custom ) );
322   }
323   else
324   {
325     type = GetTypeInfo( typeid( *pBaseObject ) );
326   }
327
328   return type;
329 }
330
331 } // namespace Internal
332
333 } // namespace Dali