Merge "Enabling animation of Renderer properties when offstage" 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 )
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
182   return ret;
183
184 }
185
186 void TypeRegistry::CallInitFunctions(void) const
187 {
188   for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
189   {
190     (*iter)();
191   }
192 }
193
194 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
195 {
196   return DemangleClassName( registerType.name() );
197 }
198
199 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
200 {
201   RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
202
203   if( iter != mRegistryLut.end() )
204   {
205     DALI_ASSERT_DEBUG(iter->second);
206
207     GetImplementation(iter->second).AddConnectorFunction( name, func );
208   }
209 }
210
211 bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
212 {
213   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
214
215   if( iter != mRegistryLut.end() )
216   {
217     DALI_ASSERT_DEBUG(iter->second);
218
219     GetImplementation(iter->second).AddActionFunction( name, f );
220
221     return true;
222   }
223   else
224   {
225     return false;
226   }
227 }
228
229 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
230 {
231   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
232
233   if( iter != mRegistryLut.end() )
234   {
235     DALI_ASSERT_DEBUG(iter->second);
236
237     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
238
239     return true;
240   }
241
242   return false;
243 }
244
245 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 )
246 {
247   RegistryMap::iterator iter = mRegistryLut.find( objectName );
248
249   if( iter != mRegistryLut.end() )
250   {
251     DALI_ASSERT_DEBUG(iter->second);
252
253     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
254
255     return true;
256   }
257
258   return false;
259
260 }
261
262
263 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
264 {
265   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
266
267   if( iter != mRegistryLut.end() )
268   {
269     DALI_ASSERT_DEBUG(iter->second);
270
271     GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
272
273     return true;
274   }
275
276   return false;
277 }
278
279 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, const Property::Value& value )
280 {
281   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
282
283   if( iter != mRegistryLut.end() )
284   {
285     DALI_ASSERT_DEBUG(iter->second);
286
287     GetImplementation(iter->second).AddAnimatableProperty( name, index, value );
288
289     return true;
290   }
291
292   return false;
293 }
294
295 bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
296 {
297   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
298
299   if( iter != mRegistryLut.end() )
300   {
301     DALI_ASSERT_DEBUG(iter->second);
302
303     GetImplementation(iter->second).AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
304
305     return true;
306   }
307
308   return false;
309 }
310
311 bool TypeRegistry::RegisterChildProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
312 {
313   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
314
315   if( iter != mRegistryLut.end() )
316   {
317     DALI_ASSERT_DEBUG(iter->second);
318
319     GetImplementation(iter->second).AddChildProperty( name, index, type );
320
321     return true;
322   }
323
324   return false;
325 }
326
327 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const Property::Map &properties)
328 {
329   bool done = false;
330
331   Dali::TypeInfo type = GetTypeInfo( object );
332
333   while( type )
334   {
335     if(GetImplementation(type).DoActionTo(object, actionName, properties))
336     {
337       done = true;
338       break;
339     }
340     type = GetTypeInfo( type.GetBaseName() );
341   }
342
343   return done;
344 }
345
346 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
347 {
348   bool connected( false );
349
350   Dali::TypeInfo type = GetTypeInfo( object );
351
352   while( type )
353   {
354     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
355     if( connected )
356     {
357       break;
358     }
359     type = GetTypeInfo( type.GetBaseName() );
360   }
361
362   if( !connected )
363   {
364     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
365     delete functor;
366   }
367
368   return connected;
369 }
370
371 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
372 {
373   Dali::TypeInfo type;
374
375   // test for custom actor which has another indirection to get to the type hiearchy we're after
376   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
377
378   if(pCustom)
379   {
380     const Dali::CustomActorImpl& custom = pCustom->GetImplementation();
381     type = GetTypeInfo( typeid( custom ) );
382   }
383   else
384   {
385     type = GetTypeInfo( typeid( *pBaseObject ) );
386   }
387
388   return type;
389 }
390
391 } // namespace Internal
392
393 } // namespace Dali