Revert "License conversion from Flora to Apache 2.0"
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-registry-impl.cpp
1 //
2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
3 //
4 // Licensed under the Flora License, Version 1.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://floralicense.org/license/
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 // CLASS HEADER
18 #include <dali/internal/event/common/type-registry-impl.h>
19
20 // EXTERNAL INCLUDES
21 #include <string.h>
22 #include <sstream>
23
24 // INTERNAL INCLUDES
25 #include <dali/internal/event/common/thread-local-storage.h>
26 #include <dali/public-api/object/type-registry.h>
27 #include <dali/public-api/object/base-handle.h>
28 #include <dali/internal/event/actors/custom-actor-internal.h>
29 #include <dali/internal/event/common/demangler.h>
30
31 #include <dali/integration-api/debug.h>
32
33 namespace
34 {
35
36 #if defined(DEBUG_ENABLED)
37 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TYPE_REGISTRY");
38 #endif
39
40 } // namespace anon
41
42 namespace Dali
43 {
44
45 extern std::string Demangle(const char* symbol);
46
47 namespace Internal
48 {
49
50 TypeRegistry *TypeRegistry::Get()
51 {
52   static TypeRegistry *_reg(new TypeRegistry());
53   DALI_ASSERT_DEBUG(_reg);
54   return _reg;
55 }
56
57 TypeRegistry::TypeRegistry()
58 {
59
60 }
61
62 TypeRegistry::~TypeRegistry()
63 {
64   mRegistryLut.clear();
65 }
66
67 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::string &uniqueTypeName )
68 {
69   Dali::TypeInfo ret;
70
71   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
72
73   if( iter != mRegistryLut.end() )
74   {
75     ret = iter->second;
76   }
77   else
78   {
79     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", uniqueTypeName.c_str());
80   }
81
82   return ret;
83 }
84
85 Dali::TypeInfo TypeRegistry::GetTypeInfo( const std::type_info& registerType )
86 {
87   Dali::TypeInfo ret;
88
89   std::string typeName = DemangleClassName(registerType.name());
90
91   RegistryMap::iterator iter = mRegistryLut.find(typeName);
92
93   if( iter != mRegistryLut.end() )
94   {
95     ret = iter->second;
96   }
97   else
98   {
99     DALI_LOG_INFO( gLogFilter, Debug::Verbose, "Cannot find requested type '%s'\n", registerType.name());
100   }
101
102   return ret;
103 }
104
105 Dali::TypeRegistry::NameContainer TypeRegistry::GetTypeNames() const
106 {
107   Dali::TypeRegistry::NameContainer ret;
108
109   for(RegistryMap::const_iterator iter = mRegistryLut.begin(); iter != mRegistryLut.end(); ++iter)
110   {
111     ret.push_back(iter->first);
112   }
113
114   return ret;
115 }
116
117 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
118                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
119 {
120   std::string uniqueTypeName  = DemangleClassName(theTypeInfo.name());
121
122   return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
123 }
124
125 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
126                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
127 {
128   bool ret = false;
129
130   std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
131
132   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
133
134   if( iter == mRegistryLut.end() )
135   {
136     mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
137     ret = true;
138     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
139   }
140   else
141   {
142     DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
143     DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
144   }
145
146   if( callCreateOnInit )
147   {
148     mInitFunctions.push_back(createInstance);
149   }
150
151   return ret;
152 }
153
154 void TypeRegistry::CallInitFunctions(void) const
155 {
156   for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
157   {
158     (*iter)();
159   }
160 }
161
162 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
163 {
164   return DemangleClassName( registerType.name() );
165 }
166
167 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunctionV2 func )
168 {
169   RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
170
171   if( iter != mRegistryLut.end() )
172   {
173     DALI_ASSERT_DEBUG(iter->second);
174
175     GetImplementation(iter->second).AddConnectorFunction( name, func );
176   }
177 }
178
179 bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
180 {
181   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
182
183   if( iter != mRegistryLut.end() )
184   {
185     DALI_ASSERT_DEBUG(iter->second);
186
187     GetImplementation(iter->second).AddActionFunction( name, f );
188
189     return true;
190   }
191   else
192   {
193     return false;
194   }
195 }
196
197 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
198 {
199   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
200
201   if( iter != mRegistryLut.end() )
202   {
203     DALI_ASSERT_DEBUG(iter->second);
204
205     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
206
207     return true;
208   }
209
210   return false;
211 }
212
213 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
214 {
215   bool done = false;
216
217   Dali::TypeInfo type = GetTypeInfo( object );
218
219   while( type )
220   {
221     if(GetImplementation(type).DoActionTo(object, actionName, properties))
222     {
223       done = true;
224       break;
225     }
226     type = GetTypeInfo( type.GetBaseName() );
227   }
228
229   return done;
230 }
231
232 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
233 {
234   bool connected( false );
235
236   Dali::TypeInfo type = GetTypeInfo( object );
237
238   while( type )
239   {
240     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
241     if( connected )
242     {
243       break;
244     }
245     type = GetTypeInfo( type.GetBaseName() );
246   }
247
248   if( !connected )
249   {
250     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
251     delete functor;
252   }
253
254   return connected;
255 }
256
257 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
258 {
259   Dali::TypeInfo type;
260
261   // test for custom actor which has another indirection to get to the type hiearchy we're after
262   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
263
264   if(pCustom)
265   {
266     type = GetTypeInfo( typeid( pCustom->GetImplementation() ) );
267   }
268   else
269   {
270     type = GetTypeInfo( typeid( *pBaseObject ) );
271   }
272
273   return type;
274 }
275
276 } // namespace Internal
277
278 } // namespace Dali