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