b0809a794004ec725795aae7ebdf9863d09c5358
[platform/core/uifw/dali-core.git] / dali / internal / event / common / type-info-impl.cpp
1 /*
2  * Copyright (c) 2016 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-info-impl.h>
20
21 // EXTERNAL INCLUDES
22 #include <algorithm> // std::find_if
23 #include <string>
24
25 // INTERNAL INCLUDES
26 #include <dali/integration-api/debug.h>
27 #include <dali/internal/event/common/type-registry-impl.h>
28 #include <dali/internal/event/common/object-impl.h>
29
30 using std::find_if;
31
32 namespace
33 {
34
35 /*
36  * Functor to find by given type for vector of pairs
37  */
38 template <typename S, typename T>
39 struct PairFinder
40 {
41   PairFinder(const S& find)
42   : mFind(find)
43   {
44   }
45
46   bool operator()(const T& p) const
47   {
48     return p.first == mFind;
49   }
50
51 private:
52
53   const S& mFind;
54 };
55
56 /**
57  * Functor to find a matching property name
58  */
59 template <typename T>
60 struct PropertyNameFinder
61 {
62   PropertyNameFinder( const std::string& find )
63   : mFind( find )
64   {
65   }
66
67   bool operator()(const T &p) const
68   {
69     return p.second.name == mFind;
70   }
71
72 private:
73
74   const std::string& mFind;
75 };
76
77 /**
78  * Functor to find a matching property component index
79  */
80 template <typename T>
81 struct PropertyComponentFinder
82 {
83   PropertyComponentFinder( Dali::Property::Index basePropertyIndex, const int find )
84   : mBasePropertyIndex( basePropertyIndex ),
85     mFind( find )
86   {
87   }
88
89   bool operator()(const T &p) const
90   {
91     return ( p.second.basePropertyIndex == mBasePropertyIndex && p.second.componentIndex == mFind );
92   }
93
94 private:
95
96   Dali::Property::Index mBasePropertyIndex;
97   const int mFind;
98 };
99
100 } // namespace anon
101
102 namespace Dali
103 {
104
105 namespace Internal
106 {
107
108 TypeInfo::TypeInfo(const std::string &name, const std::string &baseTypeName, Dali::TypeInfo::CreateFunction creator)
109   : mTypeName(name), mBaseTypeName(baseTypeName), mCreate(creator)
110 {
111   DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
112   DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
113 }
114
115 TypeInfo::~TypeInfo()
116 {
117 }
118
119 BaseHandle TypeInfo::CreateInstance() const
120 {
121   BaseHandle ret;
122
123   if(mCreate)
124   {
125     ret = mCreate();
126
127     if ( ret )
128     {
129       BaseObject& handle = ret.GetBaseObject();
130       Object *object = dynamic_cast<Internal::Object*>(&handle);
131
132       if ( object )
133       {
134         object->SetTypeInfo( this );
135       }
136     }
137   }
138   return ret;
139 }
140
141   bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
142 {
143   bool done = false;
144
145   ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
146
147   if( iter != mActions.end() )
148   {
149     done = (iter->second)(object, actionName, properties);
150   }
151   else
152   {
153     DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
154   }
155
156   if(!done)
157   {
158     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
159     while( base )
160     {
161       done = GetImplementation(base).DoActionTo(object, actionName, properties);
162       if( done )
163       {
164         break;
165       }
166       base =  Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
167     }
168   }
169
170   return done;
171 }
172
173 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
174 {
175   bool connected( false );
176
177   ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
178                                                  PairFinder<std::string, ConnectionPair>(signalName) );
179
180   if( iter != mSignalConnectors.end() )
181   {
182     connected = (iter->second)( object, connectionTracker, signalName, functor );
183   }
184
185   return connected;
186 }
187
188 const std::string& TypeInfo::GetName() const
189 {
190   return mTypeName;
191 }
192
193 const std::string& TypeInfo::GetBaseName() const
194 {
195   return mBaseTypeName;
196 }
197
198 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
199 {
200   return mCreate;
201 }
202
203 size_t TypeInfo::GetActionCount() const
204 {
205   size_t count = mActions.size();
206
207   Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
208   while( base )
209   {
210     count += GetImplementation(base).mActions.size();
211     base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
212   }
213
214   return count;
215 }
216
217 std::string TypeInfo::GetActionName(size_t index) const
218 {
219   std::string name;
220
221   if( index < mActions.size() )
222   {
223     name = mActions[index].first;
224   }
225   else
226   {
227     size_t count = mActions.size();
228
229     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
230     while( base )
231     {
232       size_t baseCount = GetImplementation(base).mActions.size();
233
234       if( index < count + baseCount )
235       {
236         name = GetImplementation(base).mActions[ index - count ].first;
237         break;
238       }
239
240       count += baseCount;
241
242       base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
243     }
244   }
245
246   return name;
247 }
248
249 size_t TypeInfo::GetSignalCount() const
250 {
251   size_t count = mSignalConnectors.size();
252
253   Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
254   while( base )
255   {
256     count += GetImplementation(base).mSignalConnectors.size();
257     base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
258   }
259
260   return count;
261 }
262
263 std::string TypeInfo::GetSignalName(size_t index) const
264 {
265   std::string name;
266
267   if( index < mSignalConnectors.size() )
268   {
269     name = mSignalConnectors[index].first;
270   }
271   else
272   {
273     size_t count = mSignalConnectors.size();
274
275     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
276     while( base )
277     {
278       size_t baseCount = GetImplementation(base).mSignalConnectors.size();
279
280       if( index < count + baseCount )
281       {
282         name = GetImplementation(base).mSignalConnectors[ index - count ].first;
283         break;
284       }
285
286       count += baseCount;
287
288       base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
289     }
290   }
291
292   return name;
293 }
294
295 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
296 {
297   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
298   if ( base )
299   {
300     const TypeInfo& baseImpl( GetImplementation( base ) );
301     baseImpl.GetPropertyIndices( indices );
302   }
303
304   if ( ! mRegisteredProperties.empty() )
305   {
306     indices.Reserve( indices.Size() + mRegisteredProperties.size() );
307
308     const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
309     for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
310     {
311       indices.PushBack( iter->first );
312     }
313   }
314 }
315
316 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
317 {
318   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
319                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
320
321   if ( iter != mRegisteredProperties.end() )
322   {
323     return iter->second.name;
324   }
325
326   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
327   if ( base )
328   {
329     return GetImplementation(base).GetPropertyName( index );
330   }
331
332   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
333 }
334
335 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
336 {
337   if( NULL == function)
338   {
339     DALI_LOG_WARNING("Action function is empty\n");
340   }
341   else
342   {
343     ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
344                                                   PairFinder<std::string, ActionPair>(actionName));
345
346     if( iter == mActions.end() )
347     {
348       mActions.push_back( ActionPair( actionName, function ) );
349     }
350     else
351     {
352       DALI_LOG_WARNING("Action already exists in TypeRegistry Type", actionName.c_str());
353     }
354   }
355 }
356
357 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
358 {
359   if( NULL == function)
360   {
361     DALI_LOG_WARNING("Connector function is empty\n");
362   }
363   else
364   {
365     ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
366                                                    PairFinder<std::string, ConnectionPair>(signalName) );
367
368     if( iter == mSignalConnectors.end() )
369     {
370       mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
371     }
372     else
373     {
374       DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function", signalName.c_str());
375     }
376   }
377 }
378
379 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
380 {
381   // The setter can be empty as a property can be read-only.
382
383   if ( NULL == getFunc )
384   {
385     DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
386   }
387   else
388   {
389     RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
390                                                           PairFinder< Property::Index, RegisteredPropertyPair>(index) );
391
392     if ( iter == mRegisteredProperties.end() )
393     {
394       mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
395     }
396     else
397     {
398       DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
399     }
400   }
401 }
402
403 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
404 {
405   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
406                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
407
408   if ( iter == mRegisteredProperties.end() )
409   {
410     mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
411   }
412   else
413   {
414     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
415   }
416 }
417
418 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue )
419 {
420   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
421                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
422
423   if ( iter == mRegisteredProperties.end() )
424   {
425     mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
426     mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) );
427   }
428   else
429   {
430     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
431   }
432 }
433
434 void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
435 {
436   Property::Type type = GetPropertyType( baseIndex );
437   DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
438
439   bool success = false;
440
441   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
442                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
443
444   if ( iter == mRegisteredProperties.end() )
445   {
446     iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
447                     PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
448
449     if ( iter == mRegisteredProperties.end() )
450     {
451       mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, baseIndex, componentIndex ) ) );
452       success = true;
453     }
454   }
455
456   DALI_ASSERT_ALWAYS( success && "Property component already registered" );
457 }
458
459 void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type )
460 {
461   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
462                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
463
464   if ( iter == mRegisteredChildProperties.end() )
465   {
466     mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, NULL, NULL, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
467   }
468   else
469   {
470     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
471   }
472 }
473
474 size_t TypeInfo::GetPropertyCount() const
475 {
476   size_t count( mRegisteredProperties.size() );
477
478   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
479   while ( base )
480   {
481     const TypeInfo& baseImpl( GetImplementation(base) );
482     count += baseImpl.mRegisteredProperties.size();
483     base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
484   }
485
486   return count;
487 }
488
489 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
490 {
491   Property::Index index = Property::INVALID_INDEX;
492
493   // Slow but should not be done that often
494   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
495                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
496
497   if ( iter != mRegisteredProperties.end() )
498   {
499     index = iter->first;
500   }
501   else
502   {
503     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
504     if ( base )
505     {
506       index = GetImplementation(base).GetPropertyIndex( name );
507     }
508   }
509
510   return index;
511 }
512
513 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
514 {
515   Property::Index basePropertyIndex = Property::INVALID_INDEX;
516
517   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
518                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
519
520   if ( iter != mRegisteredProperties.end() )
521   {
522     basePropertyIndex = iter->second.basePropertyIndex;
523   }
524   else
525   {
526     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
527     if ( base )
528     {
529       basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index );
530     }
531   }
532
533   return basePropertyIndex;
534 }
535
536 int TypeInfo::GetComponentIndex( Property::Index index ) const
537 {
538   int componentIndex = Property::INVALID_COMPONENT_INDEX;
539
540   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
541                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
542
543   if ( iter != mRegisteredProperties.end() )
544   {
545     componentIndex = iter->second.componentIndex;
546   }
547   else
548   {
549     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
550     if ( base )
551     {
552       componentIndex = GetImplementation(base).GetComponentIndex( index );
553     }
554   }
555
556   return componentIndex;
557 }
558
559 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
560 {
561   Property::Index index = Property::INVALID_INDEX;
562
563   // Slow but should not be done that often
564   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
565                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
566
567   if ( iter != mRegisteredChildProperties.end() )
568   {
569     index = iter->first;
570   }
571   else
572   {
573     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
574     if ( base )
575     {
576       index = GetImplementation(base).GetChildPropertyIndex( name );
577     }
578   }
579
580   return index;
581 }
582
583 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
584 {
585   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
586                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
587
588   if ( iter != mRegisteredChildProperties.end() )
589   {
590     return iter->second.name;
591   }
592
593   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
594   if ( base )
595   {
596     return GetImplementation(base).GetChildPropertyName( index );
597   }
598
599   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
600 }
601
602 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
603 {
604   Property::Type type( Property::NONE );
605
606   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
607                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
608
609   if ( iter != mRegisteredChildProperties.end() )
610   {
611     type = iter->second.type;
612   }
613   else
614   {
615     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
616     if ( base )
617     {
618       type = GetImplementation(base).GetChildPropertyType( index );
619     }
620     else
621     {
622       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
623     }
624   }
625
626   return type;
627 }
628
629 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
630 {
631   bool writable( false );
632
633   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
634                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
635
636   if ( iter != mRegisteredProperties.end() )
637   {
638     if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
639     {
640       writable = true; // animatable property is writable
641     }
642     else
643     {
644       writable = iter->second.setFunc ? true : false;
645     }
646   }
647   else
648   {
649     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
650     if ( base )
651     {
652       writable = GetImplementation(base).IsPropertyWritable( index );
653     }
654     else
655     {
656       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
657     }
658   }
659
660   return writable;
661 }
662
663 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
664 {
665   Property::Type type( Property::NONE );
666
667   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
668                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
669
670   if ( iter != mRegisteredProperties.end() )
671   {
672     type = iter->second.type;
673   }
674   else
675   {
676     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
677     if ( base )
678     {
679       type = GetImplementation(base).GetPropertyType( index );
680     }
681     else
682     {
683       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
684     }
685   }
686
687   return type;
688 }
689
690 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
691 {
692   PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
693                                                     PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
694   if( iter !=  mPropertyDefaultValues.end() )
695   {
696     return iter->second;
697   }
698   else
699   {
700     return Property::Value( GetPropertyType( index ) );
701   }
702 }
703
704 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
705 {
706   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
707                                                               PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
708   if ( iter != mRegisteredProperties.end() )
709   {
710     if( iter->second.setFunc )
711     {
712       iter->second.setFunc( object, index, value );
713     }
714   }
715   else
716   {
717     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
718     if ( base )
719     {
720       GetImplementation(base).SetProperty( object, index, value );
721     }
722     else
723     {
724       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
725     }
726   }
727 }
728
729 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
730 {
731   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
732                                                               PropertyNameFinder< RegisteredPropertyPair >( name ) );
733   if ( iter != mRegisteredProperties.end() )
734   {
735     DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
736     iter->second.setFunc( object, iter->first, value );
737   }
738   else
739   {
740     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
741     if ( base )
742     {
743       GetImplementation(base).SetProperty( object, name, value );
744     }
745     else
746     {
747       DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
748     }
749   }
750 }
751
752 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
753 {
754   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
755                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
756   if( iter != mRegisteredProperties.end() )
757   {
758     // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
759     return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
760   }
761
762   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
763   if ( base )
764   {
765     return GetImplementation( base ).GetProperty( object, index );
766   }
767
768   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
769 }
770
771 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
772 {
773   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
774                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
775   if( iter != mRegisteredProperties.end() )
776   {
777     // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
778     return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
779   }
780
781   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
782   if ( base )
783   {
784     return GetImplementation( base ).GetProperty( object, name );
785   }
786
787   DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
788 }
789
790 } // namespace Internal
791
792 } // namespace Dali