Added support for C# operators on DALi handle objects 70/92970/20
authorNick Holland <nick.holland@partner.samsung.com>
Wed, 19 Oct 2016 13:34:43 +0000 (14:34 +0100)
committerRichard Huang <r.huang@samsung.com>
Fri, 21 Oct 2016 16:10:20 +0000 (09:10 -0700)
Now have the ability to do operations such as

if ( actor )  // test if the C# actor object is valid and the actor isn't just any empty handle

if ( !actor )

if ( actor && anotherActor )

if ( actor || anotherActor )

Change-Id: I31dd56e89f1d4c7d056f56b52717cef469a76afb

plugins/dali-swig/SWIG/dali-operator.i
plugins/dali-swig/examples/dali-test.cs

index f6bbe4d..894b34f 100644 (file)
  * This is because from C# we can't wrap the operator BooleanType() function
  */
 %extend Dali::BaseHandle {
-   bool IsHandleEmpty() const {
+   bool HasBody() const {
+
+     // C++ code. DALi uses Handle <-> Body design pattern.
+     // This function checks the Handle to see if it has a body attached ( possible to have empty handles).
+     // Handles in DALi can be converted into a boolean type
+     // to check if the handle has a valid body attached to it.
+     // Internally checking *$self will  checks IntrusivePtr<Dali::RefObject> mObjectHandle in BaseHandle;
      if( *$self )
      {
        return true;
        return false;
      }
     }
+
+     // Check if two handles point to the same body / ref-object.
+     bool IsEqual( const BaseHandle& rhs ) const {
+
+     // C++ code. Check if two handles reference the same implemtion
+     if( *$self == rhs)
+     {
+       return true;
+     }
+     else
+     {
+       return false;
+     }
+    }
+
 };
 
 /**
  */
 %typemap(cscode) Dali::BaseHandle %{
 
- public static bool operator true(BaseHandle  handle)
- {
-   if( handle!= null  )
-   {
-     return  handle.IsHandleEmpty();
-   }
-   else
-   {
-     return false;
-   }
- }
- public static bool operator false(BaseHandle  handle)
- {
-   return  handle.IsHandleEmpty();
- }
-%}
+  // Returns the bool value true to indicate that an operand is true and returns false otherwise.
+  public static bool operator true(BaseHandle handle)
+  {
+    // if the C# object is null, return false
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return false;
+    }
+    // returns true if the handle has a body, false otherwise
+    return handle.HasBody();
+  }
+
+  // Returns the bool false  to indicate that an operand is false and returns true otherwise.
+  public static bool operator false(BaseHandle  handle)
+  {
+    // if the C# object is null, return true
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return true;
+    }
+    return !handle.HasBody();
+  }
+
+  // Explicit conversion from Handle to bool.
+  public static explicit operator bool(BaseHandle handle)
+  {
+     // if the C# object is null, return false
+    if( BaseHandle.ReferenceEquals( handle, null ) )
+    {
+      return false;
+    }
+    // returns true if the handle has a body, false otherwise
+    return handle.HasBody();
+  }
 
+  // Equality operator
+  public static bool operator == (BaseHandle x, BaseHandle y)
+  {
+    // if the C# objects are the same return true
+    if(  BaseHandle.ReferenceEquals( x, y ) )
+    {
+      return true;
+    }
+    if ( !BaseHandle.ReferenceEquals( x, null ) && !BaseHandle.ReferenceEquals( y, null ) )
+    {
+      // drop into native code to see if both handles point to the same body
+      return x.IsEqual( y) ;
+    }
+    return false;
+
+  }
+
+  // Inequality operator. Returns Null if either operand is Null
+  public static bool operator !=(BaseHandle x, BaseHandle y)
+  {
+    return !(x==y);
+  }
+
+  // Logical AND operator for &&
+  // It's possible when doing a && this function (opBitwiseAnd) is never called due
+  // to short circuiting. E.g.
+  // If you perform x && y What actually is called is
+  // BaseHandle.op_False( x ) ? BaseHandle.op_True( x ) : BaseHandle.opTrue( BaseHandle.opBitwiseAnd(x,y) )
+  //
+  public static BaseHandle operator &(BaseHandle x, BaseHandle y)
+  {
+    if( x == y )
+    {
+      return x;
+    }
+    return null;
+  }
+
+  // Logical OR operator for ||
+  // It's possible when doing a || this function (opBitwiseOr) is never called due
+  // to short circuiting. E.g.
+  // If you perform x || y What actually is called is
+  // BaseHandle.op_True( x ) ? BaseHandle.op_True( x ) : BaseHandle.opTrue( BaseHandle.opBitwiseOr(x,y) )
+  public static BaseHandle operator |(BaseHandle x, BaseHandle y)
+  {
+    if ( !BaseHandle.ReferenceEquals( x, null ) || !BaseHandle.ReferenceEquals( y, null ) )
+    {
+       if( x.HasBody() )
+       {
+         return x;
+       }
+       if( y.HasBody() )
+       {
+         return y;
+       }
+       return null;
+    }
+    return null;
+  }
+
+  // Logical ! operator
+  public static bool operator !(BaseHandle x)
+  {
+    // if the C# object is null, return true
+    if( BaseHandle.ReferenceEquals( x, null ) )
+    {
+      return true;
+    }
+    if( x.HasBody() )
+    {
+      return false;
+    }
+    return true;
+  }
 
