From e8adab973c337858df33efe7ff01d3c8f56e90fc Mon Sep 17 00:00:00 2001 From: Adeel Kazmi Date: Thu, 28 Jul 2016 15:19:37 +0100 Subject: [PATCH] (Scripting) Helper method for bit-mask enum properties & moved enum-string macros to Devel API Change-Id: Iec06be774d5ea9cd37db43fa7378634f0a3dee37 --- automated-tests/src/dali/utc-Dali-Scripting.cpp | 130 +++++++++++++++++++++++- dali/devel-api/file.list | 1 + dali/devel-api/scripting/enum-helper.h | 58 +++++++++++ dali/devel-api/scripting/scripting.h | 69 ++++++++++++- dali/internal/event/common/property-helper.h | 39 +------ 5 files changed, 256 insertions(+), 41 deletions(-) create mode 100644 dali/devel-api/scripting/enum-helper.h diff --git a/automated-tests/src/dali/utc-Dali-Scripting.cpp b/automated-tests/src/dali/utc-Dali-Scripting.cpp index 5b4bb99..e76ff62 100644 --- a/automated-tests/src/dali/utc-Dali-Scripting.cpp +++ b/automated-tests/src/dali/utc-Dali-Scripting.cpp @@ -837,7 +837,7 @@ int UtcDaliScriptingGetEnumerationProperty(void) * This test function performs the following checks: * - An enum can be looked up from a Property::Value of type INTEGER. * - An enum can be looked up from a Property::Value of type STRING. - * - An enum can NOT be looked up other Property::Value types. + * - An enum can NOT be looked up for other Property::Value types. * - The return value is "true" if the property can be successfully converted AND it has changed. * - The return value is "false" if the property can be successfully converted BUT it has NOT changed. * - The return value is "false" if the property can not be successfully converted. @@ -894,7 +894,7 @@ int UtcDaliScriptingGetEnumerationProperty(void) // The result should remain the same. DALI_TEST_EQUALS( static_cast( result ), static_cast( FaceCullingMode::BACK ), TEST_LOCATION ); - // TEST: An enum can NOT be looked up other Property::Value types. + // TEST: An enum can NOT be looked up for other Property::Value types. Property::Value propertyValueBoolean( true ); returnValue = GetEnumerationProperty< FaceCullingMode::Type >( propertyValueBoolean, testTable, testTableCount, result ); @@ -910,6 +910,132 @@ int UtcDaliScriptingGetEnumerationProperty(void) END_TEST; } +int UtcDaliScriptingGetBitmaskEnumerationProperty(void) +{ + /* + * This test function performs the following checks: + * - An enum can be looked up from a Property::Value of type INTEGER. + * - An enum can be looked up from a Property::Value of type STRING. + * - An enum can NOT be looked up from other Property::Value types. + * - The return value is "true" if the property can be successfully converted AND it has changed. + * - The return value is "false" if the property can not be successfully converted. + * - The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed). + * PropertyArrays: + * - The return value when checking an array with 2 INTEGERS is "true" if the properties can be successfully converted. + * - The result value when checking an array with 2 INTEGERS is the ORd value of the 2 integers. + * - The return value when checking an array with 2 STRINGS is "true" if the properties can be successfully converted. + * - The result value when checking an array with 2 STRINGS is the ORd value of the 2 integer equivalents of the strings. + * - The return value when checking an array with an INTEGER and a STRING is "true" if the properties can be successfully converted. + * - The result value when checking an array with an INTEGER and a STRING is the ORd value of the 2 integer equivalents of the strings. + * - The return value when checking an array with an INTEGER and a Vector3 is "false" as the properties can not be successfully converted. + * - The result value when checking an array with an INTEGER and a Vector3 is unchanged. + */ + + // String to Enum property table to test with (equivalent to ones used within DALi). + const Dali::Scripting::StringEnum testTable[] = { + { "NONE", FaceCullingMode::NONE }, + { "FRONT", FaceCullingMode::FRONT }, + { "BACK", FaceCullingMode::BACK }, + { "FRONT_AND_BACK", FaceCullingMode::FRONT_AND_BACK } + }; const unsigned int testTableCount = sizeof( testTable ) / sizeof( testTable[0] ); + + // TEST: An enum can be looked up from a Property::Value of type INTEGER. + // Initialise to first element. + FaceCullingMode::Type result = FaceCullingMode::NONE; + // Set the input property value to a different value (to emulate a change). + Property::Value propertyValueInteger( FaceCullingMode::FRONT ); + + // Perform the lookup. + bool returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyValueInteger, testTable, testTableCount, result ); + + // TEST: The return value is "true" if the property can be successfully converted AND it has changed + // Check the property could be converted. + DALI_TEST_CHECK( returnValue ); + + DALI_TEST_EQUALS( static_cast( result ), static_cast( FaceCullingMode::FRONT ), TEST_LOCATION ); + + // TEST: An enum can be looked up from a Property::Value of type STRING. + // Set the input property value to a different value (to emulate a change). + Property::Value propertyValueString( "BACK" ); + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyValueString, testTable, testTableCount, result ); + + DALI_TEST_CHECK( returnValue ); + + DALI_TEST_EQUALS( static_cast( result ), static_cast( FaceCullingMode::BACK ), TEST_LOCATION ); + + // TEST: An enum can NOT be looked up from other Property::Value types. + Property::Value propertyValueVector( Vector3::ZERO ); + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyValueVector, testTable, testTableCount, result ); + + // TEST: The return value is "false" if the property can not be successfully converted. + // Return value should be false as Property::Value was of an unsupported type for enum properties. + DALI_TEST_CHECK( !returnValue ); + + // TEST: The result value is only updated if the return value is "true" (IE. successful conversion and property value has changed). + // The result should remain the same. + DALI_TEST_EQUALS( static_cast( result ), static_cast( FaceCullingMode::BACK ), TEST_LOCATION ); + + // Test PropertyArrays: + + // Property array of 2 integers. + Property::Array propertyArrayIntegers; + propertyArrayIntegers.PushBack( FaceCullingMode::FRONT ); + propertyArrayIntegers.PushBack( FaceCullingMode::BACK ); + result = FaceCullingMode::NONE; + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyArrayIntegers, testTable, testTableCount, result ); + + // TEST: The return value when checking an array with 2 INTEGERS is "true" if the properties can be successfully converted. + DALI_TEST_CHECK( returnValue ); + // TEST: The result value when checking an array with 2 INTEGERS is the ORd value of the 2 integers. + DALI_TEST_CHECK( result == ( FaceCullingMode::FRONT | FaceCullingMode::BACK ) ); + + // Property array of 2 strings. + Property::Array propertyArrayStrings; + propertyArrayStrings.PushBack( "FRONT" ); + propertyArrayStrings.PushBack( "BACK" ); + result = FaceCullingMode::NONE; + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyArrayStrings, testTable, testTableCount, result ); + + // TEST: The return value when checking an array with 2 STRINGS is "true" if the properties can be successfully converted. + DALI_TEST_CHECK( returnValue ); + // TEST: The result value when checking an array with 2 STRINGS is the ORd value of the 2 integer equivalents of the strings. + DALI_TEST_CHECK( result == ( FaceCullingMode::FRONT | FaceCullingMode::BACK ) ); + + // Property array of an int and a string. + Property::Array propertyArrayMixed; + propertyArrayMixed.PushBack( FaceCullingMode::FRONT ); + propertyArrayMixed.PushBack( "BACK" ); + result = FaceCullingMode::NONE; + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyArrayMixed, testTable, testTableCount, result ); + + // TEST: The return value when checking an array with an INTEGER and a STRING is "true" if the properties can be successfully converted. + DALI_TEST_CHECK( returnValue ); + // TEST: The result value when checking an array with an INTEGER and a STRING is the ORd value of the 2 integer equivalents of the strings. + DALI_TEST_CHECK( result == ( FaceCullingMode::FRONT | FaceCullingMode::BACK ) ); + + // Property array of an int and a string. + Property::Array propertyArrayInvalid; + propertyArrayInvalid.PushBack( FaceCullingMode::FRONT ); + propertyArrayInvalid.PushBack( Vector3::ZERO ); + + // Set the initial value to non-zero, so we can test it does not change. + result = FaceCullingMode::FRONT_AND_BACK; + + returnValue = GetBitmaskEnumerationProperty< FaceCullingMode::Type >( propertyArrayInvalid, testTable, testTableCount, result ); + + // TEST: The return value when checking an array with an INTEGER and a Vector3 is "false" as the properties can not be successfully converted. + DALI_TEST_CHECK( !returnValue ); + // TEST: The result value when checking an array with an INTEGER and a Vector3 is unchanged. + DALI_TEST_CHECK( result == FaceCullingMode::FRONT_AND_BACK ); + + END_TEST; +} + int UtcDaliScriptingFindEnumIndexN(void) { const Scripting::StringEnum myTable[] = diff --git a/dali/devel-api/file.list b/dali/devel-api/file.list index c8b61c6..53c58ed 100644 --- a/dali/devel-api/file.list +++ b/dali/devel-api/file.list @@ -44,6 +44,7 @@ devel_api_core_signals_header_files = \ $(devel_api_src_dir)/signals/signal-delegate.h devel_api_core_scripting_header_files = \ + $(devel_api_src_dir)/scripting/enum-helper.h \ $(devel_api_src_dir)/scripting/scripting.h devel_api_core_threading_header_files = \ diff --git a/dali/devel-api/scripting/enum-helper.h b/dali/devel-api/scripting/enum-helper.h new file mode 100644 index 0000000..89beaa4 --- /dev/null +++ b/dali/devel-api/scripting/enum-helper.h @@ -0,0 +1,58 @@ +#ifndef DALI_ENUM_HELPER_H +#define DALI_ENUM_HELPER_H + +/* + * Copyright (c) 2016 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +// INTERNAL INCLUDES +#include + +namespace Dali +{ + +/** + * Macros for creating value, typically enumerations, to string tables. + * Example: + * + * DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_MODE ) + * DALI_ENUM_TO_STRING( USE_OWN_SIZE ) + * DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT ) + * DALI_ENUM_TO_STRING_TABLE_END( SIZE_MODE ) + * + * Creates: + * const Scripting::StringEnum< SizeMode > SIZE_MODE_TABLE[] = { + * { "USE_OWN_SIZE", USE_OWN_SIZE }, + * { "SIZE_EQUAL_TO_PARENT", SIZE_EQUAL_TO_PARENT }, + * }; const unsigned int SIZE_MODE_TABLE_COUNT = sizeof( SIZE_MODE_TABLE ) / sizeof( SIZE_MODE_TABLE[0] ); + * + * By default, Dali::Scripting::StringEnum is used as the type for the table, however, a different type can be specified by using + * DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE. + */ +#define DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( type, t ) const type t##_TABLE[] = { +#define DALI_ENUM_TO_STRING_TABLE_BEGIN( t ) DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( Dali::Scripting::StringEnum, t ) +#define DALI_ENUM_TO_STRING_TABLE_END( t ) }; const unsigned int t##_TABLE_COUNT = sizeof( t##_TABLE ) / sizeof( t##_TABLE[0] ); +#define DALI_ENUM_TO_STRING( s ) { #s, s }, + +/** + * Adds a value, typically an enum, to the table within a scope but without the scope name + * Example converts ( Layer, LAYER_2D ) to ( "LAYER_2D", Layer::Layer2D ) + */ +#define DALI_ENUM_TO_STRING_WITH_SCOPE( className, enumName ) { #enumName, className::enumName }, + +} // namespace Dali + +#endif // DALI_ENUM_HELPER_H diff --git a/dali/devel-api/scripting/scripting.h b/dali/devel-api/scripting/scripting.h index e688435..ad4539b 100644 --- a/dali/devel-api/scripting/scripting.h +++ b/dali/devel-api/scripting/scripting.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -101,23 +102,23 @@ bool GetEnumeration( const char* value, const StringEnum* table, unsigned int ta * @brief Gets the enumeration value from an enumeration property. * An enumeration property is a property that can be set with either an INTEGER or STRING. * - * @param[in] PropertyValue The property containing the int or string value. + * @param[in] propertyValue The property containing the int or string value. * @param[in] table A pointer to an array with the enumeration to string equivalents. * @param[in] tableCount Number of items in the array. * @param[out] result The enum value. This is not modified if the enumeration could not be converted. * @return True if the value was found successfully AND the value has changed. This is to allow the caller to do nothing if there is no change. */ template< typename T > -bool GetEnumerationProperty( const Property::Value& PropertyValue, const StringEnum* table, unsigned int tableCount, T& result ) +bool GetEnumerationProperty( const Property::Value& propertyValue, const StringEnum* table, unsigned int tableCount, T& result ) { int newValue; bool set = false; - Property::Type type = PropertyValue.GetType(); + Property::Type type = propertyValue.GetType(); if( type == Property::INTEGER ) { // Attempt to fetch the property as an INTEGER type. - if( PropertyValue.Get( newValue ) ) + if( propertyValue.Get( newValue ) ) { // Success. set = true; @@ -127,7 +128,7 @@ bool GetEnumerationProperty( const Property::Value& PropertyValue, const StringE { // Attempt to fetch the property as an STRING type, and convert it from string to enumeration value. std::string propertyString; - if( table && PropertyValue.Get( propertyString ) && EnumStringToInteger( propertyString.c_str(), table, tableCount, newValue ) ) + if( table && propertyValue.Get( propertyString ) && EnumStringToInteger( propertyString.c_str(), table, tableCount, newValue ) ) { // Success. set = true; @@ -146,6 +147,64 @@ bool GetEnumerationProperty( const Property::Value& PropertyValue, const StringE } /** + * @brief Gets the enumeration value from a bitmask enumeration property. + * An enumeration property is a property that can be set with either an INTEGER, STRING or an ARRAY of STRING. + * + * @param[in] propertyValue The property containing the int, string or and array of string values. + * @param[in] table A pointer to an array with the enumeration to string equivalents. + * @param[in] tableCount Number of items in the array. + * @param[out] result The enum value. This is not modified if the enumeration could not be converted. + * @return True if the value was found successfully AND the value has changed. This is to allow the caller to do nothing if there is no change. + */ +template< typename T > +bool GetBitmaskEnumerationProperty( const Property::Value& propertyValue, const Scripting::StringEnum* table, unsigned int tableCount, T& result ) +{ + bool returnValue = true; + + // Evaluate as a single INTEGER or STRING first. + if( !GetEnumerationProperty( propertyValue, table, tableCount, result ) ) + { + // If not, then check if it's an ARRAY + if ( propertyValue.GetType() == Property::ARRAY ) + { + int newValue = 0; + Property::Array array; + propertyValue.Get( array ); + for( Property::Array::SizeType i = 0; i < array.Count(); ++i ) + { + Property::Value currentValue = array[ i ]; + // Use an initial value of -1 so any successful property conversion + // causes a change (and true to be returned). + T current = static_cast< T >( -1 ); + if( GetEnumerationProperty( currentValue, table, tableCount, current ) ) + { + newValue |= current; + } + else + { + // We hit an invalid type. + returnValue = false; + break; + } + } + + // If we didn't hit an invalid type and the value has changed, update the result. + if( returnValue && ( result != static_cast( newValue ) ) ) + { + result = static_cast( newValue ); + } + } + else + { + // Property type was not ARRAY, and the single property evaluation also failed. + returnValue = false; + } + } + + return returnValue; +} + +/** * @brief Chooses the appropriate string for the provided enumeration from the given table. * * @param[in] value The enumeration. diff --git a/dali/internal/event/common/property-helper.h b/dali/internal/event/common/property-helper.h index a3a4cd5..0fa0a47 100644 --- a/dali/internal/event/common/property-helper.h +++ b/dali/internal/event/common/property-helper.h @@ -1,8 +1,8 @@ -#ifndef __DALI_PROPERTY_HELPER_H__ -#define __DALI_PROPERTY_HELPER_H__ +#ifndef DALI_PROPERTY_HELPER_H +#define DALI_PROPERTY_HELPER_H /* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Copyright (c) 2016 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. @@ -20,7 +20,7 @@ // INTERNAL INCLUDES #include -#include +#include namespace Dali { @@ -77,35 +77,6 @@ struct PropertyDetails #endif /** - * Macros for creating value, typically enumerations, to string tables. - * Example: - * - * DALI_ENUM_TO_STRING_TABLE_BEGIN( SIZE_MODE ) - * DALI_ENUM_TO_STRING( USE_OWN_SIZE ) - * DALI_ENUM_TO_STRING( SIZE_EQUAL_TO_PARENT ) - * DALI_ENUM_TO_STRING_TABLE_END( SIZE_MODE ) - * - * Creates: - * const Scripting::StringEnum< SizeMode > SIZE_MODE_TABLE[] = { - * { "USE_OWN_SIZE", USE_OWN_SIZE }, - * { "SIZE_EQUAL_TO_PARENT", SIZE_EQUAL_TO_PARENT }, - * }; const unsigned int SIZE_MODE_TABLE_COUNT = sizeof( SIZE_MODE_TABLE ) / sizeof( SIZE_MODE_TABLE[0] ); - * - * By default, Dali::Scripting::StringEnum is used as the type for the table, however, a different type can be specified by using - * DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE. - */ -#define DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( type, t ) const type t##_TABLE[] = { -#define DALI_ENUM_TO_STRING_TABLE_BEGIN( t ) DALI_ENUM_TO_STRING_TABLE_BEGIN_WITH_TYPE( Dali::Scripting::StringEnum, t ) -#define DALI_ENUM_TO_STRING_TABLE_END( t ) }; const unsigned int t##_TABLE_COUNT = sizeof( t##_TABLE ) / sizeof( t##_TABLE[0] ); -#define DALI_ENUM_TO_STRING( s ) { #s, s }, - -/** - * Adds a value, typically an enum, to the table within a scope but without the scope name - * Example converts ( Layer, LAYER_2D ) to ( "LAYER_2D", Layer::Layer2D ) - */ -#define DALI_ENUM_TO_STRING_WITH_SCOPE( className, enumName ) { #enumName, className::enumName }, - -/** * @brief Case insensitive string comparison. * * Additionally, '-' and '_' can be used interchangeably as well. @@ -123,4 +94,4 @@ bool CompareTokens( const char * first, const char * second, size_t& size ); } // namespace Dali -#endif // __DALI_PROPERTY_HELPER_H__ +#endif // DALI_PROPERTY_HELPER_H -- 2.7.4