Make MeasureCallback signature .NET friendly 65/242665/4
authorWander Lairson Costa <wander.lairson@gmail.com>
Tue, 4 Aug 2020 15:11:03 +0000 (12:11 -0300)
committerWander Lairson Costa <wander.lairson@gmail.com>
Tue, 22 Sep 2020 12:18:06 +0000 (09:18 -0300)
Currently, MeasureCallback signature has a return type of a POD 16 bytes
structure. Returning the structure by value is messing up when passing a
delegate from C# on Windows 10. The net effect is that arguments arrive
with random values. This happens because the C++ compiler may apply
optimization like RVO that the .NET runtime is not aware of.

This link [1] provides more details.

We fix the problem by making SizeTuple an out parameter and returning
void.

[1] https://www.tutorialsteacher.com/csharp/csharp-delegates

Change-Id: I71feef35908d139f60e6941b447a78b38053b89d

automated-tests/src/dali-toolkit/utc-Dali-FlexNode.cpp
dali-toolkit/devel-api/layouting/flex-node.cpp
dali-toolkit/devel-api/layouting/flex-node.h

index 93a3ac5..307c149 100644 (file)
@@ -41,15 +41,14 @@ namespace
 const Flex::SizeTuple ITEM_SIZE = Flex::SizeTuple{ 10.0f, 10.0f };
 const Flex::SizeTuple ITEM_SIZE_CALLBACK_TEST = Flex::SizeTuple{ 15.0f, 15.0f };
 
 const Flex::SizeTuple ITEM_SIZE = Flex::SizeTuple{ 10.0f, 10.0f };
 const Flex::SizeTuple ITEM_SIZE_CALLBACK_TEST = Flex::SizeTuple{ 15.0f, 15.0f };
 
-Flex::SizeTuple MeasureChild( Actor child, float width, int measureModeWidth, float height, int measureModeHeight)
+void MeasureChild( Actor child, float width, int measureModeWidth, float height, int measureModeHeight, Flex::SizeTuple *childSize)
 {
 {
-  Flex::SizeTuple childSize = ITEM_SIZE;
+  *childSize = ITEM_SIZE;
   if (child.GetProperty< std::string >( Dali::Actor::Property::NAME ) == "callbackTest")
   {
   if (child.GetProperty< std::string >( Dali::Actor::Property::NAME ) == "callbackTest")
   {
-    childSize = ITEM_SIZE_CALLBACK_TEST;
+    *childSize = ITEM_SIZE_CALLBACK_TEST;
   }
   }
-  tet_printf(" MeasureChild test callback executed (%f,%f)\n", childSize.width, childSize.height );
-  return childSize;
+  tet_printf(" MeasureChild test callback executed (%f,%f)\n", childSize->width, childSize->height );
 }
 
 }
 }
 
 }
index bdc520a..aa46e6f 100644 (file)
@@ -162,8 +162,8 @@ SizeTuple Node::MeasureNode(float width, int widthMode, float height, int height
   Toolkit::Flex::SizeTuple nodeSize{8, 8}; // Default size set to 8,8 to aid bug detection.
   if(mImpl->mMeasureCallback && mImpl->mActor.GetHandle())
   {
   Toolkit::Flex::SizeTuple nodeSize{8, 8}; // Default size set to 8,8 to aid bug detection.
   if(mImpl->mMeasureCallback && mImpl->mActor.GetHandle())
   {
-    DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode MeasureCallback executing on %s\n", mImpl->mActor.GetHandle().GetProperty<std::string>(Dali::Actor::Property::NAME).c_str());
-    nodeSize = mImpl->mMeasureCallback(mImpl->mActor.GetHandle(), width, widthMode, height, heightMode);
+    DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode MeasureCallback executing on %s\n", mImpl->mActor.GetHandle().GetProperty< std::string >( Dali::Actor::Property::NAME ).c_str());
+    mImpl->mMeasureCallback(mImpl->mActor.GetHandle(), width, widthMode, height, heightMode, &nodeSize);
   }
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode nodeSize width:%f height:%f\n", nodeSize.width, nodeSize.height);
   return nodeSize;
   }
   DALI_LOG_INFO(gLogFilter, Debug::Verbose, "MeasureNode nodeSize width:%f height:%f\n", nodeSize.width, nodeSize.height);
   return nodeSize;
index 677fab0..5a73458 100644 (file)
@@ -113,8 +113,9 @@ struct SizeTuple
  * @note int, width measure specifcation mode
  * @note float, available height for child
  * @note int, height measure specification mode
  * @note int, width measure specifcation mode
  * @note float, available height for child
  * @note int, height measure specification mode
+ * @note SizeTuple, return value
  */
  */
-using MeasureCallback = SizeTuple (*)(Dali::Actor, float, int, float, int);
+using MeasureCallback = void (*)(Dali::Actor, float , int , float , int, SizeTuple *);
 
 /**
  * This class provides the API for calling into the Flex layout implementation.
 
 /**
  * This class provides the API for calling into the Flex layout implementation.