Merge "Prevent API generate warning log" into devel/master
[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), mCSharpType(false), 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(const std::string &name, const std::string &baseTypeName, Dali::CSharpTypeInfo::CreateFunction creator)
116   : mTypeName(name), mBaseTypeName(baseTypeName), mCSharpType(true), mCSharpCreate(creator)
117 {
118   DALI_ASSERT_ALWAYS(!name.empty() && "Type info construction must have a name");
119   DALI_ASSERT_ALWAYS(!baseTypeName.empty() && "Type info construction must have a base type name");
120 }
121
122 TypeInfo::~TypeInfo()
123 {
124 }
125
126 BaseHandle TypeInfo::CreateInstance() const
127 {
128   BaseHandle ret;
129
130   if(mCreate)
131   {
132     if ( mCSharpType )
133     {
134       ret = *mCSharpCreate();
135     }
136     else
137     {
138       ret = mCreate();
139     }
140
141     if ( ret )
142     {
143       BaseObject& handle = ret.GetBaseObject();
144       Object *object = dynamic_cast<Internal::Object*>(&handle);
145
146       if ( object )
147       {
148         object->SetTypeInfo( this );
149       }
150     }
151   }
152   return ret;
153 }
154
155   bool TypeInfo::DoActionTo(BaseObject *object, const std::string &actionName, const Property::Map &properties)
156 {
157   bool done = false;
158
159   ActionContainer::iterator iter = find_if(mActions.begin(), mActions.end(), PairFinder<std::string, ActionPair>(actionName));
160
161   if( iter != mActions.end() )
162   {
163     done = (iter->second)(object, actionName, properties);
164   }
165   else
166   {
167     DALI_LOG_WARNING("Type '%s' cannot do action '%s'\n", mTypeName.c_str(), actionName.c_str());
168   }
169
170   if(!done)
171   {
172     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
173     while( base )
174     {
175       done = GetImplementation(base).DoActionTo(object, actionName, properties);
176       if( done )
177       {
178         break;
179       }
180       base =  Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
181     }
182   }
183
184   return done;
185 }
186
187 bool TypeInfo::ConnectSignal( BaseObject* object, ConnectionTrackerInterface* connectionTracker, const std::string& signalName, FunctorDelegate* functor )
188 {
189   bool connected( false );
190
191   ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
192                                                  PairFinder<std::string, ConnectionPair>(signalName) );
193
194   if( iter != mSignalConnectors.end() )
195   {
196     connected = (iter->second)( object, connectionTracker, signalName, functor );
197   }
198
199   return connected;
200 }
201
202 const std::string& TypeInfo::GetName() const
203 {
204   return mTypeName;
205 }
206
207 const std::string& TypeInfo::GetBaseName() const
208 {
209   return mBaseTypeName;
210 }
211
212 Dali::TypeInfo::CreateFunction TypeInfo::GetCreator() const
213 {
214   return mCreate;
215 }
216
217 size_t TypeInfo::GetActionCount() const
218 {
219   size_t count = mActions.size();
220
221   Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
222   while( base )
223   {
224     count += GetImplementation(base).mActions.size();
225     base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
226   }
227
228   return count;
229 }
230
231 std::string TypeInfo::GetActionName(size_t index) const
232 {
233   std::string name;
234
235   if( index < mActions.size() )
236   {
237     name = mActions[index].first;
238   }
239   else
240   {
241     size_t count = mActions.size();
242
243     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
244     while( base )
245     {
246       size_t baseCount = GetImplementation(base).mActions.size();
247
248       if( index < count + baseCount )
249       {
250         name = GetImplementation(base).mActions[ index - count ].first;
251         break;
252       }
253
254       count += baseCount;
255
256       base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
257     }
258   }
259
260   return name;
261 }
262
263 size_t TypeInfo::GetSignalCount() const
264 {
265   size_t count = mSignalConnectors.size();
266
267   Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
268   while( base )
269   {
270     count += GetImplementation(base).mSignalConnectors.size();
271     base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
272   }
273
274   return count;
275 }
276
277 std::string TypeInfo::GetSignalName(size_t index) const
278 {
279   std::string name;
280
281   if( index < mSignalConnectors.size() )
282   {
283     name = mSignalConnectors[index].first;
284   }
285   else
286   {
287     size_t count = mSignalConnectors.size();
288
289     Dali::TypeInfo base = Dali::TypeRegistry::Get().GetTypeInfo( mBaseTypeName );
290     while( base )
291     {
292       size_t baseCount = GetImplementation(base).mSignalConnectors.size();
293
294       if( index < count + baseCount )
295       {
296         name = GetImplementation(base).mSignalConnectors[ index - count ].first;
297         break;
298       }
299
300       count += baseCount;
301
302       base = Dali::TypeRegistry::Get().GetTypeInfo( base.GetBaseName() );
303     }
304   }
305
306   return name;
307 }
308
309 void TypeInfo::GetPropertyIndices( Property::IndexContainer& indices ) const
310 {
311   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
312   if ( base )
313   {
314     const TypeInfo& baseImpl( GetImplementation( base ) );
315     baseImpl.GetPropertyIndices( indices );
316   }
317
318   if ( ! mRegisteredProperties.empty() )
319   {
320     indices.Reserve( indices.Size() + mRegisteredProperties.size() );
321
322     const RegisteredPropertyContainer::const_iterator endIter = mRegisteredProperties.end();
323     for ( RegisteredPropertyContainer::const_iterator iter = mRegisteredProperties.begin(); iter != endIter; ++iter )
324     {
325       indices.PushBack( iter->first );
326     }
327   }
328 }
329
330 const std::string& TypeInfo::GetPropertyName( Property::Index index ) const
331 {
332   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
333                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
334
335   if ( iter != mRegisteredProperties.end() )
336   {
337     return iter->second.name;
338   }
339
340   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
341   if ( base )
342   {
343     return GetImplementation(base).GetPropertyName( index );
344   }
345
346   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
347 }
348
349 void TypeInfo::AddActionFunction( const std::string &actionName, Dali::TypeInfo::ActionFunction function )
350 {
351   if( NULL == function)
352   {
353     DALI_LOG_WARNING("Action function is empty\n");
354   }
355   else
356   {
357     ActionContainer::iterator iter = std::find_if(mActions.begin(), mActions.end(),
358                                                   PairFinder<std::string, ActionPair>(actionName));
359
360     if( iter == mActions.end() )
361     {
362       mActions.push_back( ActionPair( actionName, function ) );
363     }
364     else
365     {
366       DALI_LOG_WARNING("Action already exists in TypeRegistry Type\n", actionName.c_str());
367     }
368   }
369 }
370
371 void TypeInfo::AddConnectorFunction( const std::string& signalName, Dali::TypeInfo::SignalConnectorFunction function )
372 {
373   if( NULL == function)
374   {
375     DALI_LOG_WARNING("Connector function is empty\n");
376   }
377   else
378   {
379     ConnectorContainer::iterator iter = find_if( mSignalConnectors.begin(), mSignalConnectors.end(),
380                                                    PairFinder<std::string, ConnectionPair>(signalName) );
381
382     if( iter == mSignalConnectors.end() )
383     {
384       mSignalConnectors.push_back( ConnectionPair( signalName, function ) );
385     }
386     else
387     {
388       DALI_LOG_WARNING("Signal name already exists in TypeRegistry Type for signal connector function\n", signalName.c_str());
389     }
390   }
391 }
392
393 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::TypeInfo::SetPropertyFunction setFunc, Dali::TypeInfo::GetPropertyFunction getFunc )
394 {
395   // The setter can be empty as a property can be read-only.
396
397   if ( NULL == getFunc )
398   {
399     DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
400   }
401   else
402   {
403     RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
404                                                           PairFinder< Property::Index, RegisteredPropertyPair>(index) );
405
406     if ( iter == mRegisteredProperties.end() )
407     {
408       mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
409     }
410     else
411     {
412       DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
413     }
414   }
415 }
416
417 void TypeInfo::AddProperty( const std::string& name, Property::Index index, Property::Type type, Dali::CSharpTypeInfo::SetPropertyFunction setFunc, Dali::CSharpTypeInfo::GetPropertyFunction getFunc)
418 {
419
420   // The setter can be empty as a property can be read-only.
421
422   if ( NULL == getFunc )
423   {
424     DALI_ASSERT_ALWAYS( ! "GetProperty Function is empty" );
425   }
426   else
427   {
428     RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
429                                                           PairFinder< Property::Index, RegisteredPropertyPair>(index) );
430
431     if ( iter == mRegisteredProperties.end() )
432     {
433       mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, setFunc, getFunc, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
434     }
435     else
436     {
437       DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
438     }
439   }
440
441 }
442
443
444 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, Property::Type type )
445 {
446   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
447                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
448
449   if ( iter == mRegisteredProperties.end() )
450   {
451     mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
452   }
453   else
454   {
455     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
456   }
457 }
458
459 void TypeInfo::AddAnimatableProperty( const std::string& name, Property::Index index, const Property::Value& defaultValue )
460 {
461   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
462                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
463
464   if ( iter == mRegisteredProperties.end() )
465   {
466     mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( defaultValue.GetType(), name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
467     mPropertyDefaultValues.push_back( PropertyDefaultValuePair( index, defaultValue ) );
468   }
469   else
470   {
471     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
472   }
473 }
474
475 void TypeInfo::AddAnimatablePropertyComponent( const std::string& name, Property::Index index, Property::Index baseIndex, unsigned int componentIndex )
476 {
477   Property::Type type = GetPropertyType( baseIndex );
478   DALI_ASSERT_ALWAYS( ( type == Property::VECTOR2 || type == Property::VECTOR3 || type == Property::VECTOR4 ) && "Base property does not support component" );
479
480   bool success = false;
481
482   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
483                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
484
485   if ( iter == mRegisteredProperties.end() )
486   {
487     iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
488                     PropertyComponentFinder< RegisteredPropertyPair >( baseIndex, componentIndex ) );
489
490     if ( iter == mRegisteredProperties.end() )
491     {
492       mRegisteredProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, baseIndex, componentIndex ) ) );
493       success = true;
494     }
495   }
496
497   DALI_ASSERT_ALWAYS( success && "Property component already registered" );
498 }
499
500 void TypeInfo::AddChildProperty( const std::string& name, Property::Index index, Property::Type type )
501 {
502   RegisteredPropertyContainer::iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
503                                                         PairFinder< Property::Index, RegisteredPropertyPair>(index) );
504
505   if ( iter == mRegisteredChildProperties.end() )
506   {
507     mRegisteredChildProperties.push_back( RegisteredPropertyPair( index, RegisteredProperty( type, name, Property::INVALID_INDEX, Property::INVALID_COMPONENT_INDEX ) ) );
508   }
509   else
510   {
511     DALI_ASSERT_ALWAYS( ! "Property index already added to Type" );
512   }
513 }
514
515 size_t TypeInfo::GetPropertyCount() const
516 {
517   size_t count( mRegisteredProperties.size() );
518
519   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
520   while ( base )
521   {
522     const TypeInfo& baseImpl( GetImplementation(base) );
523     count += baseImpl.mRegisteredProperties.size();
524     base = TypeRegistry::Get()->GetTypeInfo( baseImpl.mBaseTypeName );
525   }
526
527   return count;
528 }
529
530 Property::Index TypeInfo::GetPropertyIndex( const std::string& name ) const
531 {
532   Property::Index index = Property::INVALID_INDEX;
533
534   // Slow but should not be done that often
535   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
536                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
537
538   if ( iter != mRegisteredProperties.end() )
539   {
540     index = iter->first;
541   }
542   else
543   {
544     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
545     if ( base )
546     {
547       index = GetImplementation(base).GetPropertyIndex( name );
548     }
549   }
550
551   return index;
552 }
553
554 Property::Index TypeInfo::GetBasePropertyIndex( Property::Index index ) const
555 {
556   Property::Index basePropertyIndex = Property::INVALID_INDEX;
557
558   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
559                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
560
561   if ( iter != mRegisteredProperties.end() )
562   {
563     basePropertyIndex = iter->second.basePropertyIndex;
564   }
565   else
566   {
567     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
568     if ( base )
569     {
570       basePropertyIndex = GetImplementation(base).GetBasePropertyIndex( index );
571     }
572   }
573
574   return basePropertyIndex;
575 }
576
577 int TypeInfo::GetComponentIndex( Property::Index index ) const
578 {
579   int componentIndex = Property::INVALID_COMPONENT_INDEX;
580
581   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
582                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
583
584   if ( iter != mRegisteredProperties.end() )
585   {
586     componentIndex = iter->second.componentIndex;
587   }
588   else
589   {
590     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
591     if ( base )
592     {
593       componentIndex = GetImplementation(base).GetComponentIndex( index );
594     }
595   }
596
597   return componentIndex;
598 }
599
600 Property::Index TypeInfo::GetChildPropertyIndex( const std::string& name ) const
601 {
602   Property::Index index = Property::INVALID_INDEX;
603
604   // Slow but should not be done that often
605   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
606                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
607
608   if ( iter != mRegisteredChildProperties.end() )
609   {
610     index = iter->first;
611   }
612   else
613   {
614     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
615     if ( base )
616     {
617       index = GetImplementation(base).GetChildPropertyIndex( name );
618     }
619   }
620
621   return index;
622 }
623
624 const std::string& TypeInfo::GetChildPropertyName( Property::Index index ) const
625 {
626   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
627                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
628
629   if ( iter != mRegisteredChildProperties.end() )
630   {
631     return iter->second.name;
632   }
633
634   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
635   if ( base )
636   {
637     return GetImplementation(base).GetChildPropertyName( index );
638   }
639
640   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
641 }
642
643 Property::Type TypeInfo::GetChildPropertyType( Property::Index index ) const
644 {
645   Property::Type type( Property::NONE );
646
647   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredChildProperties.begin(), mRegisteredChildProperties.end(),
648                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
649
650   if ( iter != mRegisteredChildProperties.end() )
651   {
652     type = iter->second.type;
653   }
654   else
655   {
656     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
657     if ( base )
658     {
659       type = GetImplementation(base).GetChildPropertyType( index );
660     }
661     else
662     {
663       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
664     }
665   }
666
667   return type;
668 }
669
670 bool TypeInfo::IsPropertyWritable( Property::Index index ) const
671 {
672   bool writable( false );
673
674   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
675                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
676
677   if ( iter != mRegisteredProperties.end() )
678   {
679     if( ( index >= ANIMATABLE_PROPERTY_REGISTRATION_START_INDEX ) && ( index <= ANIMATABLE_PROPERTY_REGISTRATION_MAX_INDEX ) )
680     {
681       writable = true; // animatable property is writable
682     }
683     else
684     {
685       writable = iter->second.setFunc ? true : false;
686     }
687   }
688   else
689   {
690     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
691     if ( base )
692     {
693       writable = GetImplementation(base).IsPropertyWritable( index );
694     }
695     else
696     {
697       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
698     }
699   }
700
701   return writable;
702 }
703
704 Property::Type TypeInfo::GetPropertyType( Property::Index index ) const
705 {
706   Property::Type type( Property::NONE );
707
708   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
709                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
710
711   if ( iter != mRegisteredProperties.end() )
712   {
713     type = iter->second.type;
714   }
715   else
716   {
717     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
718     if ( base )
719     {
720       type = GetImplementation(base).GetPropertyType( index );
721     }
722     else
723     {
724       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
725     }
726   }
727
728   return type;
729 }
730
731 Property::Value TypeInfo::GetPropertyDefaultValue( Property::Index index ) const
732 {
733   PropertyDefaultValueContainer::const_iterator iter = find_if( mPropertyDefaultValues.begin(), mPropertyDefaultValues.end(),
734                                                     PairFinder< Property::Index, PropertyDefaultValuePair >( index ) );
735   if( iter !=  mPropertyDefaultValues.end() )
736   {
737     return iter->second;
738   }
739   else
740   {
741     return Property::Value( GetPropertyType( index ) );
742   }
743 }
744
745 void TypeInfo::SetProperty( BaseObject *object, Property::Index index, const Property::Value& value ) const
746 {
747   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
748                                                               PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
749   if ( iter != mRegisteredProperties.end() )
750   {
751     if( iter->second.setFunc )
752     {
753       iter->second.setFunc( object, index, value );
754     }
755   }
756   else
757   {
758     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
759     if ( base )
760     {
761       GetImplementation(base).SetProperty( object, index, value );
762     }
763     else
764     {
765       DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
766     }
767   }
768 }
769
770 void TypeInfo::SetProperty( BaseObject *object, const std::string& name, const Property::Value& value ) const
771 {
772   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
773                                                               PropertyNameFinder< RegisteredPropertyPair >( name ) );
774   if ( iter != mRegisteredProperties.end() )
775   {
776     DALI_ASSERT_ALWAYS( iter->second.setFunc && "Trying to write to a read-only property" );
777     iter->second.setFunc( object, iter->first, value );
778   }
779   else
780   {
781     Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
782     if ( base )
783     {
784       GetImplementation(base).SetProperty( object, name, value );
785     }
786     else
787     {
788       DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
789     }
790   }
791 }
792
793 Property::Value TypeInfo::GetProperty( const BaseObject *object, Property::Index index ) const
794 {
795   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
796                                                           PairFinder< Property::Index, RegisteredPropertyPair >( index ) );
797   if( iter != mRegisteredProperties.end() )
798   {
799     if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
800     {
801        // CSharp can't return any object by value, it can return pointers.
802        // CSharp has ownership of the pointer contents, which is fine because we are returning by value
803        int index = (iter->first );
804        return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), &index  ));
805
806     }
807     else
808     {
809       // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
810       return iter->second.getFunc( const_cast< BaseObject* >( object ), index );
811     }
812   }
813
814   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
815   if ( base )
816   {
817     return GetImplementation( base ).GetProperty( object, index );
818   }
819
820   DALI_ASSERT_ALWAYS( ! "Cannot find property index" ); // use the same assert as Object
821 }
822
823 Property::Value TypeInfo::GetProperty( const BaseObject *object, const std::string& name ) const
824 {
825   RegisteredPropertyContainer::const_iterator iter = find_if( mRegisteredProperties.begin(), mRegisteredProperties.end(),
826                                                           PropertyNameFinder< RegisteredPropertyPair >( name ) );
827   if( iter != mRegisteredProperties.end() )
828   {
829     if( mCSharpType ) // using csharp property get which returns a pointer to a Property::Value
830     {
831       // CSharp can't return any object by value, it can return pointers.
832       // CSharp has ownership of the pointer contents, which is fine because we are returning by value
833       int index = (iter->first );
834       return *( iter->second.cSharpGetFunc( const_cast< BaseObject* >( object ), &index ));
835
836     }
837     else
838     {
839       // Need to remove the constness here as CustomActor will not be able to call Downcast with a const pointer to the object
840       return iter->second.getFunc( const_cast< BaseObject* >( object ), iter->first );
841     }
842   }
843
844   Dali::TypeInfo base = TypeRegistry::Get()->GetTypeInfo( mBaseTypeName );
845   if ( base )
846   {
847     return GetImplementation( base ).GetProperty( object, name );
848   }
849
850   DALI_ASSERT_ALWAYS( ! "Cannot find property name" );
851 }
852
853 } // namespace Internal
854
855 } // namespace Dali