Allow registering property components for animatable properties
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-registry-impl.cpp
1 /*
2  * Copyright (c) 2015 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::RegisterAnimatablePropertyComponent( TypeRegistration& registered, const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
227 {
228   RegistryMap::iterator iter = mRegistryLut.find( registered.RegisteredName() );
229
230   if( iter != mRegistryLut.end() )
231   {
232     DALI_ASSERT_DEBUG(iter->second);
233
234     GetImplementation(iter->second).AddAnimatablePropertyComponent( name, index, baseIndex, componentIndex );
235
236     return true;
237   }
238
239   return false;
240 }
241
242 bool TypeRegistry::DoActionTo( BaseObject * const object, const std::string &actionName, const std::vector<Property::Value> &properties)
243 {
244   bool done = false;
245
246   Dali::TypeInfo type = GetTypeInfo( object );
247
248   while( type )
249   {
250     if(GetImplementation(type).DoActionTo(object, actionName, properties))
251     {
252       done = true;
253       break;
254     }
255     type = GetTypeInfo( type.GetBaseName() );
256   }
257
258   return done;
259 }
260
261 bool TypeRegistry::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
262 {
263   bool connected( false );
264
265   Dali::TypeInfo type = GetTypeInfo( object );
266
267   while( type )
268   {
269     connected = GetImplementation(type).ConnectSignal( object, connectionTracker, signalName, functor );
270     if( connected )
271     {
272       break;
273     }
274     type = GetTypeInfo( type.GetBaseName() );
275   }
276
277   if( !connected )
278   {
279     // Ownership of functor was not passed to Dali::CallbackBase, so clean-up now
280     delete functor;
281   }
282
283   return connected;
284 }
285
286 Dali::TypeInfo TypeRegistry::GetTypeInfo(const Dali::BaseObject * const pBaseObject)
287 {
288   Dali::TypeInfo type;
289
290   // test for custom actor which has another indirection to get to the type hiearchy we're after
291   const Dali::Internal::CustomActor * const pCustom = dynamic_cast<const Dali::Internal::CustomActor*>(pBaseObject);
292
293   if(pCustom)
294   {
295     type = GetTypeInfo( typeid( pCustom->GetImplementation() ) );
296   }
297   else
298   {
299     type = GetTypeInfo( typeid( *pBaseObject ) );
300   }
301
302   return type;
303 }
304
305 } // namespace Internal
306
307 } // namespace Dali