(Scripting) Helper method for bit-mask enum properties & moved enum-string macros... 51/81851/3
authorAdeel Kazmi <adeel.kazmi@samsung.com>
Thu, 28 Jul 2016 14:19:37 +0000 (15:19 +0100)
committerAdeel Kazmi <adeel.kazmi@samsung.com>
Fri, 29 Jul 2016 12:08:26 +0000 (05:08 -0700)
Change-Id: Iec06be774d5ea9cd37db43fa7378634f0a3dee37

automated-tests/src/dali/utc-Dali-Scripting.cpp
dali/devel-api/file.list
dali/devel-api/scripting/enum-helper.h [new file with mode: 0644]
dali/devel-api/scripting/scripting.h
dali/internal/event/common/property-helper.h

index 5b4bb99..e76ff62 100644 (file)
@@ -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<int>( result ), static_cast<int>( 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<int>( result ), static_cast<int>( 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<int>( result ), static_cast<int>( 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<int>( result ), static_cast<int>( 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[] =
index c8b61c6..53c58ed 100644 (file)
@@ -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 (file)
index 0000000..89beaa4
--- /dev/null
@@ -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 <dali/devel-api/scripting/scripting.h>
+
+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
index e688435..ad4539b 100644 (file)
@@ -24,6 +24,7 @@
 #include <dali/devel-api/animation/animation-data.h>
 #include <dali/public-api/images/image.h>
 #include <dali/public-api/shader-effects/shader-effect.h>
+#include <dali/public-api/object/property-array.h>
 #include <dali/public-api/object/property-map.h>
 #include <dali/public-api/object/property-value.h>
 
@@ -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<T>( newValue ) ) )
+      {
+        result = static_cast<T>( 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.
index a3a4cd5..0fa0a47 100644 (file)
@@ -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 <dali/integration-api/bitmap.h>
-#include <dali/devel-api/scripting/scripting.h>
+#include <dali/devel-api/scripting/enum-helper.h>
 
 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