2 // Copyright (c) 2014 Samsung Electronics Co., Ltd.
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
8 // http://floralicense.org/license/
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.
18 #include <dali/public-api/object/property-value.h>
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>
37 struct Property::Value::Impl
40 : mType( Property::NONE )
45 : mType( PropertyTypes::Get<bool>() ),
50 Impl(float floatValue)
51 : mType( PropertyTypes::Get<float>() ),
56 Impl(int integerValue)
57 : mType( PropertyTypes::Get<int>() ),
58 mValue( integerValue )
62 Impl(unsigned int unsignedIntegerValue)
63 : mType( PropertyTypes::Get<unsigned int>() ),
64 mValue( unsignedIntegerValue )
68 Impl(const Vector2& vectorValue)
69 : mType( PropertyTypes::Get<Vector2>() ),
74 Impl(const Vector3& vectorValue)
75 : mType( PropertyTypes::Get<Vector3>() ),
80 Impl(const Vector4& vectorValue)
81 : mType( PropertyTypes::Get<Vector4>() ),
86 Impl(const Matrix3& matrixValue)
87 : mType(PropertyTypes::Get<Matrix3>()),
92 Impl(const Matrix& matrixValue)
93 : mType(PropertyTypes::Get<Matrix>()),
98 Impl(const AngleAxis& angleAxisValue)
99 : mType( PropertyTypes::Get<AngleAxis>() ),
100 mValue( angleAxisValue )
104 Impl(const Quaternion& quaternionValue)
105 : mType( PropertyTypes::Get<Quaternion>() ),
106 mValue( quaternionValue )
110 Impl(const std::string& stringValue)
111 : mType( PropertyTypes::Get<std::string>() ),
112 mValue( stringValue )
116 Impl(const Rect<int>& rect)
117 : mType( PropertyTypes::Get<Rect<int> >() ),
122 Impl(Property::Map container)
123 : mType( PropertyTypes::Get<Property::Map >() ),
128 Impl(Property::Array container)
129 : mType( PropertyTypes::Get<Property::Array >() ),
136 typedef Any AnyValue;
140 Property::Value::Value()
146 Property::Value::Value(bool boolValue)
149 mImpl = new Impl( boolValue );
152 Property::Value::Value(float floatValue)
155 mImpl = new Impl( floatValue );
158 Property::Value::Value(int integerValue)
161 mImpl = new Impl( integerValue );
164 Property::Value::Value(unsigned int unsignedIntegerValue)
167 mImpl = new Impl( unsignedIntegerValue );
170 Property::Value::Value(const Vector2& vectorValue)
173 mImpl = new Impl( vectorValue );
176 Property::Value::Value(const Vector3& vectorValue)
179 mImpl = new Impl( vectorValue );
182 Property::Value::Value(const Vector4& vectorValue)
185 mImpl = new Impl( vectorValue );
188 Property::Value::Value(const Matrix3& matrixValue)
191 mImpl = new Impl( matrixValue );
194 Property::Value::Value(const Matrix& matrixValue)
197 mImpl = new Impl( matrixValue );
200 Property::Value::Value(const Rect<int>& rect)
203 mImpl = new Impl( rect );
206 Property::Value::Value(const AngleAxis& angleAxisValue)
209 mImpl = new Impl( angleAxisValue );
212 Property::Value::Value(const Quaternion& quaternionValue)
214 mImpl = new Impl( quaternionValue );
217 Property::Value::Value(const std::string& stringValue)
219 mImpl = new Impl( stringValue );
222 Property::Value::Value(const char *stringValue)
224 mImpl = new Impl( std::string(stringValue) );
227 Property::Value::Value(Property::Array &arrayValue)
229 mImpl = new Impl( arrayValue );
232 Property::Value::Value(Property::Map &mapValue)
234 mImpl = new Impl( mapValue );
238 Property::Value::~Value()
243 Property::Value::Value(const Value& value)
245 switch (value.GetType())
247 case Property::BOOLEAN:
249 mImpl = new Impl( value.Get<bool>() );
253 case Property::FLOAT:
255 mImpl = new Impl( value.Get<float>() );
259 case Property::INTEGER:
261 mImpl = new Impl( value.Get<int>() );
265 case Property::UNSIGNED_INTEGER:
267 mImpl = new Impl( value.Get<unsigned int>() );
271 case Property::VECTOR2:
273 mImpl = new Impl( value.Get<Vector2>() );
277 case Property::VECTOR3:
279 mImpl = new Impl( value.Get<Vector3>() );
283 case Property::VECTOR4:
285 mImpl = new Impl( value.Get<Vector4>() );
289 case Property::RECTANGLE:
291 mImpl = new Impl( value.Get<Rect<int> >() );
295 case Property::ROTATION:
297 mImpl = new Impl( value.Get<Quaternion>() );
301 case Property::MATRIX3:
303 mImpl = new Impl( value.Get<Matrix3>());
307 case Property::MATRIX:
309 mImpl = new Impl( value.Get<Matrix>());
313 case Property::STRING:
315 mImpl = new Impl( value.Get<std::string>() );
321 mImpl = new Impl( value.Get<Property::Map>() );
325 case Property::ARRAY:
327 mImpl = new Impl( value.Get<Property::Array>() );
331 case Property::NONE: // fall
340 Property::Value::Value(Type type)
344 case Property::BOOLEAN:
346 mImpl = new Impl( false );
350 case Property::FLOAT:
352 mImpl = new Impl( 0.f );
356 case Property::INTEGER:
358 mImpl = new Impl( 0 );
362 case Property::UNSIGNED_INTEGER:
364 mImpl = new Impl( 0U );
368 case Property::VECTOR2:
370 mImpl = new Impl( Vector2::ZERO );
374 case Property::VECTOR3:
376 mImpl = new Impl( Vector3::ZERO );
380 case Property::VECTOR4:
382 mImpl = new Impl( Vector4::ZERO );
386 case Property::RECTANGLE:
388 mImpl = new Impl( Rect<int>(0,0,0,0) );
392 case Property::ROTATION:
394 mImpl = new Impl( Quaternion(0.f, Vector4::YAXIS) );
398 case Property::STRING:
400 mImpl = new Impl( std::string() );
406 mImpl = new Impl( Property::Map() );
410 case Property::MATRIX:
412 mImpl = new Impl( Matrix() );
416 case Property::MATRIX3:
418 mImpl = new Impl( Matrix3() );
422 case Property::ARRAY:
424 mImpl = new Impl( Property::Array() );
428 case Property::NONE: // fall
437 Property::Value& Property::Value::operator=(const Property::Value& value)
441 // skip self assignment
445 mImpl->mType = value.GetType();
447 switch (mImpl->mType)
449 case Property::BOOLEAN:
451 mImpl->mValue = value.Get<bool>();
455 case Property::FLOAT:
457 mImpl->mValue = value.Get<float>();
461 case Property::INTEGER:
463 mImpl->mValue = value.Get<int>();
467 case Property::UNSIGNED_INTEGER:
469 mImpl->mValue = value.Get<unsigned int>();
473 case Property::VECTOR2:
475 mImpl->mValue = value.Get<Vector2>();
479 case Property::VECTOR3:
481 mImpl->mValue = value.Get<Vector3>();
485 case Property::VECTOR4:
487 mImpl->mValue = value.Get<Vector4>();
491 case Property::RECTANGLE:
493 mImpl->mValue = value.Get<Rect<int> >();
497 case Property::ROTATION:
499 mImpl->mValue = value.Get<Quaternion>();
503 case Property::STRING:
505 mImpl->mValue = value.Get<std::string>();
509 case Property::MATRIX:
511 mImpl->mValue = value.Get<Matrix>();
515 case Property::MATRIX3:
517 mImpl->mValue = value.Get<Matrix3>();
523 mImpl->mValue = value.Get<Property::Map>();
527 case Property::ARRAY:
529 mImpl->mValue = value.Get<Property::Array>();
533 case Property::NONE: // fall
536 mImpl->mValue = Impl::AnyValue(0);
544 Property::Type Property::Value::GetType() const
549 void Property::Value::Get(bool& boolValue) const
551 DALI_ASSERT_DEBUG( Property::BOOLEAN == GetType() && "Property type invalid" ); // AnyCast does asserted type checking
553 boolValue = AnyCast<bool>(mImpl->mValue);
556 void Property::Value::Get(float& floatValue) const
558 DALI_ASSERT_DEBUG( Property::FLOAT == GetType() && "Property type invalid" );
560 floatValue = AnyCast<float>(mImpl->mValue);
563 void Property::Value::Get(int& integerValue) const
565 DALI_ASSERT_DEBUG( Property::INTEGER == GetType() && "Property type invalid" );
567 integerValue = AnyCast<int>(mImpl->mValue);
570 void Property::Value::Get(unsigned int& unsignedIntegerValue) const
572 DALI_ASSERT_DEBUG( Property::UNSIGNED_INTEGER == GetType() && "Property type invalid" );
574 unsignedIntegerValue = AnyCast<unsigned int>(mImpl->mValue);
577 void Property::Value::Get(Vector2& vectorValue) const
579 DALI_ASSERT_DEBUG( Property::VECTOR2 == GetType() && "Property type invalid" );
581 vectorValue = AnyCast<Vector2>(mImpl->mValue);
584 void Property::Value::Get(Vector3& vectorValue) const
586 DALI_ASSERT_DEBUG( Property::VECTOR3 == GetType() && "Property type invalid" );
588 vectorValue = AnyCast<Vector3>(mImpl->mValue);
591 void Property::Value::Get(Vector4& vectorValue) const
593 DALI_ASSERT_DEBUG( Property::VECTOR4 == GetType() && "Property type invalid" );
595 vectorValue = AnyCast<Vector4>(mImpl->mValue);
598 void Property::Value::Get(Matrix3& matrixValue) const
600 DALI_ASSERT_DEBUG( Property::MATRIX3 == GetType() && "Property type invalid" );
601 matrixValue = AnyCast<Matrix3>(mImpl->mValue);
604 void Property::Value::Get(Matrix& matrixValue) const
606 DALI_ASSERT_DEBUG( Property::MATRIX == GetType() && "Property type invalid" );
607 matrixValue = AnyCast<Matrix>(mImpl->mValue);
610 void Property::Value::Get(Rect<int>& rect) const
612 DALI_ASSERT_DEBUG( Property::RECTANGLE == GetType() && "Property type invalid" );
614 rect = AnyCast<Rect<int> >(mImpl->mValue);
617 void Property::Value::Get(AngleAxis& angleAxisValue) const
619 DALI_ASSERT_ALWAYS( Property::ROTATION == GetType() && "Property type invalid" );
621 // Rotations have two representations
622 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
623 typeid(AngleAxis) == mImpl->mValue.GetType() );
625 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
627 Quaternion quaternion = AnyCast<Quaternion>(mImpl->mValue);
629 Radian angleRadians(0.0f);
630 quaternion.ToAxisAngle( angleAxisValue.axis, angleRadians );
631 angleAxisValue.angle = angleRadians;
635 angleAxisValue = AnyCast<AngleAxis>(mImpl->mValue);
639 void Property::Value::Get(Quaternion& quaternionValue) const
641 DALI_ASSERT_DEBUG( Property::ROTATION == GetType() && "Property type invalid" );
643 // Rotations have two representations
644 DALI_ASSERT_DEBUG( typeid(Quaternion) == mImpl->mValue.GetType() ||
645 typeid(AngleAxis) == mImpl->mValue.GetType() );
647 if ( typeid(Quaternion) == mImpl->mValue.GetType() )
649 quaternionValue = AnyCast<Quaternion>(mImpl->mValue);
653 AngleAxis angleAxis = AnyCast<AngleAxis>(mImpl->mValue);
655 quaternionValue = Quaternion( Radian(angleAxis.angle), angleAxis.axis );
659 void Property::Value::Get(std::string &out) const
661 DALI_ASSERT_DEBUG(Property::STRING == GetType() && "Property type invalid");
663 out = AnyCast<std::string>(mImpl->mValue);
666 void Property::Value::Get(Property::Array &out) const
668 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
670 out = AnyCast<Property::Array>(mImpl->mValue);
673 void Property::Value::Get(Property::Map &out) const
675 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
677 out = AnyCast<Property::Map>(mImpl->mValue);
680 Property::Value& Property::Value::GetValue(const std::string& key) const
682 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
684 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
686 DALI_ASSERT_DEBUG(container);
690 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
692 if(iter->first == 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 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
721 if(iter->first == key)
733 const std::string& Property::Value::GetKey(const int index) const
740 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
741 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
744 if(0 <= index && index < static_cast<int>(container->size()))
746 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
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:
778 // should never return this
779 static std::string null;
784 void Property::Value::SetValue(const std::string& key, const Property::Value &value)
786 DALI_ASSERT_DEBUG(Property::MAP == GetType() && "Property type invalid");
788 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
792 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
794 if(iter->first == key)
796 iter->second = value;
801 // if we get here its a new key
802 container->push_back(Property::StringValuePair(key, value));
807 Property::Value& Property::Value::GetItem(const int index) const
814 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
816 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
819 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
820 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
822 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
833 case Property::ARRAY:
836 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
838 DALI_ASSERT_DEBUG(container && "Property::Map has no container?");
841 DALI_ASSERT_ALWAYS(index < static_cast<int>(container->size()) && "Property array index invalid");
842 DALI_ASSERT_ALWAYS(index >= 0 && "Property array index invalid");
844 for(Property::Array::iterator iter = container->begin(); iter != container->end(); ++iter)
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:
870 DALI_ASSERT_ALWAYS(!"Cannot GetItem on property Type; not a container");
874 } // switch GetType()
877 DALI_ASSERT_ALWAYS(!"Property value index not valid");
879 // should never return this
880 static Property::Value null;
884 void Property::Value::SetItem(const int index, const Property::Value &value)
890 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
891 if( container && index < static_cast<int>(container->size()) )
894 for(Property::Map::iterator iter = container->begin(); iter != container->end(); ++iter)
898 iter->second = value;
906 case Property::ARRAY:
908 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
909 if( container && index < static_cast<int>(container->size()) )
911 (*container)[index] = value;
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:
931 DALI_ASSERT_ALWAYS(!"Cannot SetItem on property Type; not a container");
937 int Property::Value::AppendItem(const Property::Value &value)
939 DALI_ASSERT_DEBUG(Property::ARRAY == GetType() && "Property type invalid");
941 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
945 container->push_back(value);
946 return container->size() - 1;
955 int Property::Value::GetSize() const
963 Property::Map *container = AnyCast<Property::Map>(&(mImpl->mValue));
966 ret = container->size();
971 case Property::ARRAY:
973 Property::Array *container = AnyCast<Property::Array>(&(mImpl->mValue));
976 ret = container->size();
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: