Remove use of map-wrapper from TypeRegistry
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-registry-impl.cpp
1 /*
2  * Copyright (c) 2017 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   for( auto&& iter : mRegistryLut )
67   {
68     // Note! mRegistryLut contains Dali::TypeInfo handles, so cannot call GetTypeName()
69     // as it calls us back resulting in infinite loop (GetTypeName is in BaseHandle part)
70     if( GetImplementation( iter ).GetName() == uniqueTypeName )
71     {
72       return iter;
73     }
74   }
75   DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str() );
76
77   return Dali::TypeInfo();
78 }
79
80 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType )
81 {
82   std::string typeName = DemangleClassName( registerType.name() );
83
84   return GetTypeInfo( typeName );
85 }
86
87 size_t TypeRegistry::GetTypeNameCount() const
88 {
89   return mRegistryLut.size();
90 }
91
92
93 std::string TypeRegistry::GetTypeName( size_t index ) const
94 {
95   std::string name;
96
97   if( index < mRegistryLut.size() )
98   {
99     name = GetImplementation( mRegistryLut[ index ] ).GetName();
100   }
101
102   return name;
103 }
104
105
106 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
107                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
108 {
109   std::string uniqueTypeName  = DemangleClassName( theTypeInfo.name() );
110
111   return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
112 }
113
114 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
115                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
116 {
117   std::string baseTypeName = DemangleClassName( baseTypeInfo.name() );
118
119   // check for duplicates using uniqueTypeName
120   for( auto&& iter : mRegistryLut )
121   {
122     if( GetImplementation( iter ).GetName() == uniqueTypeName )
123     {
124       DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() );
125       DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" );
126       return false;
127     }
128   }
129
130   mRegistryLut.push_back( Dali::TypeInfo( new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance ) ) );
131   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() );
132
133   if( callCreateOnInit )
134   {
135     mInitFunctions.push_back(createInstance);
136   }
137
138   return true;
139 }
140
141 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
142     Dali::CSharpTypeInfo::CreateFunction createInstance )
143 {
144   std::string baseTypeName = DemangleClassName( baseTypeInfo.name() );
145
146   // check for duplicates using uniqueTypeName
147   for( auto&& iter : mRegistryLut )
148   {
149     if( GetImplementation( iter ).GetName() == uniqueTypeName )
150     {
151       DALI_LOG_WARNING( "Duplicate name in TypeRegistry for '%s'\n", + uniqueTypeName.c_str() );
152       DALI_ASSERT_ALWAYS( !"Duplicate type name in Type Registration" );
153       return false;
154     }
155   }
156
157   mRegistryLut.push_back( Dali::TypeInfo( new Internal::TypeInfo( uniqueTypeName, baseTypeName, createInstance ) ) );
158   DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str() );
159
160   return true;
161 }
162
163 void TypeRegistry::CallInitFunctions(void) const
164 {
165   for( auto&& iter : mInitFunctions )
166   {
167     (*iter)();
168   }
169 }
170
171 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
172 {
173   return DemangleClassName( registerType.name() );
174 }
175
176 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
177 {
178   for( auto&& iter : mRegistryLut )
179   {
180     auto&& impl = GetImplementation( iter );
181     if( impl.GetName() == typeRegistration.RegisteredName() )
182     {
183       impl.AddConnectorFunction( name, func );
184       break;
185     }
186   }
187 }
188
189 bool TypeRegistry::RegisterAction( TypeRegistration& typeRegistration, const std::string &name, Dali::TypeInfo::ActionFunction f )
190 {
191   for( auto&& iter : mRegistryLut )
192   {
193     auto&& impl = GetImplementation( iter );
194     if( impl.GetName() == typeRegistration.RegisteredName() )
195     {
196       impl.AddActionFunction( name, f );
197       return true;
198     }
199   }
200   return false;
201 }
202
203 bool TypeRegistry::RegisterProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
204 {
205   for( auto&& iter : mRegistryLut )
206   {
207     auto&& impl = GetImplementation( iter );
208     if( impl.GetName() == typeRegistration.RegisteredName() )
209     {
210       impl.AddProperty( name, index, type, setFunc, getFunc );
211       return true;
212     }
213   }
214
215   return false;
216 }
217
218 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 )
219 {
220   for( auto&& iter : mRegistryLut )
221   {
222     auto&& impl = GetImplementation( iter );
223     if( impl.GetName() == objectName )
224     {
225       impl.AddProperty( name, index, type, setFunc, getFunc );
226       return true;
227     }
228   }
229
230   return false;
231 }
232
233
234 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type )
235 {
236   for( auto&& iter : mRegistryLut )
237   {
238     auto&& impl = GetImplementation( iter );
239     if( impl.GetName() == typeRegistration.RegisteredName() )
240     {
241       impl.AddAnimatableProperty( name, index, type );
242       return true;
243     }
244   }
245
246   return false;
247 }
248
249 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, const Property::Value& value )
250 {
251   for( auto&& iter : mRegistryLut )
252   {
253     auto&& impl = GetImplementation( iter );
254     if( impl.GetName() == typeRegistration.RegisteredName() )
255     {
256       impl.AddAnimatableProperty( name, index, value );
257       return true;
258     }
259   }
260
261   return false;
262 }
263
264 bool TypeRegistry::RegisterAnimatablePropertyComponent( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
265 {
266   for( auto&& iter : mRegistryLut )
267   {
268     auto&& impl = GetImplementation( iter );
269     if( impl.GetName() == typeRegistration.RegisteredName() )
270     {
271       impl.AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
272       return true;
273     }
274   }
275
276   return false;
277 }
278
279 bool TypeRegistry::RegisterChildProperty( TypeRegistration& typeRegistration, const std::string& name, Property::Index index, Property::Type type )
280 {
281   for( auto&& iter : mRegistryLut )
282   {
283     auto&& impl = GetImplementation( iter );
284     if( impl.GetName() == typeRegistration.RegisteredName() )
285     {
286       impl.AddChildProperty( name, index, type );
287       return true;
288     }
289   }
290
291   return false;
292 }
293
294 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string& actionName, const Property::Map& properties )
295 {
296   bool done = false;
297
298   Dali::TypeInfo type = GetTypeInfo( object );
299
300   while( type )
301   {
302     auto&& impl = GetImplementation( type );
303     if( impl.DoActionTo( object, actionName, properties ) )
304     {
305       done = true;
306       break;
307     }
308     type = GetTypeInfo( impl.GetBaseName() );
309   }
310
311   return done;
312 }
313
314 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
315 {
316   bool connected( false );
317
318   Dali::TypeInfo type = GetTypeInfo( object );
319
320   while( type )
321   {
322     auto&& impl = GetImplementation( type );
323     connected = impl.ConnectSignal( object, connectionTracker, signalName, functor );
324     if( connected )
325     {
326       break;
327     }
328     type = GetTypeInfo( impl.GetBaseName() );
329   }
330
331   if( !connected )
332   {
333     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
334     delete functor;
335   }
336
337   return connected;
338 }
339
340 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
341 {
342   Dali::TypeInfo type;
343
344   // test for custom actor which has another indirection to get to the type hiearchy we're after
345   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
346
347   if(pCustom)
348   {
349     const Dali::CustomActorImpl& custom = pCustom->GetImplementation();
350     type = GetTypeInfo( typeid( custom ) );
351   }
352   else
353   {
354     type = GetTypeInfo( typeid( *pBaseObject ) );
355   }
356
357   return type;
358 }
359
360 } // namespace Internal
361
362 } // namespace Dali