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-map.h>
33 #include <dali/public-api/object/property-types.h>
34 #include <dali/integration-api/debug.h>
39 struct Property::Value::Impl
42 : mType( Property::NONE )
47 : mType( PropertyTypes::Get<bool>() ),
52 Impl(float floatValue)
53 : mType( PropertyTypes::Get<float>() ),
58 Impl(int integerValue)
59 : mType( PropertyTypes::Get<int>() ),
60 mValue( integerValue )
64 Impl(unsigned int unsignedIntegerValue)
65 : mType( PropertyTypes::Get<unsigned int>() ),
66 mValue( unsignedIntegerValue )
70 Impl(const Vector2& vectorValue)
71 : mType( PropertyTypes::Get<Vector2>() ),
76 Impl(const Vector3& vectorValue)
77 : mType( PropertyTypes::Get<Vector3>() ),
82 Impl(const Vector4& vectorValue)
83 : mType( PropertyTypes::Get<Vector4>() ),
88 Impl(const Matrix3& matrixValue)
89 : mType(PropertyTypes::Get<Matrix3>()),
94 Impl(const Matrix& matrixValue)
95 : mType(PropertyTypes::Get<Matrix>()),
100 Impl(const AngleAxis& angleAxisValue)
101 : mType( PropertyTypes::Get<AngleAxis>() ),
102 mValue( angleAxisValue )
106 Impl(const Quaternion& quaternionValue)
107 : mType( PropertyTypes::Get<Quaternion>() ),
108 mValue( quaternionValue )
112 Impl(const std::string& stringValue)
113 : mType( PropertyTypes::Get<std::string>() ),
114 mValue( stringValue )
118 Impl(const Rect<int>& rect)
119 : mType( PropertyTypes::Get<Rect<int> >() ),
124 Impl(Property::Map container)
125 : mType( PropertyTypes::Get<Property::Map >() ),
130 Impl(Property::Array container)
131 : mType( PropertyTypes::Get<Property::Array >() ),
138 typedef Any AnyValue;
142 Property::Value::Value()
148 Property::Value::Value(bool boolValue)
151 mImpl = new Impl( boolValue );
154 Property::Value::Value(float floatValue)
157 mImpl = new Impl( floatValue );
160 Property::Value::Value(int integerValue)
163 mImpl = new Impl( integerValue );
166 Property::Value::Value(unsigned int unsignedIntegerValue)
169 mImpl = new Impl( unsignedIntegerValue );
172 Property::Value::Value(const Vector2& vectorValue)
175 mImpl = new Impl( vectorValue );
178 Property::Value::Value(const Vector3& vectorValue)
181 mImpl = new Impl( vectorValue );
184 Property::Value::Value(const Vector4& vectorValue)
187 mImpl = new Impl( vectorValue );
190 Property::Value::Value(const Matrix3& matrixValue)
193 mImpl = new Impl( matrixValue );
196 Property::Value::Value(const Matrix& matrixValue)
199 mImpl = new Impl( matrixValue );
202 Property::Value::Value(const Rect<int>& rect)
205 mImpl = new Impl( rect );
208 Property::Value::Value(const AngleAxis& angleAxisValue)
211 mImpl = new Impl( angleAxisValue );
214 Property::Value::Value(const Quaternion& quaternionValue)
216 mImpl = new Impl( quaternionValue );
219 Property::Value::Value(const std::string& stringValue)
221 mImpl = new Impl( stringValue );
224 Property::Value::Value(const char *stringValue)
226 mImpl = new Impl( std::string(stringValue) );
229 Property::Value::Value(Property::Array &arrayValue)
231 mImpl = new Impl( arrayValue );
234 Property::Value::Value(Property::Map &mapValue)
236 mImpl = new Impl( mapValue );
240 Property::Value::~Value()
245 Property::Value::Value(const Value& value)
247 switch (value.GetType())
249 case Property::BOOLEAN:
251 mImpl = new Impl( value.Get<bool>() );
255 case Property::FLOAT:
257 mImpl = new Impl( value.Get<float>() );
261 case Property::INTEGER:
263 mImpl = new Impl( value.Get<int>() );
267 case Property::UNSIGNED_INTEGER:
269 mImpl = new Impl( value.Get<unsigned int>() );
273 case Property::VECTOR2:
275 mImpl = new Impl( value.Get<Vector2>() );
279 case Property::VECTOR3:
281 mImpl = new Impl( value.Get<Vector3>() );
285 case Property::VECTOR4:
287 mImpl = new Impl( value.Get<Vector4>() );
291 case Property::RECTANGLE:
293 mImpl = new Impl( value.Get<Rect<int> >() );
297 case Property::ROTATION:
299 mImpl = new Impl( value.Get<Quaternion>() );
303 case Property::MATRIX3:
305 mImpl = new Impl( value.Get<Matrix3>());
309 case Property::MATRIX:
311 mImpl = new Impl( value.Get<Matrix>());
315 case Property::STRING:
317 mImpl = new Impl( value.Get<std::string>() );
323 mImpl = new Impl( value.Get<Property::Map>() );
327 case Property::ARRAY:
329 mImpl = new Impl( value.Get<Property::Array>() );
333 case Property::NONE: // fall
342 Property::Value::Value(Type type)
346 case Property::BOOLEAN:
348 mImpl = new Impl( false );
352 case Property::FLOAT:
354 mImpl = new Impl( 0.f );
358 case Property::INTEGER:
360 mImpl = new Impl( 0 );
364 case Property::UNSIGNED_INTEGER:
366 mImpl = new Impl( 0U );
370 case Property::VECTOR2:
372 mImpl = new Impl( Vector2::ZERO );
376 case Property::VECTOR3:
378 mImpl = new Impl( Vector3::ZERO );
382 case Property::VECTOR4:
384 mImpl = new Impl( Vector4::ZERO );
388 case Property::RECTANGLE:
390 mImpl = new Impl( Rect<int>(0,0,0,0) );
394 case Property::ROTATION:
396 mImpl = new Impl( Quaternion(0.f, Vector4::YAXIS) );
400 case Property::STRING:
402 mImpl = new Impl( std::string() );
408 mImpl = new Impl( Property::Map() );
412 case Property::MATRIX:
414 mImpl = new Impl( Matrix() );
418 case Property::MATRIX3:
420 mImpl = new Impl( Matrix3() );
424 case Property::ARRAY:
426 mImpl = new Impl( Property::Array() );
430 case Property::NONE: // fall
439 Property::Value& Property::Value::operator=(const Property::Value& value)
443 // skip self assignment
447 mImpl->mType = value.GetType();
449 switch (mImpl->mType)
451 case Property::BOOLEAN:
453 mImpl->mValue = value.Get<bool>();
457 case Property::FLOAT:
459 mImpl->mValue = value.Get<float>();
463 case Property::INTEGER:
465 mImpl->mValue = value.Get<int>();
469 case Property::UNSIGNED_INTEGER:
471 mImpl->mValue = value.Get<unsigned int>();
475 case Property::VECTOR2:
477 mImpl->mValue = value.Get<Vector2>();
481 case Property::VECTOR3:
483 mImpl->mValue = value.Get<Vector3>();
487 case Property::VECTOR4:
489 mImpl->mValue = value.Get<Vector4>();
493 case Property::RECTANGLE:
495 mImpl->mValue = value.Get<Rect<int> >();
499 case Property::ROTATION:
501 mImpl->mValue = value.Get<Quaternion>();
505 case Property::STRING:
507 mImpl->mValue = value.Get<std::string>();
511 case Property::MATRIX:
513 mImpl->mValue = value.Get<Matrix>();
517 case Property::MATRIX3:
519 mImpl->mValue = value.Get<Matrix3>();
525 mImpl->mValue = value.Get<Property::Map>();
529 case Property::ARRAY:
531 mImpl->mValue = value.Get<Property::Array>();
535 case Property::NONE: // fall
538 mImpl->mValue = Impl::AnyValue(0);
546 Property::Type Property::Value::GetType() const
551 void Property::Value::Get(bool& boolValue) const
553 DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" ); // AnyCast does asserted type checking
555 boolValue = AnyCast<bool>(mImpl->mValue);
558 void Property::Value::Get(float& floatValue) const
560 DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
562 floatValue = AnyCast<float>(mImpl->mValue);
565 void Property::Value::Get(int& integerValue) const
567 DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
569 integerValue = AnyCast<int>(mImpl->mValue);
572 void Property::Value::Get(unsigned int& unsignedIntegerValue) const
574 DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
576 unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
579 void Property::Value::Get(Vector2& vectorValue) const
581 DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
583 vectorValue = AnyCast<Vector2>(mImpl->mValue);
586 void Property::Value::Get(Vector3& vectorValue) const
588 DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
590 vectorValue = AnyCast<Vector3>(mImpl->mValue);
593 void Property::Value::Get(Vector4& vectorValue) const
595 DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
597 vectorValue = AnyCast<Vector4>(mImpl->mValue);
600 void Property::Value::Get(Matrix3& matrixValue) const
602 DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
603 matrixValue = AnyCast<Matrix3>(mImpl->mValue);
606 void Property::Value::Get(Matrix& matrixValue) const
608 DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
609 matrixValue = AnyCast<Matrix>(mImpl->mValue);
612 void Property::Value::Get(Rect<int>& rect) const
614 DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
616 rect = AnyCast<Rect<int> >(mImpl->mValue);
619 void Property::Value::Get(AngleAxis& angleAxisValue) const
621 DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
623 // Rotations have two representations
624 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
625 typeid(AngleAxis) == mImpl->mValue.GetType() );
627 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
629 Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
631 Radian angleRadians(0.0f);
632 quaternion.ToAxisAngle( angleAxisValue.axis, angleRadians );
633 angleAxisValue.angle = angleRadians;
637 angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
641 void Property::Value::Get(Quaternion& quaternionValue) const
643 DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
645 // Rotations have two representations
646 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
647 typeid(AngleAxis) == mImpl->mValue.GetType() );
649 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
651 quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
655 AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
657 quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
661 void Property::Value::Get(std::string &out) const
663 DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
665 out = AnyCast<std::string>(mImpl->mValue);
668 void Property::Value::Get(Property::Array &out) const
670 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
672 out = AnyCast<Property::Array>(mImpl->mValue);
675 void Property::Value::Get(Property::Map &out) const
677 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
679 out = AnyCast<Property::Map>(mImpl->mValue);
682 Property::Value& Property::Value::GetValue(const std::string& key) const
684 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
686 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
688 DALI_ASSERT_DEBUG(container);
692 Property::Value* value = container->Find( key );
699 DALI_LOG_WARNING("Cannot find property map key %s", key.c_str());
700 DALI_ASSERT_ALWAYS(!"Cannot find property map key");
702 // should never return this
703 static Property::Value null;
707 bool Property::Value::HasKey(const std::string& key) const
711 if( Property::MAP == GetType() )
713 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
715 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
719 Property::Value* value = container->Find( key );
731 const std::string& Property::Value::GetKey(const int index) const
737 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
738 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
741 if(0 <= index && index < static_cast<int>(container->Count()))
743 return container->GetKey( index );
749 case Property::ARRAY:
750 case Property::BOOLEAN:
751 case Property::FLOAT:
752 case Property::UNSIGNED_INTEGER:
753 case Property::INTEGER:
754 case Property::VECTOR2:
755 case Property::VECTOR3:
756 case Property::VECTOR4:
757 case Property::MATRIX:
758 case Property::MATRIX3:
759 case Property::RECTANGLE:
760 case Property::ROTATION:
761 case Property::STRING:
762 case Property::TYPE_COUNT:
769 // should never return this
770 static std::string null;
775 void Property::Value::SetValue(const std::string& key, const Property::Value &value)
777 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
779 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
783 (*container)[ key ] = value;
787 Property::Value& Property::Value::GetItem(const int index) const
793 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
795 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
798 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->Count()) && "Property array index invalid");
799 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
801 return container->GetValue( index );
806 case Property::ARRAY:
809 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
811 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
814 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
815 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
817 for(Property::Array::iterator iter = container->begin(); iter != container->end(); ++iter)
829 case Property::BOOLEAN:
830 case Property::FLOAT:
831 case Property::INTEGER:
832 case Property::UNSIGNED_INTEGER:
833 case Property::VECTOR2:
834 case Property::VECTOR3:
835 case Property::VECTOR4:
836 case Property::MATRIX3:
837 case Property::MATRIX:
838 case Property::RECTANGLE:
839 case Property::ROTATION:
840 case Property::STRING:
841 case Property::TYPE_COUNT:
843 DALI_ASSERT_ALWAYS(!"Cannot GetItem on property Type; not a container");
847 } // switch GetType()
850 DALI_ASSERT_ALWAYS(!"Property value index not valid");
852 // should never return this
853 static Property::Value null;
857 Property::Value& Property::Value::GetItem(const int index, std::string& key) const
859 Property::Value& ret( GetItem(index) );
861 if( Property::MAP == GetType() )
863 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
864 if( index < static_cast<int>(container->Count()) )
866 key = container->GetKey( index );
873 void Property::Value::SetItem(const int index, const Property::Value &value)
879 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
880 if( container && index < static_cast<int>(container->Count()) )
882 Property::Value& indexValue = container->GetValue( index );
888 case Property::ARRAY:
890 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
891 if( container && index < static_cast<int>(container->size()) )
893 (*container)[index] = value;
899 case Property::BOOLEAN:
900 case Property::FLOAT:
901 case Property::INTEGER:
902 case Property::UNSIGNED_INTEGER:
903 case Property::VECTOR2:
904 case Property::VECTOR3:
905 case Property::VECTOR4:
906 case Property::MATRIX3:
907 case Property::MATRIX:
908 case Property::RECTANGLE:
909 case Property::ROTATION:
910 case Property::STRING:
911 case Property::TYPE_COUNT:
913 DALI_ASSERT_ALWAYS(!"Cannot SetItem on property Type; not a container");
919 int Property::Value::AppendItem(const Property::Value &value)
921 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
923 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
927 container->push_back(value);
928 return container->size() - 1;
937 int Property::Value::GetSize() const
945 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
948 ret = container->Count();
953 case Property::ARRAY:
955 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
958 ret = container->size();
964 case Property::BOOLEAN:
965 case Property::FLOAT:
966 case Property::INTEGER:
967 case Property::UNSIGNED_INTEGER:
968 case Property::VECTOR2:
969 case Property::VECTOR3:
970 case Property::VECTOR4:
971 case Property::MATRIX3:
972 case Property::MATRIX:
973 case Property::RECTANGLE:
974 case Property::ROTATION:
975 case Property::STRING:
976 case Property::TYPE_COUNT: