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