Boost::any replacement in Dali Core functions
[platform/core/uifw/dali-core.git] / dali / public-api / object / property-value.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/public-api/object/property-value.h>
19
20 // INTERNAL INCLUDES
21 #include <dali/public-api/object/any.h>
22 #include <dali/public-api/math/angle-axis.h>
23 #include <dali/public-api/math/radian.h>
24 #include <dali/public-api/math/vector2.h>
25 #include <dali/public-api/math/vector3.h>
26 #include <dali/public-api/math/vector4.h>
27 #include <dali/public-api/math/matrix3.h>
28 #include <dali/public-api/math/matrix.h>
29 #include <dali/public-api/math/rect.h>
30 #include <dali/public-api/math/quaternion.h>
31 #include <dali/public-api/object/property-types.h>
32 #include <dali/integration-api/debug.h>
33
34 namespace Dali
35 {
36
37 struct Property::Value::Impl
38 {
39   Impl()
40   : mType( Property::NONE )
41   {
42   }
43
44   Impl(bool boolValue)
45   : mType( PropertyTypes::Get<bool>() ),
46     mValue( boolValue )
47   {
48   }
49
50   Impl(float floatValue)
51   : mType( PropertyTypes::Get<float>() ),
52     mValue( floatValue )
53   {
54   }
55
56   Impl(int integerValue)
57   : mType( PropertyTypes::Get<int>() ),
58     mValue( integerValue )
59   {
60   }
61
62   Impl(unsigned int unsignedIntegerValue)
63   : mType( PropertyTypes::Get<unsigned int>() ),
64     mValue( unsignedIntegerValue )
65   {
66   }
67
68   Impl(const Vector2& vectorValue)
69   : mType( PropertyTypes::Get<Vector2>() ),
70     mValue( vectorValue )
71   {
72   }
73
74   Impl(const Vector3& vectorValue)
75   : mType( PropertyTypes::Get<Vector3>() ),
76     mValue( vectorValue )
77   {
78   }
79
80   Impl(const Vector4& vectorValue)
81   : mType( PropertyTypes::Get<Vector4>() ),
82     mValue( vectorValue )
83   {
84   }
85
86   Impl(const Matrix3& matrixValue)
87   : mType(PropertyTypes::Get<Matrix3>()),
88     mValue(matrixValue)
89   {
90   }
91
92   Impl(const Matrix& matrixValue)
93   : mType(PropertyTypes::Get<Matrix>()),
94     mValue(matrixValue)
95   {
96   }
97
98   Impl(const AngleAxis& angleAxisValue)
99   : mType( PropertyTypes::Get<AngleAxis>() ),
100     mValue( angleAxisValue )
101   {
102   }
103
104   Impl(const Quaternion& quaternionValue)
105   : mType( PropertyTypes::Get<Quaternion>() ),
106     mValue( quaternionValue )
107   {
108   }
109
110   Impl(const std::string& stringValue)
111     : mType( PropertyTypes::Get<std::string>() ),
112       mValue( stringValue )
113   {
114   }
115
116   Impl(const Rect<int>& rect)
117     : mType( PropertyTypes::Get<Rect<int> >() ),
118       mValue( rect )
119   {
120   }
121
122   Impl(Property::Map container)
123     : mType( PropertyTypes::Get<Property::Map >() ),
124       mValue( container )
125   {
126   }
127
128   Impl(Property::Array container)
129     : mType( PropertyTypes::Get<Property::Array >() ),
130       mValue( container )
131   {
132   }
133
134   Type mType;
135
136   typedef Any AnyValue;
137   AnyValue mValue;
138 };
139
140 Property::Value::Value()
141 : mImpl( NULL )
142 {
143   mImpl = new Impl();
144 }
145
146 Property::Value::Value(bool boolValue)
147 : mImpl( NULL )
148 {
149   mImpl = new Impl( boolValue );
150 }
151
152 Property::Value::Value(float floatValue)
153 : mImpl( NULL )
154 {
155   mImpl = new Impl( floatValue );
156 }
157
158 Property::Value::Value(int integerValue)
159 : mImpl( NULL )
160 {
161   mImpl = new Impl( integerValue );
162 }
163
164 Property::Value::Value(unsigned int unsignedIntegerValue)
165 : mImpl( NULL )
166 {
167   mImpl = new Impl( unsignedIntegerValue );
168 }
169
170 Property::Value::Value(const Vector2& vectorValue)
171 : mImpl( NULL )
172 {
173   mImpl = new Impl( vectorValue );
174 }
175
176 Property::Value::Value(const Vector3& vectorValue)
177 : mImpl( NULL )
178 {
179   mImpl = new Impl( vectorValue );
180 }
181
182 Property::Value::Value(const Vector4& vectorValue)
183 : mImpl( NULL )
184 {
185   mImpl = new Impl( vectorValue );
186 }
187
188 Property::Value::Value(const Matrix3& matrixValue)
189 : mImpl( NULL )
190 {
191   mImpl = new Impl( matrixValue );
192 }
193
194 Property::Value::Value(const Matrix& matrixValue)
195 : mImpl( NULL )
196 {
197   mImpl = new Impl( matrixValue );
198 }
199
200 Property::Value::Value(const Rect<int>& rect)
201 : mImpl( NULL )
202 {
203   mImpl = new Impl( rect );
204 }
205
206 Property::Value::Value(const AngleAxis& angleAxisValue)
207 : mImpl( NULL )
208 {
209   mImpl = new Impl( angleAxisValue );
210 }
211
212 Property::Value::Value(const Quaternion& quaternionValue)
213 {
214   mImpl = new Impl( quaternionValue );
215 }
216
217 Property::Value::Value(const std::string& stringValue)
218 {
219   mImpl = new Impl( stringValue );
220 }
221
222 Property::Value::Value(const char *stringValue)
223 {
224   mImpl = new Impl( std::string(stringValue) );
225 }
226
227 Property::Value::Value(Property::Array &arrayValue)
228 {
229   mImpl = new Impl( arrayValue );
230 }
231
232 Property::Value::Value(Property::Map &mapValue)
233 {
234   mImpl = new Impl( mapValue );
235 }
236
237
238 Property::Value::~Value()
239 {
240   delete mImpl;
241 }
242
243 Property::Value::Value(const Value& value)
244 {
245   switch (value.GetType())
246   {
247     case Property::BOOLEAN:
248     {
249       mImpl = new Impl( value.Get<bool>() );
250       break;
251     }
252
253     case Property::FLOAT:
254     {
255       mImpl = new Impl( value.Get<float>() );
256       break;
257     }
258
259     case Property::INTEGER:
260     {
261       mImpl = new Impl( value.Get<int>() );
262       break;
263     }
264
265     case Property::UNSIGNED_INTEGER:
266     {
267       mImpl = new Impl( value.Get<unsigned int>() );
268       break;
269     }
270
271     case Property::VECTOR2:
272     {
273       mImpl = new Impl( value.Get<Vector2>() );
274       break;
275     }
276
277     case Property::VECTOR3:
278     {
279       mImpl = new Impl( value.Get<Vector3>() );
280       break;
281     }
282
283     case Property::VECTOR4:
284     {
285       mImpl = new Impl( value.Get<Vector4>() );
286       break;
287     }
288
289     case Property::RECTANGLE:
290     {
291       mImpl = new Impl( value.Get<Rect<int> >() );
292       break;
293     }
294
295     case Property::ROTATION:
296     {
297       mImpl = new Impl( value.Get<Quaternion>() );
298       break;
299     }
300
301     case Property::MATRIX3:
302     {
303       mImpl = new Impl( value.Get<Matrix3>());
304       break;
305     }
306
307     case Property::MATRIX:
308     {
309       mImpl = new Impl( value.Get<Matrix>());
310       break;
311     }
312
313     case Property::STRING:
314     {
315       mImpl = new Impl( value.Get<std::string>() );
316       break;
317     }
318
319     case Property::MAP:
320     {
321       mImpl = new Impl( value.Get<Property::Map>() );
322       break;
323     }
324
325     case Property::ARRAY:
326     {
327       mImpl = new Impl( value.Get<Property::Array>() );
328       break;
329     }
330
331     case Property::NONE: // fall
332     default:
333     {
334       mImpl = new Impl();
335       break;
336     }
337   }
338 }
339
340 Property::Value::Value(Type type)
341 {
342   switch (type)
343   {
344     case Property::BOOLEAN:
345     {
346       mImpl = new Impl( false );
347       break;
348     }
349
350     case Property::FLOAT:
351     {
352       mImpl = new Impl( 0.f );
353       break;
354     }
355
356     case Property::INTEGER:
357     {
358       mImpl = new Impl( 0 );
359       break;
360     }
361
362     case Property::UNSIGNED_INTEGER:
363     {
364       mImpl = new Impl( 0U );
365       break;
366     }
367
368     case Property::VECTOR2:
369     {
370       mImpl = new Impl( Vector2::ZERO );
371       break;
372     }
373
374     case Property::VECTOR3:
375     {
376       mImpl = new Impl( Vector3::ZERO );
377       break;
378     }
379
380     case Property::VECTOR4:
381     {
382       mImpl = new Impl( Vector4::ZERO );
383       break;
384     }
385
386     case Property::RECTANGLE:
387     {
388       mImpl = new Impl( Rect<int>(0,0,0,0) );
389       break;
390     }
391
392     case Property::ROTATION:
393     {
394       mImpl = new Impl( Quaternion(0.f, Vector4::YAXIS) );
395       break;
396     }
397
398     case Property::STRING:
399     {
400       mImpl = new Impl( std::string() );
401       break;
402     }
403
404     case Property::MAP:
405     {
406       mImpl = new Impl( Property::Map() );
407       break;
408     }
409
410     case Property::MATRIX:
411     {
412       mImpl = new Impl( Matrix() );
413       break;
414     }
415
416     case Property::MATRIX3:
417     {
418       mImpl = new Impl( Matrix3() );
419       break;
420     }
421
422     case Property::ARRAY:
423     {
424       mImpl = new Impl( Property::Array() );
425       break;
426     }
427
428     case Property::NONE: // fall
429     default:
430     {
431       mImpl = new Impl();
432       break;
433     }
434   }
435 }
436
437 Property::Value& Property::Value::operator=(const Property::Value& value)
438 {
439   if (this == &value)
440   {
441     // skip self assignment
442     return *this;
443   }
444
445   mImpl->mType = value.GetType();
446
447   switch (mImpl->mType)
448   {
449     case Property::BOOLEAN:
450     {
451       mImpl->mValue = value.Get<bool>();
452       break;
453     }
454
455     case Property::FLOAT:
456     {
457       mImpl->mValue = value.Get<float>();
458       break;
459     }
460
461     case Property::INTEGER:
462     {
463       mImpl->mValue = value.Get<int>();
464       break;
465     }
466
467     case Property::UNSIGNED_INTEGER:
468     {
469       mImpl->mValue = value.Get<unsigned int>();
470       break;
471     }
472
473     case Property::VECTOR2:
474     {
475       mImpl->mValue = value.Get<Vector2>();
476       break;
477     }
478
479     case Property::VECTOR3:
480     {
481       mImpl->mValue = value.Get<Vector3>();
482       break;
483     }
484
485     case Property::VECTOR4:
486     {
487       mImpl->mValue = value.Get<Vector4>();
488       break;
489     }
490
491     case Property::RECTANGLE:
492     {
493       mImpl->mValue = value.Get<Rect<int> >();
494       break;
495     }
496
497     case Property::ROTATION:
498     {
499       mImpl->mValue = value.Get<Quaternion>();
500       break;
501     }
502
503     case Property::STRING:
504     {
505       mImpl->mValue = value.Get<std::string>();
506       break;
507     }
508
509     case Property::MATRIX:
510     {
511       mImpl->mValue = value.Get<Matrix>();
512       break;
513     }
514
515     case Property::MATRIX3:
516     {
517       mImpl->mValue = value.Get<Matrix3>();
518       break;
519     }
520
521     case Property::MAP:
522     {
523       mImpl->mValue = value.Get<Property::Map>();
524       break;
525     }
526
527     case Property::ARRAY:
528     {
529       mImpl->mValue = value.Get<Property::Array>();
530       break;
531     }
532
533     case Property::NONE: // fall
534     default:
535     {
536       mImpl->mValue = Impl::AnyValue(0);
537       break;
538     }
539   }
540
541   return *this;
542 }
543
544 Property::Type Property::Value::GetType() const
545 {
546   return mImpl->mType;
547 }
548
549 void Property::Value::Get(bool& boolValue) const
550 {
551   DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" );  // AnyCast does asserted type checking
552
553   boolValue = AnyCast<bool>(mImpl->mValue);
554 }
555
556 void Property::Value::Get(float& floatValue) const
557 {
558   DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
559
560   floatValue = AnyCast<float>(mImpl->mValue);
561 }
562
563 void Property::Value::Get(int& integerValue) const
564 {
565   DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
566
567   integerValue = AnyCast<int>(mImpl->mValue);
568 }
569
570 void Property::Value::Get(unsigned int& unsignedIntegerValue) const
571 {
572   DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
573
574   unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
575 }
576
577 void Property::Value::Get(Vector2& vectorValue) const
578 {
579   DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
580
581   vectorValue = AnyCast<Vector2>(mImpl->mValue);
582 }
583
584 void Property::Value::Get(Vector3& vectorValue) const
585 {
586   DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
587
588   vectorValue = AnyCast<Vector3>(mImpl->mValue);
589 }
590
591 void Property::Value::Get(Vector4& vectorValue) const
592 {
593   DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
594
595   vectorValue = AnyCast<Vector4>(mImpl->mValue);
596 }
597
598 void Property::Value::Get(Matrix3& matrixValue) const
599 {
600   DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
601   matrixValue = AnyCast<Matrix3>(mImpl->mValue);
602 }
603
604 void Property::Value::Get(Matrix& matrixValue) const
605 {
606   DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
607   matrixValue = AnyCast<Matrix>(mImpl->mValue);
608 }
609
610 void Property::Value::Get(Rect<int>& rect) const
611 {
612   DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
613
614   rect = AnyCast<Rect<int> >(mImpl->mValue);
615 }
616
617 void Property::Value::Get(AngleAxis& angleAxisValue) const
618 {
619   DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
620
621   // Rotations have two representations
622   DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
623                      typeid(AngleAxis)  == mImpl->mValue.GetType() );
624
625   if ( typeid(Quaternion) == mImpl->mValue.GetType() )
626   {
627     Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
628
629     Radian angleRadians(0.0f);
630     quaternion.ToAxisAngle( angleAxisValue.axis, angleRadians );
631     angleAxisValue.angle = angleRadians;
632   }
633   else
634   {
635     angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
636   }
637 }
638
639 void Property::Value::Get(Quaternion& quaternionValue) const
640 {
641   DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
642
643   // Rotations have two representations
644   DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
645                typeid(AngleAxis)  == mImpl->mValue.GetType() );
646
647   if ( typeid(Quaternion) == mImpl->mValue.GetType() )
648   {
649     quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
650   }
651   else
652   {
653     AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
654
655     quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
656   }
657 }
658
659 void Property::Value::Get(std::string &out) const
660 {
661   DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
662
663   out = AnyCast<std::string>(mImpl->mValue);
664 }
665
666 void Property::Value::Get(Property::Array &out) const
667 {
668   DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
669
670   out = AnyCast<Property::Array>(mImpl->mValue);
671 }
672
673 void Property::Value::Get(Property::Map &out) const
674 {
675   DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
676
677   out = AnyCast<Property::Map>(mImpl->mValue);
678 }
679
680 Property::Value& Property::Value::GetValue(const std::string& key) const
681 {
682   DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
683
684   Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
685
686   DALI_ASSERT_DEBUG(container);
687
688   if(container)
689   {
690     for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
691     {
692       if(iter->first == key)
693       {
694         return iter->second;
695       }
696     }
697   }
698
699   DALI_LOG_WARNING("Cannot find property map key %s", key.c_str());
700   DALI_ASSERT_ALWAYS(!"Cannot find property map key");
701
702   // should never return this
703   static Property::Value null;
704   return null;
705 }
706
707 bool Property::Value::HasKey(const std::string& key) const
708 {
709   bool has = false;
710
711   if( Property::MAP == GetType() )
712   {
713     Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
714
715     DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
716
717     if(container)
718     {
719       for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
720       {
721         if(iter->first == key)
722         {
723           has = true;
724         }
725       }
726     }
727   }
728
729   return has;
730 }
731
732
733 const std::string& Property::Value::GetKey(const int index) const
734 {
735   switch( GetType() )
736   {
737     case Property::MAP:
738     {
739       int i = 0;
740       Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
741       DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
742       if(container)
743       {
744         if(0 <= index && index < static_cast<int>(container->size()))
745         {
746           for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
747           {
748             if(i++ == index)
749             {
750               return iter->first;
751             }
752           }
753         }
754       }
755     }
756     break;
757     case Property::NONE:
758     case Property::ARRAY:
759     case Property::BOOLEAN:
760     case Property::FLOAT:
761     case Property::UNSIGNED_INTEGER:
762     case Property::INTEGER:
763     case Property::VECTOR2:
764     case Property::VECTOR3:
765     case Property::VECTOR4:
766     case Property::MATRIX:
767     case Property::MATRIX3:
768     case Property::RECTANGLE:
769     case Property::ROTATION:
770     case Property::STRING:
771     case Property::TYPE_COUNT:
772     {
773       break;
774     }
775   }
776
777
778   // should never return this
779   static std::string null;
780   return null;
781 }
782
783
784 void Property::Value::SetValue(const std::string& key, const Property::Value &value)
785 {
786   DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
787
788   Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
789
790   if(container)
791   {
792     for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
793     {
794       if(iter->first == key)
795       {
796         iter->second = value;
797         return;
798       }
799     }
800
801     // if we get here its a new key
802     container->push_back(Property::StringValuePair(key, value));
803
804   }
805 }
806
807 Property::Value& Property::Value::GetItem(const int index) const
808 {
809   switch( GetType() )
810   {
811     case Property::MAP:
812     {
813       int i = 0;
814       Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
815
816       DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
817       if(container)
818       {
819         DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
820         DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
821
822         for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
823         {
824           if(i++ == index)
825           {
826             return iter->second;
827           }
828         }
829       }
830     }
831     break;
832
833     case Property::ARRAY:
834     {
835       int i = 0;
836       Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
837
838       DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
839       if(container)
840       {
841         DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
842         DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
843
844         for(Property::Array::iterator iter = container->begin(); iter != container->end(); ++iter)
845         {
846           if(i++ == index)
847           {
848             return *iter;
849           }
850         }
851       }
852     }
853     break;
854
855     case Property::NONE:
856     case Property::BOOLEAN:
857     case Property::FLOAT:
858     case Property::INTEGER:
859     case Property::UNSIGNED_INTEGER:
860     case Property::VECTOR2:
861     case Property::VECTOR3:
862     case Property::VECTOR4:
863     case Property::MATRIX3:
864     case Property::MATRIX:
865     case Property::RECTANGLE:
866     case Property::ROTATION:
867     case Property::STRING:
868     case Property::TYPE_COUNT:
869     {
870       DALI_ASSERT_ALWAYS(!"Cannot GetItem on property Type; not a container");
871       break;
872     }
873
874   } // switch GetType()
875
876
877   DALI_ASSERT_ALWAYS(!"Property value index not valid");
878
879   // should never return this
880   static Property::Value null;
881   return null;
882 }
883
884 void Property::Value::SetItem(const int index, const Property::Value &value)
885 {
886   switch( GetType() )
887   {
888     case Property::MAP:
889     {
890       Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
891       if( container && index < static_cast<int>(container->size()) )
892       {
893         int i = 0;
894         for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
895         {
896           if(i++ == index)
897           {
898             iter->second = value;
899             break;
900           }
901         }
902       }
903     }
904     break;
905
906     case Property::ARRAY:
907     {
908       Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
909       if( container && index < static_cast<int>(container->size()) )
910       {
911         (*container)[index] = value;
912       }
913     }
914     break;
915
916     case Property::NONE:
917     case Property::BOOLEAN:
918     case Property::FLOAT:
919     case Property::INTEGER:
920     case Property::UNSIGNED_INTEGER:
921     case Property::VECTOR2:
922     case Property::VECTOR3:
923     case Property::VECTOR4:
924     case Property::MATRIX3:
925     case Property::MATRIX:
926     case Property::RECTANGLE:
927     case Property::ROTATION:
928     case Property::STRING:
929     case Property::TYPE_COUNT:
930     {
931       DALI_ASSERT_ALWAYS(!"Cannot SetItem on property Type; not a container");
932       break;
933     }
934   }
935 }
936
937 int Property::Value::AppendItem(const Property::Value &value)
938 {
939   DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
940
941   Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
942
943   if(container)
944   {
945     container->push_back(value);
946     return container->size() - 1;
947   }
948   else
949   {
950     return -1;
951   }
952
953 }
954
955 int Property::Value::GetSize() const
956 {
957   int ret = 0;
958
959   switch(GetType())
960   {
961     case Property::MAP:
962     {
963       Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
964       if(container)
965       {
966         ret = container->size();
967       }
968     }
969     break;
970
971     case Property::ARRAY:
972     {
973       Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
974       if(container)
975       {
976         ret = container->size();
977       }
978     }
979     break;
980
981     case Property::NONE:
982     case Property::BOOLEAN:
983     case Property::FLOAT:
984     case Property::INTEGER:
985     case Property::UNSIGNED_INTEGER:
986     case Property::VECTOR2:
987     case Property::VECTOR3:
988     case Property::VECTOR4:
989     case Property::MATRIX3:
990     case Property::MATRIX:
991     case Property::RECTANGLE:
992     case Property::ROTATION:
993     case Property::STRING:
994     case Property::TYPE_COUNT:
995     {
996       break;
997     }
998
999   }
1000
1001   return ret;
1002 }
1003
1004
1005 } // namespace Dali