forked from enlightenment/efl
csharp: Add marshal support for Eina.ValueType
Summary: It uses a custom marshaler and a helper boxing class to convert between the managed enum values and the native Eina_Value_Type pointers. To be used by future MVVM machinery. Reviewers: vitor.sousa, felipealmeida Reviewed By: vitor.sousa Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D9443
This commit is contained in:
parent
1530d0386c
commit
29d24aa409
|
@ -82,6 +82,9 @@ struct marshall_annotation_visitor_generate
|
|||
{"strbuf", false, [&] {
|
||||
return "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
|
||||
}},
|
||||
{"Value_Type", false, [&] {
|
||||
return "[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueTypeMarshaler))]";
|
||||
}},
|
||||
};
|
||||
match const return_match_table[] =
|
||||
{
|
||||
|
@ -117,6 +120,9 @@ struct marshall_annotation_visitor_generate
|
|||
{"strbuf", false, [&] {
|
||||
return "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Efl.Eo.StrbufKeepOwnershipMarshaler))]";
|
||||
}},
|
||||
{"Value_Type", false, [&] {
|
||||
return "[return: MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef=typeof(Eina.ValueTypeMarshaler))]";
|
||||
}},
|
||||
};
|
||||
|
||||
if(eina::optional<bool> b = call_annotation_match
|
||||
|
|
|
@ -161,6 +161,13 @@ struct marshall_type_visitor_generate
|
|||
r.base_type = "void";
|
||||
return r;
|
||||
}}
|
||||
, {"Value_Type", nullptr, [&]
|
||||
{
|
||||
regular_type_def r = regular;
|
||||
r.namespaces.clear();
|
||||
r.base_type = "Eina.ValueTypeBox";
|
||||
return r;
|
||||
}}
|
||||
};
|
||||
|
||||
if (regular.is_struct() && !blacklist::is_struct_blacklisted(regular) && !(bool)(regular.base_qualifier & qualifier_info::is_own))
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#define CODE_ANALYSIS
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Collections.Generic;
|
||||
|
@ -515,6 +516,8 @@ static internal class UnsafeNativeMethods
|
|||
internal static extern IntPtr type_array();
|
||||
[DllImport(efl.Libs.CustomExports)]
|
||||
internal static extern IntPtr type_list();
|
||||
[DllImport(efl.Libs.CustomExports)]
|
||||
internal static extern IntPtr type_hash();
|
||||
|
||||
// Optional
|
||||
[DllImport(efl.Libs.CustomExports)]
|
||||
|
@ -716,6 +719,39 @@ static class ValueTypeMethods
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>Boxing class for custom marshalling of ValueType enums.
|
||||
///
|
||||
/// <para>As custom marshalling of enums (and other value types) is not supported, use
|
||||
/// use this boxing class as an intermediate at the Marshalling API level (like in
|
||||
/// marshall_type_impl.hh in the generator). User-facing API still uses Eina.ValueType
|
||||
/// normally.</para>
|
||||
/// </summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class ValueTypeBox
|
||||
{
|
||||
public ValueType _payload;
|
||||
|
||||
public ValueTypeBox(ValueType v)
|
||||
{
|
||||
_payload = v;
|
||||
}
|
||||
|
||||
public static implicit operator ValueTypeBox(ValueType v)
|
||||
{
|
||||
return new ValueTypeBox(v);
|
||||
}
|
||||
|
||||
public static implicit operator ValueType(ValueTypeBox box)
|
||||
{
|
||||
if (box == null)
|
||||
{
|
||||
return Eina.ValueType.Empty;
|
||||
}
|
||||
|
||||
return box._payload;
|
||||
}
|
||||
}
|
||||
|
||||
static class ValueTypeBridge
|
||||
{
|
||||
private static Dictionary<ValueType, IntPtr> ManagedToNative = new Dictionary<ValueType, IntPtr>();
|
||||
|
@ -860,6 +896,9 @@ static class ValueTypeBridge
|
|||
ManagedToNative.Add(ValueType.List, type_list());
|
||||
NativeToManaged.Add(type_list(), ValueType.List);
|
||||
|
||||
ManagedToNative.Add(ValueType.Hash, type_hash());
|
||||
NativeToManaged.Add(type_hash(), ValueType.Hash);
|
||||
|
||||
ManagedToNative.Add(ValueType.Optional, type_optional());
|
||||
NativeToManaged.Add(type_optional(), ValueType.Optional);
|
||||
|
||||
|
@ -2898,6 +2937,7 @@ public class Value : IDisposable, IComparable<Value>, IEquatable<Value>
|
|||
|
||||
/// <summary> Custom marshaler to convert value pointers to managed values and back,
|
||||
/// without changing ownership.</summary>
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public class ValueMarshaler : ICustomMarshaler
|
||||
{
|
||||
/// <summary>Creates a managed value from a C pointer, whitout taking ownership of it.</summary>
|
||||
|
@ -3000,4 +3040,49 @@ public class ValueMarshalerOwn : ICustomMarshaler
|
|||
static private ValueMarshalerOwn marshaler;
|
||||
}
|
||||
|
||||
/// <summary> Custom marshaler to convert value type pointers to managed boxed enum values
|
||||
/// and back.</summary>
|
||||
public class ValueTypeMarshaler : ICustomMarshaler
|
||||
{
|
||||
/// <summary>Creates a boxed ValueType enum value from a C pointer.</summary>
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData)
|
||||
{
|
||||
var r = ValueTypeBridge.GetManaged(pNativeData);
|
||||
return new ValueTypeBox(r);
|
||||
}
|
||||
public static Eina.ValueType vtype;
|
||||
|
||||
/// <summary>Retrieves the C pointer from a given boxed enum value type.</summary>
|
||||
public IntPtr MarshalManagedToNative(object managedObj)
|
||||
{
|
||||
ValueTypeBox v = (ValueTypeBox)managedObj;
|
||||
return ValueTypeBridge.GetNative(v);
|
||||
}
|
||||
|
||||
public void CleanUpNativeData(IntPtr pNativeData)
|
||||
{
|
||||
}
|
||||
|
||||
public void CleanUpManagedData(object managedObj)
|
||||
{
|
||||
}
|
||||
|
||||
public int GetNativeDataSize()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static ICustomMarshaler GetInstance(string cookie)
|
||||
{
|
||||
if (marshaler == null)
|
||||
{
|
||||
marshaler = new ValueTypeMarshaler();
|
||||
}
|
||||
|
||||
return marshaler;
|
||||
}
|
||||
|
||||
static private ValueTypeMarshaler marshaler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -421,6 +421,9 @@ EAPI const Eina_Value_Type *type_array() {
|
|||
EAPI const Eina_Value_Type *type_list() {
|
||||
return EINA_VALUE_TYPE_LIST;
|
||||
}
|
||||
EAPI const Eina_Value_Type *type_hash() {
|
||||
return EINA_VALUE_TYPE_HASH;
|
||||
}
|
||||
EAPI const Eina_Value_Type *type_error() {
|
||||
return EINA_VALUE_TYPE_ERROR;
|
||||
}
|
||||
|
|
|
@ -160,6 +160,17 @@ public static class TestEinaValueEolian {
|
|||
Test.AssertEquals(expected, received);
|
||||
Test.AssertEquals(Eina.ValueType.Int32, received.GetValueType());
|
||||
}
|
||||
|
||||
public static void TestEolianEinaValueTypeMarshalling()
|
||||
{
|
||||
var obj = new Dummy.TestObject();
|
||||
|
||||
var values = Enum.GetValues(typeof(Eina.ValueType));
|
||||
foreach (Eina.ValueType type in values)
|
||||
{
|
||||
Test.AssertEquals(type, obj.MirrorValueType(type));
|
||||
}
|
||||
}
|
||||
}
|
||||
#pragma warning restore 1591
|
||||
}
|
||||
|
|
|
@ -4685,6 +4685,11 @@ Efl_Object *_dummy_test_object_call_find_provider_for_iface(Eo *obj, EINA_UNUSED
|
|||
return efl_provider_find(obj, DUMMY_TEST_IFACE_INTERFACE);
|
||||
}
|
||||
|
||||
const Eina_Value_Type *_dummy_test_object_mirror_value_type(EINA_UNUSED const Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, const Eina_Value_Type *type)
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
// Inherit
|
||||
int _dummy_inherit_helper_receive_dummy_and_call_int_out(Dummy_Test_Object *x)
|
||||
{
|
||||
|
|
|
@ -1642,6 +1642,13 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
|
|||
call_find_provider_for_iface {
|
||||
return: Efl.Object;
|
||||
}
|
||||
|
||||
mirror_value_type @beta @const {
|
||||
params {
|
||||
@in type: const(ptr(Eina.Value_Type));
|
||||
}
|
||||
return: const(ptr(Eina.Value_Type));
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
|
|
Loading…
Reference in New Issue