Merge "Size negotiation patch 3: Scope size negotiation enums" into tizen
[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 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 Dali::TypeRegistry::NameContainer TypeRegistry::GetTypeNames() const
103 {
104   Dali::TypeRegistry::NameContainer ret;
105
106   for(RegistryMap::const_iterator iter = mRegistryLut.begin(); iter != mRegistryLut.end(); ++iter)
107   {
108     ret.push_back(iter->first);
109   }
110
111   return ret;
112 }
113
114 bool TypeRegistry::Register( const std::type_info& theTypeInfo, const std::type_info& baseTypeInfo,
115                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
116 {
117   std::string uniqueTypeName  = DemangleClassName(theTypeInfo.name());
118
119   return Register( uniqueTypeName, baseTypeInfo, createInstance, callCreateOnInit );
120 }
121
122 bool TypeRegistry::Register( const std::string& uniqueTypeName, const std::type_info& baseTypeInfo,
123                              Dali::TypeInfo::CreateFunction createInstance, bool callCreateOnInit )
124 {
125   bool ret = false;
126
127   std::string baseTypeName    = DemangleClassName(baseTypeInfo.name());
128
129   RegistryMap::iterator iter = mRegistryLut.find(uniqueTypeName);
130
131   if( iter == mRegistryLut.end() )
132   {
133     mRegistryLut[uniqueTypeName] = Dali::TypeInfo(new Internal::TypeInfo(uniqueTypeName, baseTypeName, createInstance));
134     ret = true;
135     DALI_LOG_INFO( gLogFilter, Debug::Concise, "Type Registration %s(%s)\n", uniqueTypeName.c_str(), baseTypeName.c_str());
136   }
137   else
138   {
139     DALI_LOG_WARNING("Duplicate name for TypeRegistry for '%s'\n", + uniqueTypeName.c_str());
140     DALI_ASSERT_ALWAYS(!"Duplicate type name for Type Registation");
141   }
142
143   if( callCreateOnInit )
144   {
145     mInitFunctions.push_back(createInstance);
146   }
147
148   return ret;
149 }
150
151 void TypeRegistry::CallInitFunctions(void) const
152 {
153   for( InitFunctions::const_iterator iter = mInitFunctions.begin(); iter != mInitFunctions.end(); ++iter)
154   {
155     (*iter)();
156   }
157 }
158
159 std::string TypeRegistry::RegistrationName( const std::type_info& registerType )
160 {
161   return DemangleClassName( registerType.name() );
162 }
163
164 void TypeRegistry::RegisterSignal( TypeRegistration& typeRegistration, const std::string& name, Dali::TypeInfo::SignalConnectorFunction func )
165 {
166   RegistryMap::iterator iter = mRegistryLut.find( typeRegistration.RegisteredName() );
167
168   if( iter != mRegistryLut.end() )
169   {
170     DALI_ASSERT_DEBUG(iter->second);
171
172     GetImplementation(iter->second).AddConnectorFunction( name, func );
173   }
174 }
175
176 bool TypeRegistry::RegisterAction( TypeRegistration &registered, const std::string &name, Dali::TypeInfo::ActionFunction f)
177 {
178   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
179
180   if( iter != mRegistryLut.end() )
181   {
182     DALI_ASSERT_DEBUG(iter->second);
183
184     GetImplementation(iter->second).AddActionFunction( name, f );
185
186     return true;
187   }
188   else
189   {
190     return false;
191   }
192 }
193
194 bool TypeRegistry::RegisterProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
195 {
196   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
197
198   if( iter != mRegistryLut.end() )
199   {
200     DALI_ASSERT_DEBUG(iter->second);
201
202     GetImplementation(iter->second).AddProperty( name, index, type, setFunc, getFunc );
203
204     return true;
205   }
206
207   return false;
208 }
209
210 bool TypeRegistry::RegisterAnimatableProperty( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Type type )
211 {
212   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
213
214   if( iter != mRegistryLut.end() )
215   {
216     DALI_ASSERT_DEBUG(iter->second);
217
218     GetImplementation(iter->second).AddAnimatableProperty( name, index, type );
219
220     return true;
221   }
222
223   return false;
224 }
225
226 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
227 {
228   bool done = false;
229
230   Dali::TypeInfo type = GetTypeInfo( object );
231
232   while( type )
233   {
234     if(GetImplementation(type).DoActionTo(object, actionName, properties))
235     {
236       done = true;
237       break;
238     }
239     type = GetTypeInfo( type.GetBaseName() );
240   }
241
242   return done;
243 }
244
245 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
246 {
247   bool connected( false );
248
249   Dali::TypeInfo type = GetTypeInfo( object );
250
251   while( type )
252   {
253     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
254     if( connected )
255     {
256       break;
257     }
258     type = GetTypeInfo( type.GetBaseName() );
259   }
260
261   if( !connected )
262   {
263     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
264     delete functor;
265   }
266
267   return connected;
268 }
269
270 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
271 {
272   Dali::TypeInfo type;
273
274   // test for custom actor which has another indirection to get to the type hiearchy we're after
275   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
276
277   if(pCustom)
278   {
279     type = GetTypeInfo( typeid( pCustom->GetImplementation() ) );
280   }
281   else
282   {
283     type = GetTypeInfo( typeid( *pBaseObject ) );
284   }
285
286   return type;
287 }
288
289 } // namespace Internal
290
291 } // namespace Dali