+%}
\ No newline at end of file
index ac4bc85..491bd95 100644 (file)
@@ -39,6 +39,9 @@ namespace MyCSharpExample
 
     public void Initialize(object source, AUIApplicationInitEventArgs e)
     {
+
+      OperatorTests();
+
       Handle handle = new Handle();
       int myPropertyIndex = handle.RegisterProperty("myProperty", new Property.Value(10.0f), Property.AccessMode.READ_WRITE);
       float myProperty = 0.0f;
@@ -162,6 +165,181 @@ namespace MyCSharpExample
       Console.WriteLine( "    Vector4 r =  " + vector4.r + ", g = " + vector4.g + ", b = " + vector4.b + ", a = " + vector4.a );
     }
 
+
+  public void OperatorTests()
+  {
+    Actor actor = new Actor();
+    Actor differentActor = new Actor();
+    Actor actorSame = actor;
+    Actor nullActor = null;
+
+      // test the true operator
+    if ( actor )
+    {
+      Console.WriteLine ("BaseHandle Operator true (actor) : test passed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator true (actor): test failed ");
+    }
+
+    Actor parent = actor.GetParent ();
+
+    if ( parent )
+    {
+      Console.WriteLine ("Handle with Empty body  :failed ");
+    }
+    else
+    {
+      Console.WriteLine ("Valid with Empty body  :passed ");
+    }
+
+    actor.Add( differentActor );
+    // here we test two different C# objects, which on the native side have the same body/ ref-object
+    if ( actor == differentActor.GetParent() )
+    {
+       Console.WriteLine ("actor == differentActor.GetParent() :passed ");
+    }
+    else
+    {
+      Console.WriteLine ("actor == differentActor.GetParent() :failed ");
+    }
+
+    if ( differentActor == differentActor.GetParent() )
+    {
+       Console.WriteLine ("differentActor == differentActor.GetParent() :failed ");
+    }
+    else
+    {
+      Console.WriteLine ("differentActor == differentActor.GetParent() :passed ");
+    }
+
+
+    if ( nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator true (nullActor) : test failed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator true (nullActor): test passed ");
+    }
+
+    // ! operator
+    if ( !actor )
+    {
+      Console.WriteLine ("BaseHandle Operator !(actor) : test failed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator !(actor): test passed ");
+    }
+
+    if ( !nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator !(nullActor) : test passed ");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator !(nullActor): test failed ");
+    }
+
+    // Note: operator false only used inside & operator
+    // test equality operator ==
+    if ( actor == actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator  (actor == actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator  (actor == actorSame) : test failed");
+    }
+
+    if ( actor == differentActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == differentActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == differentActor) : test passed");
+    }
+
+    if ( actor == nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor == nullActor) : test passed");
+    }
+
+    if ( nullActor == nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor == nullActor) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor == nullActor) : test failed");
+    }
+
+    // test || operator
+    if ( actor || actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || actorSame) : test failed");
+    }
+
+    if ( actor || nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || nullActor) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor || nullActor) : test failed");
+    }
+
+    if ( nullActor || nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor || nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor || nullActor) : test passed");
+    }
+
+
+    // test && operator
+    if ( actor && actorSame )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && actorSame) : test passed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && actorSame) : test failed");
+    }
+
+    if ( actor && nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (actor && nullActor) : test passed");
+    }
+
+    if ( nullActor && nullActor )
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor && nullActor) : test failed");
+    }
+    else
+    {
+      Console.WriteLine ("BaseHandle Operator (nullActor && nullActor) : test passed");
+    }
+
+  }
+
     public void MainLoop()
     {
       _application.MainLoop ();