/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <ostream>
// INTERNAL INCLUDES
+#include <dali/public-api/common/extents.h>
#include <dali/public-api/math/angle-axis.h>
#include <dali/public-api/math/radian.h>
#include <dali/public-api/math/vector2.h>
namespace
{
/**
- * Helper to check if the property value can be read as int/unsigned int/bool
+ * Helper to check if the property value can be read as int/bool
*/
inline bool IsIntegerType( Property::Type type )
{
- return ( Property::BOOLEAN == type )||( Property::INTEGER == type )||(Property::UNSIGNED_INTEGER == type );
+ return ( Property::BOOLEAN == type )||( Property::INTEGER == type );
}
}
struct Property::Value::Impl
{
- Impl()
- : type( Property::NONE ),
- integerValue( 0 )
- { }
-
Impl( bool booleanValue )
: type( Property::BOOLEAN ),
integerValue( booleanValue )
floatValue( floatValue )
{ }
- Impl( int integerValue )
+ Impl( int32_t integerValue )
: type( Property::INTEGER ),
integerValue( integerValue )
{ }
- Impl( unsigned int unsignedIntegerValue )
- : type( Property::UNSIGNED_INTEGER ),
- unsignedIntegerValue( unsignedIntegerValue )
- { }
-
Impl( const Vector2& vectorValue )
: type( Property::VECTOR2 ),
vector2Value( new Vector2( vectorValue ) )
Impl( const AngleAxis& angleAxisValue )
: type( Property::ROTATION ),
- quaternionValue( new Quaternion( angleAxisValue.angle, angleAxisValue.axis ) )
+ angleAxisValue( new AngleAxis(angleAxisValue) )
{
}
Impl( const Quaternion& quaternionValue )
: type( Property::ROTATION ),
- quaternionValue( new Quaternion( quaternionValue ) )
+ angleAxisValue( new AngleAxis() )
{
+ quaternionValue.ToAxisAngle( angleAxisValue->axis, angleAxisValue->angle );
}
- Impl(const std::string& stringValue)
+ Impl( const std::string& stringValue )
: type( Property::STRING ),
stringValue( new std::string( stringValue ) )
{
}
- Impl( const Rect<int>& rectValue )
+ Impl( const Rect<int32_t>& rectValue )
: type( Property::RECTANGLE ),
rectValue( new Rect<int>( rectValue ) )
{
}
+ Impl( const Rect<float>& rectValue )
+ : type( Property::VECTOR4 ),
+ vector4Value( new Vector4( rectValue.x, rectValue.y, rectValue.width, rectValue.height ) )
+ {
+ }
+
Impl( const Property::Array& arrayValue )
: type( Property::ARRAY ),
arrayValue( new Property::Array( arrayValue ) )
{
}
+ Impl( Property::Array&& arrayValue )
+ : type( Property::ARRAY ),
+ arrayValue( new Property::Array( std::move( arrayValue ) ) )
+ {
+ }
+
Impl( const Property::Map& mapValue )
: type( Property::MAP ),
mapValue( new Property::Map( mapValue ) )
{
}
+ Impl( Property::Map&& mapValue )
+ : type( Property::MAP ),
+ mapValue( new Property::Map( std::move( mapValue ) ) )
+ {
+ }
+
+ Impl( const Extents& extentsValue )
+ : type( Property::EXTENTS ),
+ extentsValue( new Extents( extentsValue ) )
+ {
+ }
+
+ Impl( const std::initializer_list< KeyValuePair >& values )
+ : type( Property::MAP ),
+ mapValue( new Property::Map( values ) )
+ {
+ }
+
/**
* Destructor, takes care of releasing the dynamically allocated types
*/
case Property::NONE : // FALLTHROUGH
case Property::BOOLEAN : // FALLTHROUGH
case Property::FLOAT : // FALLTHROUGH
- case Property::INTEGER : // FALLTHROUGH
- case Property::UNSIGNED_INTEGER :
+ case Property::INTEGER :
{
break; // nothing to do
}
}
case Property::ROTATION:
{
- delete quaternionValue;
+ delete angleAxisValue;
break;
}
case Property::STRING:
delete mapValue;
break;
}
+ case Property::EXTENTS:
+ {
+ delete extentsValue;
+ break;
+ }
}
}
Type type;
union
{
- int integerValue;
+ int32_t integerValue;
float floatValue;
- unsigned int unsignedIntegerValue;
// must use pointers for any class value pre c++ 11
Vector2* vector2Value;
Vector3* vector3Value;
Vector4* vector4Value;
Matrix3* matrix3Value;
Matrix* matrixValue;
- Quaternion* quaternionValue;
+ AngleAxis* angleAxisValue;
std::string* stringValue;
- Rect<int>* rectValue;
+ Rect<int32_t>* rectValue;
Property::Array* arrayValue;
Property::Map* mapValue;
+ Extents* extentsValue;
};
+
+private:
+
+ // non-copyable
+ Impl( const Impl& ) = delete;
+ Impl& operator=( const Impl& ) = delete;
+
};
Property::Value::Value()
-: mImpl( NULL )
+: mImpl( nullptr )
{
}
{
}
-Property::Value::Value( int integerValue )
+Property::Value::Value( int32_t integerValue )
: mImpl( new Impl( integerValue ) )
{
}
-Property::Value::Value( unsigned int unsignedIntegerValue )
-: mImpl( new Impl( unsignedIntegerValue ) )
-{
-}
-
Property::Value::Value( const Vector2& vectorValue )
: mImpl( new Impl( vectorValue ) )
{
{
}
-Property::Value::Value( const Rect<int>& rectValue )
+Property::Value::Value( const Rect<int32_t>& rectValue )
+: mImpl( new Impl( rectValue ) )
+{
+}
+
+Property::Value::Value( const Rect<float>& rectValue )
: mImpl( new Impl( rectValue ) )
{
}
}
Property::Value::Value( const char* stringValue )
-: mImpl( NULL )
+: mImpl( nullptr )
{
- if( stringValue ) // string constructor is undefined with NULL pointer
+ if( stringValue ) // string constructor is undefined with nullptr
{
mImpl = new Impl( std::string(stringValue) );
}
{
}
+Property::Value::Value( Property::Array&& arrayValue )
+: mImpl( new Impl( std::move( arrayValue ) ) )
+{
+}
+
Property::Value::Value( Property::Map& mapValue )
: mImpl( new Impl( mapValue ) )
{
}
+Property::Value::Value( Property::Map&& mapValue )
+: mImpl( new Impl( std::move( mapValue ) ) )
+{
+}
+
+Property::Value::Value( const Extents& extentsValue )
+: mImpl( new Impl( extentsValue ) )
+{
+}
+
+Property::Value::Value( const std::initializer_list< KeyValuePair >& values )
+: mImpl( new Impl( values ) )
+{
+}
+
Property::Value::Value( Type type )
+: mImpl( nullptr )
{
switch (type)
{
mImpl = new Impl( 0 );
break;
}
- case Property::UNSIGNED_INTEGER:
- {
- mImpl = new Impl( 0U );
- break;
- }
case Property::VECTOR2:
{
mImpl = new Impl( Vector2::ZERO );
}
case Property::RECTANGLE:
{
- mImpl = new Impl( Rect<int>(0,0,0,0) );
+ mImpl = new Impl( Rect<int32_t>(0,0,0,0) );
break;
}
case Property::ROTATION:
{
- mImpl = new Impl( Quaternion() );
+ mImpl = new Impl( AngleAxis() );
break;
}
case Property::STRING:
mImpl = new Impl( Property::Map() );
break;
}
+ case Property::EXTENTS:
+ {
+ mImpl = new Impl( Extents() );
+ break;
+ }
case Property::NONE:
{
- mImpl = new Impl();
+ // No need to create an Impl
break;
}
}
}
+
Property::Value::Value( const Property::Value& value )
-: mImpl( NULL )
+: mImpl( nullptr )
{
// reuse assignment operator
operator=( value );
}
+Property::Value::Value( Property::Value&& value )
+: mImpl( value.mImpl )
+{
+ value.mImpl = nullptr;
+}
+
Property::Value& Property::Value::operator=( const Property::Value& value )
{
if ( this == &value )
if( !value.mImpl )
{
delete mImpl;
- mImpl = NULL;
+ mImpl = nullptr;
return *this;
}
// first check if the type is the same, no need to change impl, just assign
mImpl->integerValue = value.mImpl->integerValue;
break;
}
- case Property::UNSIGNED_INTEGER:
- {
- mImpl->unsignedIntegerValue = value.mImpl->unsignedIntegerValue;
- break;
- }
case Property::VECTOR2:
{
*mImpl->vector2Value = *value.mImpl->vector2Value; // type cannot change in mImpl so vector is allocated
}
case Property::ROTATION:
{
- *mImpl->quaternionValue = *value.mImpl->quaternionValue; // type cannot change in mImpl so quaternion is allocated
+ *mImpl->angleAxisValue = *value.mImpl->angleAxisValue; // type cannot change in mImpl so quaternion is allocated
break;
}
case Property::STRING:
*mImpl->mapValue = *value.mImpl->mapValue; // type cannot change in mImpl so map is allocated
break;
}
+ case Property::EXTENTS:
+ {
+ *mImpl->extentsValue = *value.mImpl->extentsValue; // type cannot change in mImpl so extents is allocated
+ break;
+ }
case Property::NONE:
- { // mImpl will be NULL, there's no way to get to this case
+ { // mImpl will be a nullptr, there's no way to get to this case
}
}
}
else
{
// different type, release old impl and create new
- Impl* newImpl( NULL );
+ Impl* newImpl( nullptr );
switch ( value.mImpl->type )
{
case Property::BOOLEAN:
newImpl = new Impl( value.mImpl->integerValue );
break;
}
- case Property::UNSIGNED_INTEGER:
- {
- newImpl = new Impl( value.mImpl->unsignedIntegerValue );
- break;
- }
case Property::VECTOR2:
{
newImpl = new Impl( *value.mImpl->vector2Value ); // type cannot change in mImpl so vector is allocated
}
case Property::ROTATION:
{
- newImpl = new Impl( *value.mImpl->quaternionValue ); // type cannot change in mImpl so quaternion is allocated
+ newImpl = new Impl( *value.mImpl->angleAxisValue ); // type cannot change in mImpl so quaternion is allocated
break;
}
case Property::MATRIX3:
newImpl = new Impl( *value.mImpl->mapValue ); // type cannot change in mImpl so map is allocated
break;
}
+ case Property::EXTENTS:
+ {
+ newImpl = new Impl( *value.mImpl->extentsValue ); // type cannot change in mImpl so extents is allocated
+ break;
+ }
case Property::NONE:
- { // NULL value will be used for "empty" value
+ { // nullptr value will be used for "empty" value
}
}
delete mImpl;
return *this;
}
+Property::Value& Property::Value::operator=( Property::Value&& value )
+{
+ if( this != &value )
+ {
+ delete mImpl;
+ mImpl = value.mImpl;
+ value.mImpl = nullptr;
+ }
+
+ return *this;
+}
+
Property::Value::~Value()
{
delete mImpl;
return converted;
}
-bool Property::Value::Get( int& integerValue ) const
+bool Property::Value::Get( int32_t& integerValue ) const
{
bool converted = false;
if( mImpl )
}
else if( mImpl->type == FLOAT )
{
- integerValue = static_cast< int >( mImpl->floatValue );
+ integerValue = static_cast< int32_t >( mImpl->floatValue );
converted = true;
}
}
return converted;
}
-bool Property::Value::Get( unsigned int& unsignedIntegerValue ) const
-{
- bool converted = false;
- if( mImpl && IsIntegerType( mImpl->type ) )
- {
- unsignedIntegerValue = mImpl->unsignedIntegerValue;
- converted = true;
- }
- return converted;
-}
-
bool Property::Value::Get( Vector2& vectorValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == VECTOR2) ) // type cannot change in mImpl so vector is allocated
+ if( mImpl )
{
- vectorValue = *(mImpl->vector2Value);
- converted = true;
+ // type cannot change in mImpl so vector is allocated
+ if( mImpl->type == VECTOR2 || mImpl->type == VECTOR3 || mImpl->type == VECTOR4 )
+ {
+ vectorValue = *(mImpl->vector2Value); // if Vector3 or 4 only x and y are assigned
+ converted = true;
+ }
}
return converted;
}
bool Property::Value::Get( Vector3& vectorValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == VECTOR3) ) // type cannot change in mImpl so vector is allocated
+ if( mImpl )
{
- vectorValue = *(mImpl->vector3Value);
- converted = true;
+ // type cannot change in mImpl so vector is allocated
+ if ( mImpl->type == VECTOR3 || mImpl->type == VECTOR4 )
+ {
+ vectorValue = *(mImpl->vector3Value); // if Vector4 only x,y,z are assigned
+ converted = true;
+ }
+ else if( mImpl->type == VECTOR2 )
+ {
+ vectorValue = *(mImpl->vector2Value);
+ converted = true;
+ }
}
return converted;
}
bool Property::Value::Get( Vector4& vectorValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == VECTOR4) ) // type cannot change in mImpl so vector is allocated
+ if( mImpl )
{
- vectorValue = *(mImpl->vector4Value);
- converted = true;
+ if( mImpl->type == VECTOR4 ) // type cannot change in mImpl so vector is allocated
+ {
+ vectorValue = *(mImpl->vector4Value);
+ converted = true;
+ }
+ else if( mImpl->type == VECTOR2 )
+ {
+ vectorValue = *(mImpl->vector2Value);
+ converted = true;
+ }
+ else if( mImpl->type == VECTOR3 )
+ {
+ vectorValue = *(mImpl->vector3Value);
+ converted = true;
+ }
}
return converted;
}
return converted;
}
-bool Property::Value::Get( Rect<int>& rectValue ) const
+bool Property::Value::Get( Rect<int32_t>& rectValue ) const
{
bool converted = false;
if( mImpl && (mImpl->type == RECTANGLE) ) // type cannot change in mImpl so rect is allocated
bool Property::Value::Get( AngleAxis& angleAxisValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so quaternion is allocated
+ if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
{
- mImpl->quaternionValue->ToAxisAngle( angleAxisValue.axis, angleAxisValue.angle );
+ angleAxisValue = *(mImpl->angleAxisValue);
converted = true;
}
return converted;
bool Property::Value::Get( Quaternion& quaternionValue ) const
{
bool converted = false;
- if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so quaternion is allocated
+ if( mImpl && (mImpl->type == ROTATION) ) // type cannot change in mImpl so angleAxis is allocated
{
- quaternionValue = *(mImpl->quaternionValue);
+ quaternionValue = Quaternion(mImpl->angleAxisValue->angle, mImpl->angleAxisValue->axis );
converted = true;
}
return converted;
Property::Array* Property::Value::GetArray() const
{
- Property::Array* array = NULL;
+ Property::Array* array = nullptr;
if( mImpl && (mImpl->type == ARRAY) ) // type cannot change in mImpl so array is allocated
{
array = mImpl->arrayValue;
Property::Map* Property::Value::GetMap() const
{
- Property::Map* map = NULL;
+ Property::Map* map = nullptr;
if( mImpl && (mImpl->type == MAP) ) // type cannot change in mImpl so map is allocated
{
map = mImpl->mapValue;
return map;
}
+bool Property::Value::Get( Extents& extentsValue ) const
+{
+ bool converted = false;
+ if( mImpl )
+ {
+ if( mImpl->type == EXTENTS )
+ {
+ extentsValue = *(mImpl->extentsValue);
+ converted = true;
+ }
+ else if( mImpl->type == VECTOR4 )
+ {
+ extentsValue.start = static_cast< uint16_t >( mImpl->vector4Value->x );
+ extentsValue.end = static_cast< uint16_t >( mImpl->vector4Value->y );
+ extentsValue.top = static_cast< uint16_t >( mImpl->vector4Value->z );
+ extentsValue.bottom = static_cast< uint16_t >( mImpl->vector4Value->w );
+ converted = true;
+ }
+ }
+ return converted;
+}
+
std::ostream& operator<<( std::ostream& stream, const Property::Value& value )
{
if( value.mImpl )
stream << impl.integerValue;
break;
}
- case Dali::Property::UNSIGNED_INTEGER:
- {
- stream << impl.unsignedIntegerValue;
- break;
- }
case Dali::Property::VECTOR2:
{
stream << *impl.vector2Value;
}
case Dali::Property::ROTATION:
{
- stream << *impl.quaternionValue;
+ stream << *impl.angleAxisValue;
break;
}
case Dali::Property::STRING:
}
case Dali::Property::ARRAY:
{
- stream << "Array containing" << impl.arrayValue->Count() << " elements"; // TODO add ostream<< operator in array
+ stream << *(value.GetArray());
break;
}
case Dali::Property::MAP:
{
- stream << "Map containing " << impl.mapValue->Count() << " elements"; // TODO add ostream<< operator in map
+ stream << *(value.GetMap());
break;
}
- case Dali::Property::NONE:
+ case Dali::Property::EXTENTS:
{
- stream << "undefined type";
+ stream << *impl.extentsValue;
break;
}
+ case Dali::Property::NONE:
+ { // mImpl will be a nullptr, there's no way to get to this case
+ }
}
}
else
{
- stream << "empty type";
+ stream << "undefined type";
}
return stream;
}