2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <dali/public-api/object/property-value.h>
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>
38 struct Property::Value::Impl
41 : mType( Property::NONE )
46 : mType( PropertyTypes::Get<bool>() ),
51 Impl(float floatValue)
52 : mType( PropertyTypes::Get<float>() ),
57 Impl(int integerValue)
58 : mType( PropertyTypes::Get<int>() ),
59 mValue( integerValue )
63 Impl(unsigned int unsignedIntegerValue)
64 : mType( PropertyTypes::Get<unsigned int>() ),
65 mValue( unsignedIntegerValue )
69 Impl(const Vector2& vectorValue)
70 : mType( PropertyTypes::Get<Vector2>() ),
75 Impl(const Vector3& vectorValue)
76 : mType( PropertyTypes::Get<Vector3>() ),
81 Impl(const Vector4& vectorValue)
82 : mType( PropertyTypes::Get<Vector4>() ),
87 Impl(const Matrix3& matrixValue)
88 : mType(PropertyTypes::Get<Matrix3>()),
93 Impl(const Matrix& matrixValue)
94 : mType(PropertyTypes::Get<Matrix>()),
99 Impl(const AngleAxis& angleAxisValue)
100 : mType( PropertyTypes::Get<AngleAxis>() ),
101 mValue( angleAxisValue )
105 Impl(const Quaternion& quaternionValue)
106 : mType( PropertyTypes::Get<Quaternion>() ),
107 mValue( quaternionValue )
111 Impl(const std::string& stringValue)
112 : mType( PropertyTypes::Get<std::string>() ),
113 mValue( stringValue )
117 Impl(const Rect<int>& rect)
118 : mType( PropertyTypes::Get<Rect<int> >() ),
123 Impl(Property::Map container)
124 : mType( PropertyTypes::Get<Property::Map >() ),
129 Impl(Property::Array container)
130 : mType( PropertyTypes::Get<Property::Array >() ),
137 typedef Any AnyValue;
141 Property::Value::Value()
147 Property::Value::Value(bool boolValue)
150 mImpl = new Impl( boolValue );
153 Property::Value::Value(float floatValue)
156 mImpl = new Impl( floatValue );
159 Property::Value::Value(int integerValue)
162 mImpl = new Impl( integerValue );
165 Property::Value::Value(unsigned int unsignedIntegerValue)
168 mImpl = new Impl( unsignedIntegerValue );
171 Property::Value::Value(const Vector2& vectorValue)
174 mImpl = new Impl( vectorValue );
177 Property::Value::Value(const Vector3& vectorValue)
180 mImpl = new Impl( vectorValue );
183 Property::Value::Value(const Vector4& vectorValue)
186 mImpl = new Impl( vectorValue );
189 Property::Value::Value(const Matrix3& matrixValue)
192 mImpl = new Impl( matrixValue );
195 Property::Value::Value(const Matrix& matrixValue)
198 mImpl = new Impl( matrixValue );
201 Property::Value::Value(const Rect<int>& rect)
204 mImpl = new Impl( rect );
207 Property::Value::Value(const AngleAxis& angleAxisValue)
210 mImpl = new Impl( angleAxisValue );
213 Property::Value::Value(const Quaternion& quaternionValue)
215 mImpl = new Impl( quaternionValue );
218 Property::Value::Value(const std::string& stringValue)
220 mImpl = new Impl( stringValue );
223 Property::Value::Value(const char *stringValue)
225 mImpl = new Impl( std::string(stringValue) );
228 Property::Value::Value(Property::Array &arrayValue)
230 mImpl = new Impl( arrayValue );
233 Property::Value::Value(Property::Map &mapValue)
235 mImpl = new Impl( mapValue );
239 Property::Value::~Value()
244 Property::Value::Value(const Value& value)
246 switch (value.GetType())
248 case Property::BOOLEAN:
250 mImpl = new Impl( value.Get<bool>() );
254 case Property::FLOAT:
256 mImpl = new Impl( value.Get<float>() );
260 case Property::INTEGER:
262 mImpl = new Impl( value.Get<int>() );
266 case Property::UNSIGNED_INTEGER:
268 mImpl = new Impl( value.Get<unsigned int>() );
272 case Property::VECTOR2:
274 mImpl = new Impl( value.Get<Vector2>() );
278 case Property::VECTOR3:
280 mImpl = new Impl( value.Get<Vector3>() );
284 case Property::VECTOR4:
286 mImpl = new Impl( value.Get<Vector4>() );
290 case Property::RECTANGLE:
292 mImpl = new Impl( value.Get<Rect<int> >() );
296 case Property::ROTATION:
298 mImpl = new Impl( value.Get<Quaternion>() );
302 case Property::MATRIX3:
304 mImpl = new Impl( value.Get<Matrix3>());
308 case Property::MATRIX:
310 mImpl = new Impl( value.Get<Matrix>());
314 case Property::STRING:
316 mImpl = new Impl( value.Get<std::string>() );
322 mImpl = new Impl( value.Get<Property::Map>() );
326 case Property::ARRAY:
328 mImpl = new Impl( value.Get<Property::Array>() );
332 case Property::NONE: // fall
341 Property::Value::Value(Type type)
345 case Property::BOOLEAN:
347 mImpl = new Impl( false );
351 case Property::FLOAT:
353 mImpl = new Impl( 0.f );
357 case Property::INTEGER:
359 mImpl = new Impl( 0 );
363 case Property::UNSIGNED_INTEGER:
365 mImpl = new Impl( 0U );
369 case Property::VECTOR2:
371 mImpl = new Impl( Vector2::ZERO );
375 case Property::VECTOR3:
377 mImpl = new Impl( Vector3::ZERO );
381 case Property::VECTOR4:
383 mImpl = new Impl( Vector4::ZERO );
387 case Property::RECTANGLE:
389 mImpl = new Impl( Rect<int>(0,0,0,0) );
393 case Property::ROTATION:
395 mImpl = new Impl( Quaternion(0.f, Vector4::YAXIS) );
399 case Property::STRING:
401 mImpl = new Impl( std::string() );
407 mImpl = new Impl( Property::Map() );
411 case Property::MATRIX:
413 mImpl = new Impl( Matrix() );
417 case Property::MATRIX3:
419 mImpl = new Impl( Matrix3() );
423 case Property::ARRAY:
425 mImpl = new Impl( Property::Array() );
429 case Property::NONE: // fall
438 Property::Value& Property::Value::operator=(const Property::Value& value)
442 // skip self assignment
446 mImpl->mType = value.GetType();
448 switch (mImpl->mType)
450 case Property::BOOLEAN:
452 mImpl->mValue = value.Get<bool>();
456 case Property::FLOAT:
458 mImpl->mValue = value.Get<float>();
462 case Property::INTEGER:
464 mImpl->mValue = value.Get<int>();
468 case Property::UNSIGNED_INTEGER:
470 mImpl->mValue = value.Get<unsigned int>();
474 case Property::VECTOR2:
476 mImpl->mValue = value.Get<Vector2>();
480 case Property::VECTOR3:
482 mImpl->mValue = value.Get<Vector3>();
486 case Property::VECTOR4:
488 mImpl->mValue = value.Get<Vector4>();
492 case Property::RECTANGLE:
494 mImpl->mValue = value.Get<Rect<int> >();
498 case Property::ROTATION:
500 mImpl->mValue = value.Get<Quaternion>();
504 case Property::STRING:
506 mImpl->mValue = value.Get<std::string>();
510 case Property::MATRIX:
512 mImpl->mValue = value.Get<Matrix>();
516 case Property::MATRIX3:
518 mImpl->mValue = value.Get<Matrix3>();
524 mImpl->mValue = value.Get<Property::Map>();
528 case Property::ARRAY:
530 mImpl->mValue = value.Get<Property::Array>();
534 case Property::NONE: // fall
537 mImpl->mValue = Impl::AnyValue(0);
545 Property::Type Property::Value::GetType() const
550 void Property::Value::Get(bool& boolValue) const
552 DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" ); // AnyCast does asserted type checking
554 boolValue = AnyCast<bool>(mImpl->mValue);
557 void Property::Value::Get(float& floatValue) const
559 DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
561 floatValue = AnyCast<float>(mImpl->mValue);
564 void Property::Value::Get(int& integerValue) const
566 DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
568 integerValue = AnyCast<int>(mImpl->mValue);
571 void Property::Value::Get(unsigned int& unsignedIntegerValue) const
573 DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
575 unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
578 void Property::Value::Get(Vector2& vectorValue) const
580 DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
582 vectorValue = AnyCast<Vector2>(mImpl->mValue);
585 void Property::Value::Get(Vector3& vectorValue) const
587 DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
589 vectorValue = AnyCast<Vector3>(mImpl->mValue);
592 void Property::Value::Get(Vector4& vectorValue) const
594 DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
596 vectorValue = AnyCast<Vector4>(mImpl->mValue);
599 void Property::Value::Get(Matrix3& matrixValue) const
601 DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
602 matrixValue = AnyCast<Matrix3>(mImpl->mValue);
605 void Property::Value::Get(Matrix& matrixValue) const
607 DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
608 matrixValue = AnyCast<Matrix>(mImpl->mValue);
611 void Property::Value::Get(Rect<int>& rect) const
613 DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
615 rect = AnyCast<Rect<int> >(mImpl->mValue);
618 void Property::Value::Get(AngleAxis& angleAxisValue) const
620 DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
622 // Rotations have two representations
623 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
624 typeid(AngleAxis) == mImpl->mValue.GetType() );
626 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
628 Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
630 Radian angleRadians(0.0f);
631 quaternion.ToAxisAngle( angleAxisValue.axis, angleRadians );
632 angleAxisValue.angle = angleRadians;
636 angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
640 void Property::Value::Get(Quaternion& quaternionValue) const
642 DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
644 // Rotations have two representations
645 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
646 typeid(AngleAxis) == mImpl->mValue.GetType() );
648 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
650 quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
654 AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
656 quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
660 void Property::Value::Get(std::string &out) const
662 DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
664 out = AnyCast<std::string>(mImpl->mValue);
667 void Property::Value::Get(Property::Array &out) const
669 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
671 out = AnyCast<Property::Array>(mImpl->mValue);
674 void Property::Value::Get(Property::Map &out) const
676 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
678 out = AnyCast<Property::Map>(mImpl->mValue);
681 Property::Value& Property::Value::GetValue(const std::string& key) const
683 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
685 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
687 DALI_ASSERT_DEBUG(container);
691 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
693 if(iter->first == key)
700 DALI_LOG_WARNING("Cannot find property map key %s", key.c_str());
701 DALI_ASSERT_ALWAYS(!"Cannot find property map key");
703 // should never return this
704 static Property::Value null;
708 bool Property::Value::HasKey(const std::string& key) const
712 if( Property::MAP == GetType() )
714 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
716 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
720 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
722 if(iter->first == key)
734 const std::string& Property::Value::GetKey(const int index) const
741 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
742 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
745 if(0 <= index && index < static_cast<int>(container->size()))
747 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
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:
779 // should never return this
780 static std::string null;
785 void Property::Value::SetValue(const std::string& key, const Property::Value &value)
787 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
789 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
793 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
795 if(iter->first == key)
797 iter->second = value;
802 // if we get here its a new key
803 container->push_back(Property::StringValuePair(key, value));
808 Property::Value& Property::Value::GetItem(const int index) const
815 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
817 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
820 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
821 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
823 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
834 case Property::ARRAY:
837 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
839 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
842 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
843 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
845 for(Property::Array::iterator iter = container->begin(); iter != container->end(); ++iter)
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:
871 DALI_ASSERT_ALWAYS(!"Cannot GetItem on property Type; not a container");
875 } // switch GetType()
878 DALI_ASSERT_ALWAYS(!"Property value index not valid");
880 // should never return this
881 static Property::Value null;
885 void Property::Value::SetItem(const int index, const Property::Value &value)
891 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
892 if( container && index < static_cast<int>(container->size()) )
895 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
899 iter->second = value;
907 case Property::ARRAY:
909 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
910 if( container && index < static_cast<int>(container->size()) )
912 (*container)[index] = value;
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:
932 DALI_ASSERT_ALWAYS(!"Cannot SetItem on property Type; not a container");
938 int Property::Value::AppendItem(const Property::Value &value)
940 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
942 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
946 container->push_back(value);
947 return container->size() - 1;
956 int Property::Value::GetSize() const
964 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
967 ret = container->size();
972 case Property::ARRAY:
974 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
977 ret = container->size();
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: