summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-06-25 19:11:23 +0900
committerJaehyun Cho <jae_hyun.cho@samsung.com>2019-06-25 19:11:23 +0900
commit907bdad065aac9676613ed49e5aedfd7f9052b27 (patch)
tree749b3009f1048860be52c3375b2147aff7f90061
parent0a0f3d5bfe167d1cb31127f066e1e4af3ef0a563 (diff)
efl-mono: Add object type support for Eina.Value
Summary: C# `Eina.Value` now has builtin support for `EINA_VALUE_TYPE_OBJECT`. To avoid ambiguity with the `Set` method overloads, explicit casting operators were used for wrapping/unwrapping `Efl.Object` instead of implicit ones like for other value types. Thus, to initialize an `Eina.Value` from an object, you can use the following: `var v = (Eina.Value)myObj;` Reviewers: felipealmeida, vitor.sousa, segfaultxavi, Jaehyun_Cho Reviewed By: Jaehyun_Cho Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9164
-rw-r--r--src/bindings/mono/eina_mono/eina_value.cs114
-rw-r--r--src/lib/efl_mono/efl_custom_exports_mono.c3
-rw-r--r--src/tests/efl_mono/Value.cs80
3 files changed, 197 insertions, 0 deletions
diff --git a/src/bindings/mono/eina_mono/eina_value.cs b/src/bindings/mono/eina_mono/eina_value.cs
index 627c7cb343..99cf09757d 100644
--- a/src/bindings/mono/eina_mono/eina_value.cs
+++ b/src/bindings/mono/eina_mono/eina_value.cs
@@ -184,6 +184,10 @@ static internal class UnsafeNativeMethods
184 184
185 [DllImport(efl.Libs.CustomExports)] 185 [DllImport(efl.Libs.CustomExports)]
186 [return: MarshalAsAttribute(UnmanagedType.U1)] 186 [return: MarshalAsAttribute(UnmanagedType.U1)]
187 internal static extern bool eina_value_container_append_wrapper_ptr(IntPtr handle, IntPtr data);
188
189 [DllImport(efl.Libs.CustomExports)]
190 [return: MarshalAsAttribute(UnmanagedType.U1)]
187 internal static extern bool eina_value_container_append_wrapper_char(IntPtr handle, sbyte data); 191 internal static extern bool eina_value_container_append_wrapper_char(IntPtr handle, sbyte data);
188 192
189 [DllImport(efl.Libs.CustomExports)] 193 [DllImport(efl.Libs.CustomExports)]
@@ -280,6 +284,10 @@ static internal class UnsafeNativeMethods
280 284
281 [DllImport(efl.Libs.CustomExports)] 285 [DllImport(efl.Libs.CustomExports)]
282 [return: MarshalAsAttribute(UnmanagedType.U1)] 286 [return: MarshalAsAttribute(UnmanagedType.U1)]
287 internal static extern bool eina_value_container_set_wrapper_ptr(IntPtr handle, int index, IntPtr value);
288
289 [DllImport(efl.Libs.CustomExports)]
290 [return: MarshalAsAttribute(UnmanagedType.U1)]
283 internal static extern bool eina_value_container_set_wrapper_uchar(IntPtr handle, int index, byte value); 291 internal static extern bool eina_value_container_set_wrapper_uchar(IntPtr handle, int index, byte value);
284 292
285 [DllImport(efl.Libs.CustomExports)] 293 [DllImport(efl.Libs.CustomExports)]
@@ -380,6 +388,10 @@ static internal class UnsafeNativeMethods
380 388
381 [DllImport(efl.Libs.Eina)] 389 [DllImport(efl.Libs.Eina)]
382 [return: MarshalAsAttribute(UnmanagedType.U1)] 390 [return: MarshalAsAttribute(UnmanagedType.U1)]
391 internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, ref IntPtr value);
392
393 [DllImport(efl.Libs.Eina)]
394 [return: MarshalAsAttribute(UnmanagedType.U1)]
383 internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, IntPtr value); 395 internal static extern bool eina_value_optional_pset(IntPtr handle, IntPtr subtype, IntPtr value);
384 396
385 [DllImport(efl.Libs.Eina)] 397 [DllImport(efl.Libs.Eina)]
@@ -507,6 +519,10 @@ static internal class UnsafeNativeMethods
507 // Error 519 // Error
508 [DllImport(efl.Libs.CustomExports)] 520 [DllImport(efl.Libs.CustomExports)]
509 internal static extern IntPtr type_error(); 521 internal static extern IntPtr type_error();
522
523 // Error
524 [DllImport(efl.Libs.CustomExports)]
525 internal static extern IntPtr type_object();
510} 526}
511} 527}
512 528
@@ -613,6 +629,7 @@ public enum ValueType
613 Optional, 629 Optional,
614 /// <summary>Error values.</summary> 630 /// <summary>Error values.</summary>
615 Error, 631 Error,
632 Object,
616 /// <summary>Empty values.</summary> 633 /// <summary>Empty values.</summary>
617 Empty, 634 Empty,
618} 635}
@@ -675,6 +692,11 @@ static class ValueTypeMethods
675 return val == ValueType.Error; 692 return val == ValueType.Error;
676 } 693 }
677 694
695 public static bool IsObject(this ValueType val)
696 {
697 return val == ValueType.Object;
698 }
699
678 /// <summary>Returns the Marshal.SizeOf for the given ValueType native structure.</summary> 700 /// <summary>Returns the Marshal.SizeOf for the given ValueType native structure.</summary>
679 public static int MarshalSizeOf(this ValueType val) 701 public static int MarshalSizeOf(this ValueType val)
680 { 702 {
@@ -771,6 +793,9 @@ static class ValueTypeBridge
771 ManagedToNative.Add(ValueType.Error, type_error()); 793 ManagedToNative.Add(ValueType.Error, type_error());
772 NativeToManaged.Add(type_error(), ValueType.Error); 794 NativeToManaged.Add(type_error(), ValueType.Error);
773 795
796 ManagedToNative.Add(ValueType.Object, type_object());
797 NativeToManaged.Add(type_object(), ValueType.Object);
798
774 ManagedToNative.Add(ValueType.Empty, IntPtr.Zero); 799 ManagedToNative.Add(ValueType.Empty, IntPtr.Zero);
775 NativeToManaged.Add(IntPtr.Zero, ValueType.Empty); 800 NativeToManaged.Add(IntPtr.Zero, ValueType.Empty);
776 801
@@ -1354,6 +1379,32 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
1354 return b; 1379 return b;
1355 } 1380 }
1356 1381
1382 // Efl.Object conversions are made explicit to avoid ambiguity between
1383 // Set(Efl.Object) and Set(Value) when dealing with classes derived from
1384 // Efl.Object.
1385 /// <summary>Explicit conversion from EFL objects.</summary>
1386 public static explicit operator Value(Efl.Object obj)
1387 {
1388 var v = new Eina.Value(ValueType.Object);
1389 if (!v.Set(obj))
1390 {
1391 throw new InvalidOperationException("Couldn't set value.");
1392 }
1393 return v;
1394 }
1395
1396 /// <summary>Explicit conversion from Value to Efl.Objects.</summary>
1397 public static explicit operator Efl.Object(Value v)
1398 {
1399 Efl.Object obj;
1400 if (!v.Get(out obj))
1401 {
1402 throw new InvalidOperationException("Couldn't get value.");
1403 }
1404
1405 return obj;
1406 }
1407
1357 /// <summary>Creates an Value instance from a given array description.</summary> 1408 /// <summary>Creates an Value instance from a given array description.</summary>
1358 private static Value FromArrayDesc(Eina.EinaNative.Value_Array arrayDesc) 1409 private static Value FromArrayDesc(Eina.EinaNative.Value_Array arrayDesc)
1359 { 1410 {
@@ -1789,6 +1840,22 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
1789 return eina_value_set_wrapper_int(this.Handle, error_code); 1840 return eina_value_set_wrapper_int(this.Handle, error_code);
1790 } 1841 }
1791 1842
1843 /// <summary>Stores the given object.</summary>
1844 public bool Set(Efl.Object value)
1845 {
1846 // FIXME Implement me
1847 SanityChecks();
1848
1849 if (this.Optional)
1850 {
1851 IntPtr ptr = value.NativeHandle;
1852 return eina_value_optional_pset(this.Handle,
1853 ValueTypeBridge.GetNative(ValueType.Object),
1854 ref ptr);
1855 }
1856 return eina_value_set_wrapper_ptr(this.Handle, value.NativeHandle);
1857 }
1858
1792 /// <summary>Stores the given value into this value. The target value must be an optional.</summary> 1859 /// <summary>Stores the given value into this value. The target value must be an optional.</summary>
1793 public bool Set(Value value) 1860 public bool Set(Value value)
1794 { 1861 {
@@ -2017,6 +2084,36 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
2017 return ret; 2084 return ret;
2018 } 2085 }
2019 2086
2087 /// <summary>Gets the currently stored value as an <see cref="Efl.Object"/>.</summary>
2088 public bool Get(out Efl.Object obj)
2089 {
2090 // FIXME Implement me
2091 SanityChecks();
2092 IntPtr ptr;
2093 bool ret;
2094
2095 if (this.Optional)
2096 {
2097 ret = eina_value_optional_pget(this.Handle, out ptr);
2098 }
2099 else
2100 {
2101 ret = eina_value_get_wrapper(this.Handle, out ptr);
2102 }
2103
2104 if (ret)
2105 {
2106 obj = (Efl.Object) Efl.Eo.Globals.CreateWrapperFor(ptr);
2107 }
2108 else
2109 {
2110 obj = null;
2111 }
2112
2113 return ret;
2114 }
2115
2116
2020 /// <summary>Gets the currently stored value as an complex (e.g. container) Eina.Value.</summary> 2117 /// <summary>Gets the currently stored value as an complex (e.g. container) Eina.Value.</summary>
2021 public bool Get(out Value value) 2118 public bool Get(out Value value)
2022 { 2119 {
@@ -2281,6 +2378,11 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
2281 string x = Convert.ToString(o); 2378 string x = Convert.ToString(o);
2282 return eina_value_container_append_wrapper_string(this.Handle, x); 2379 return eina_value_container_append_wrapper_string(this.Handle, x);
2283 } 2380 }
2381 case ValueType.Object:
2382 {
2383 var x = (Efl.Object) o;
2384 return eina_value_container_append_wrapper_ptr(this.Handle, x.NativeHandle);
2385 }
2284 } 2386 }
2285 2387
2286 return false; 2388 return false;
@@ -2374,6 +2476,12 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
2374 eina_value_container_get_wrapper(this.Handle, i, out ptr); 2476 eina_value_container_get_wrapper(this.Handle, i, out ptr);
2375 return Eina.StringConversion.NativeUtf8ToManagedString(ptr); 2477 return Eina.StringConversion.NativeUtf8ToManagedString(ptr);
2376 } 2478 }
2479 case ValueType.Object:
2480 {
2481 IntPtr ptr = IntPtr.Zero;
2482 eina_value_container_get_wrapper(this.Handle, i, out ptr);
2483 return Efl.Eo.Globals.CreateWrapperFor(ptr);
2484 }
2377 2485
2378 default: 2486 default:
2379 throw new InvalidOperationException("Subtype not supported."); 2487 throw new InvalidOperationException("Subtype not supported.");
@@ -2463,6 +2571,12 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
2463 eina_value_container_set_wrapper_string(this.Handle, i, x); 2571 eina_value_container_set_wrapper_string(this.Handle, i, x);
2464 break; 2572 break;
2465 } 2573 }
2574 case ValueType.Object:
2575 {
2576 Efl.Object x = (Efl.Object)value;
2577 eina_value_container_set_wrapper_ptr(this.Handle, i, x.NativeHandle);
2578 break;
2579 }
2466 } 2580 }
2467 } 2581 }
2468 } 2582 }
diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c
index 55f0054da0..ad74babe52 100644
--- a/src/lib/efl_mono/efl_custom_exports_mono.c
+++ b/src/lib/efl_mono/efl_custom_exports_mono.c
@@ -403,6 +403,9 @@ EAPI const Eina_Value_Type *type_list() {
403EAPI const Eina_Value_Type *type_error() { 403EAPI const Eina_Value_Type *type_error() {
404 return EINA_VALUE_TYPE_ERROR; 404 return EINA_VALUE_TYPE_ERROR;
405} 405}
406EAPI const Eina_Value_Type *type_object() {
407 return EINA_VALUE_TYPE_OBJECT;
408}
406 409
407EAPI const Eina_Value_Type *type_optional() { 410EAPI const Eina_Value_Type *type_optional() {
408 return EINA_VALUE_TYPE_OPTIONAL; 411 return EINA_VALUE_TYPE_OPTIONAL;
diff --git a/src/tests/efl_mono/Value.cs b/src/tests/efl_mono/Value.cs
index 2c5e3115f0..75b8e96ca1 100644
--- a/src/tests/efl_mono/Value.cs
+++ b/src/tests/efl_mono/Value.cs
@@ -146,6 +146,31 @@ public static class TestEinaValue {
146 } 146 }
147 } 147 }
148 148
149 public static void TestObjectSimple()
150 {
151 using (Eina.Value v = new Eina.Value(Eina.ValueType.Object))
152 {
153 var obj = new Dummy.TestObject();
154 Test.Assert(v.Set(obj));
155 Efl.Object target;
156 Test.Assert(v.Get(out target));
157 Test.AssertEquals(target, obj);
158 }
159 }
160
161 // Efl.Object conversions are made explicit to avoid ambiguity between
162 // Set(Efl.Object) and Set(Value) when dealing with classes derived from
163 // Efl.Object.
164 public static void TestObjectImplicit()
165 {
166 var obj = new Dummy.TestObject();
167 var v = (Eina.Value)obj;
168 Test.AssertEquals(v.GetValueType(), Eina.ValueType.Object);
169 Efl.Object target = (Efl.Object)v;
170
171 Test.AssertEquals(target, obj);
172 }
173
149 public static void TestSetWrongType() 174 public static void TestSetWrongType()
150 { 175 {
151 using (Eina.Value v = new Eina.Value(Eina.ValueType.String)) { 176 using (Eina.Value v = new Eina.Value(Eina.ValueType.String)) {
@@ -259,6 +284,37 @@ public static class TestEinaValue {
259 Test.AssertEquals(expected, actual); 284 Test.AssertEquals(expected, actual);
260 } 285 }
261 } 286 }
287
288 public static void TestValueOptionalObject()
289 {
290 using (Eina.Value a = new Eina.Value(Eina.ValueType.Object)) {
291 Test.Assert(!a.Optional);
292 BoolRet dummy = () => a.OptionalEmpty;
293 Test.AssertRaises<Eina.InvalidValueTypeException>(() => dummy());
294 }
295
296 using (Eina.Value a = new Eina.Value(Eina.ValueType.Optional)) {
297 Test.Assert(a.Optional);
298 Test.Assert(a.OptionalEmpty); // By default, optional values are empty
299
300 // Sets expectation
301 Efl.Object expected = new Dummy.TestObject();
302 Test.Assert(a.Set(expected));
303 Test.Assert(a.Optional);
304 Test.Assert(!a.OptionalEmpty);
305
306 Test.Assert(a.Reset());
307 Test.Assert(a.OptionalEmpty);
308
309 Test.Assert(a.Set(expected));
310 Test.Assert(!a.OptionalEmpty);
311
312 Efl.Object received = null;
313 Test.Assert(a.Get(out received));
314 Test.AssertEquals(expected, received);
315 }
316 }
317
262 public static void TestValueOptionalArrays() 318 public static void TestValueOptionalArrays()
263 { 319 {
264 using (Eina.Value a = new Eina.Value(Eina.ValueType.Optional)) 320 using (Eina.Value a = new Eina.Value(Eina.ValueType.Optional))
@@ -763,6 +819,30 @@ public static class TestEinaValue {
763 } 819 }
764 } 820 }
765 821
822 public static void TestValueArrayOfObjects()
823 {
824
825 using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Object)) {
826
827 var a = new Dummy.TestObject();
828 var b = new Dummy.TestObject();
829
830 Test.Assert(array.Append(a));
831 Test.Assert(array.Append(b));
832
833 Test.AssertEquals((Efl.Object)array[0], a);
834 Test.AssertEquals((Efl.Object)array[1], b);
835
836 var c = new Dummy.TestObject();
837 array[0] = c;
838 array[1] = b;
839
840 Test.AssertEquals((Efl.Object)array[0], c);
841 Test.AssertEquals((Efl.Object)array[1], b);
842 }
843 }
844
845
766 public static void TestArrayOutOfBounds() { 846 public static void TestArrayOutOfBounds() {
767 using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Int32)) { 847 using(Eina.Value array = new Eina.Value(Eina.ValueType.Array, Eina.ValueType.Int32)) {
768 object placeholder = null; 848 object placeholder = null;