vitorsousa pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=cfafd01bbe27bab90117e1a8d97fdace55b47944

commit cfafd01bbe27bab90117e1a8d97fdace55b47944
Author: Lauro Moura <lauromo...@expertisesolutions.com.br>
Date:   Fri May 18 00:50:37 2018 -0300

    efl_mono: Initial support for Accessors.
    
    Summary:
    Plain conversion to IEnumerable, which is the base of LINQ
    Depends on D6189
    
    Reviewers: felipealmeida, vitor.sousa
    
    Reviewed By: vitor.sousa
    
    Subscribers: cedric, #committers, zmike
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D6190
---
 src/Makefile_Efl_Mono.am                     |   1 +
 src/bindings/mono/eina_mono/eina_accessor.cs | 108 +++++++++++++++++++++++++++
 src/bindings/mono/eina_mono/eina_array.cs    |   8 ++
 src/bindings/mono/eina_mono/eina_inarray.cs  |   6 ++
 src/bindings/mono/eina_mono/eina_inlist.cs   |   6 ++
 src/bindings/mono/eina_mono/eina_list.cs     |   6 ++
 src/tests/efl_mono/Eina.cs                   |  71 ++++++++++++++++++
 7 files changed, 206 insertions(+)

diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index a4376c0761..41c9d225c9 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -23,6 +23,7 @@ efl_eina_mono_files = \
        bindings/mono/eina_mono/eina_error.cs \
        bindings/mono/eina_mono/eina_value.cs \
        bindings/mono/eina_mono/eina_promises.cs \
+       bindings/mono/eina_mono/eina_accessor.cs \
        bindings/mono/eina_mono/eina_strbuf.cs
 
 efl_eldbus_mono_files = \
diff --git a/src/bindings/mono/eina_mono/eina_accessor.cs 
b/src/bindings/mono/eina_mono/eina_accessor.cs
new file mode 100644
index 0000000000..eab0aebc8c
--- /dev/null
+++ b/src/bindings/mono/eina_mono/eina_accessor.cs
@@ -0,0 +1,108 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+using static eina.TraitFunctions;
+
+using static eina.AccessorNativeFunctions;
+
+namespace eina {
+
+internal class AccessorNativeFunctions
+{
+    [DllImport(efl.Libs.Eina)] [return: MarshalAs(UnmanagedType.U1)] public 
static extern bool
+        eina_accessor_data_get(IntPtr accessor, uint position, IntPtr data);
+    [DllImport(efl.Libs.Eina)] public static extern void
+        eina_accessor_free(IntPtr accessor);
+}
+
+/// <summary>Accessors provide an uniform way of accessing Eina containers, 
similar to C++ STL's and C# IEnumerable.</summary>
+public class Accessor<T> : IEnumerable<T>, IDisposable
+{
+    /// <summary>Pointer to the native accessor.</summary>
+    public IntPtr Handle { get; private set; } = IntPtr.Zero;
+
+    /// <summary>Who is in charge of releasing the resources wrapped by this 
instance.</summary>
+    private Ownership Ownership { get; set; }
+
+    /// <summary>Create a new accessor wrapping the given pointer.</summary>
+    public Accessor(IntPtr handle, Ownership owner=Ownership.Managed)
+    {
+        Handle = handle;
+        Ownership = owner;
+    }
+
+    /// <summary>Release the native resources held by this instance.</summary>
+    public void Dispose()
+    {
+        Dispose(true);
+    }
+
+    protected virtual void Dispose(bool disposing)
+    {
+        if (Ownership == Ownership.Managed && Handle != IntPtr.Zero)
+        {
+            eina_accessor_free(Handle);
+            Handle = IntPtr.Zero;
+        }
+    }
+
+    ~Accessor()
+    {
+        Dispose(false);
+    }
+
+    public virtual T Convert(IntPtr data)
+    {
+        return NativeToManaged<T>(data);
+    }
+
+    /// <summary>Returns an enumerator that iterates throught this 
accessor.</summary>
+    public IEnumerator<T> GetEnumerator()
+    {
+        if (Handle == IntPtr.Zero)
+            throw new ObjectDisposedException(base.GetType().Name);
+        IntPtr tmp = MemoryNative.Alloc(Marshal.SizeOf(typeof(IntPtr)));
+        uint position = 0;
+
+        try
+        {
+            while(eina_accessor_data_get(Handle, position, tmp))
+            {
+                IntPtr data = (IntPtr)Marshal.PtrToStructure(tmp, 
typeof(IntPtr));
+                yield return Convert(data);
+                position += 1;
+            }
+        }
+        finally
+        {
+            MemoryNative.Free(tmp);
+        }
+    }
+
+    IEnumerator IEnumerable.GetEnumerator()
+    {
+        return this.GetEnumerator();
+    }
+}
+
+public class AccessorInList<T> : Accessor<T>
+{
+    public AccessorInList(IntPtr handle, Ownership own): base(handle, own) {}
+    public override T Convert(IntPtr data)
+    {
+        return NativeToManagedInlistNode<T>(data);
+    }
+}
+
+public class AccessorInArray<T> : Accessor<T>
+{
+    public AccessorInArray(IntPtr handle, Ownership own): base(handle, own) {}
+    public override T Convert(IntPtr data)
+    {
+        return NativeToManagedInplace<T>(data);
+    }
+}
+
+}
diff --git a/src/bindings/mono/eina_mono/eina_array.cs 
b/src/bindings/mono/eina_mono/eina_array.cs
index 6156c0cbb1..86e69fc407 100644
--- a/src/bindings/mono/eina_mono/eina_array.cs
+++ b/src/bindings/mono/eina_mono/eina_array.cs
@@ -24,6 +24,8 @@ public static class ArrayNativeFunctions
 
     [DllImport(efl.Libs.Eina)] public static extern IntPtr
         eina_array_iterator_new(IntPtr array);
+    [DllImport(efl.Libs.Eina)] public static extern IntPtr
+        eina_array_accessor_new(IntPtr array);
 
     [DllImport(efl.Libs.CustomExports)] public static extern void
         eina_array_clean_custom_export_mono(IntPtr array);
@@ -288,6 +290,12 @@ public class Array<T> : IEnumerable<T>, IDisposable
     {
         return this.GetEnumerator();
     }
+
+    /// <summary> Gets an Accessor for this Array.</summary>
+    public eina.Accessor<T> GetAccessor()
+    {
+        return new eina.Accessor<T>(eina_array_accessor_new(Handle), 
Ownership.Managed);
+    }
 }
 
 }
diff --git a/src/bindings/mono/eina_mono/eina_inarray.cs 
b/src/bindings/mono/eina_mono/eina_inarray.cs
index e246af83f0..a9d3116a34 100644
--- a/src/bindings/mono/eina_mono/eina_inarray.cs
+++ b/src/bindings/mono/eina_mono/eina_inarray.cs
@@ -321,6 +321,12 @@ public class Inarray<T> : IEnumerable<T>, IDisposable
     {
         return this.GetEnumerator();
     }
+
+    /// <summary> Gets an Accessor for this Array.</summary>
+    public eina.Accessor<T> GetAccessor()
+    {
+        return new eina.AccessorInArray<T>(eina_inarray_accessor_new(Handle), 
Ownership.Managed);
+    }
 }
 
 }
diff --git a/src/bindings/mono/eina_mono/eina_inlist.cs 
b/src/bindings/mono/eina_mono/eina_inlist.cs
index 7b69924a9a..c3392a2db8 100644
--- a/src/bindings/mono/eina_mono/eina_inlist.cs
+++ b/src/bindings/mono/eina_mono/eina_inlist.cs
@@ -313,6 +313,12 @@ public class Inlist<T> : IEnumerable<T>, IDisposable
     {
         return this.GetEnumerator();
     }
+
+    /// <summary> Gets an Accessor for this List.</summary>
+    public eina.Accessor<T> GetAccessor()
+    {
+        return new eina.AccessorInList<T>(eina_inlist_accessor_new(Handle), 
Ownership.Managed);
+    }
 }
 
 }
diff --git a/src/bindings/mono/eina_mono/eina_list.cs 
b/src/bindings/mono/eina_mono/eina_list.cs
index cef766f331..e31a8ffed3 100644
--- a/src/bindings/mono/eina_mono/eina_list.cs
+++ b/src/bindings/mono/eina_mono/eina_list.cs
@@ -349,6 +349,12 @@ public class List<T> : IEnumerable<T>, IDisposable
     {
         return this.GetEnumerator();
     }
+
+    /// <summary> Gets an Accessor for this List.</summary>
+    public eina.Accessor<T> GetAccessor()
+    {
+        return new eina.Accessor<T>(eina_list_accessor_new(Handle), 
Ownership.Managed);
+    }
 }
 
 }
diff --git a/src/tests/efl_mono/Eina.cs b/src/tests/efl_mono/Eina.cs
index 9a844f5280..f1e1dc49ff 100644
--- a/src/tests/efl_mono/Eina.cs
+++ b/src/tests/efl_mono/Eina.cs
@@ -4254,4 +4254,75 @@ class TestEinaIterator
     }
 } // < TestEinaIterator
 
+
+class TestEinaAccessor
+{
+    public static void basic_accessor_list()
+    {
+        var lst = new eina.List<int>();
+        lst.Append(1);
+        lst.Append(2);
+        lst.Append(3);
+        lst.Append(4);
+
+        eina.Accessor<int> accessor = lst.GetAccessor();
+
+        var zipped = accessor.Zip(lst, (first, second) => new Tuple<int, 
int>(first, second));
+
+        foreach(Tuple<int, int> pair in zipped)
+        {
+            Test.AssertEquals(pair.Item1, pair.Item2);
+        }
+    }
+
+    public static void basic_accessor_array()
+    {
+        var arr = new eina.Array<string>();
+        arr.Append(base_seq_str);
+
+        eina.Accessor<string> accessor = arr.GetAccessor();
+
+        var zipped = accessor.Zip(arr, (first, second) => new Tuple<string, 
string>(first, second));
+
+        foreach(Tuple<string, string> pair in zipped)
+        {
+            Test.AssertEquals(pair.Item1, pair.Item2);
+        }
+    }
+
+    public static void basic_accessor_inlist()
+    {
+        var lst = new eina.Inlist<int>();
+        lst.Append(1);
+        lst.Append(2);
+        lst.Append(3);
+        lst.Append(4);
+
+        eina.Accessor<int> accessor = lst.GetAccessor();
+
+        var zipped = accessor.Zip(lst, (first, second) => new Tuple<int, 
int>(first, second));
+
+        foreach(Tuple<int, int> pair in zipped)
+        {
+            Test.AssertEquals(pair.Item1, pair.Item2);
+        }
+    }
+
+    public static void basic_accessor_inarray()
+    {
+        var arr = new eina.Inarray<int>();
+        arr.Append(base_seq_int);
+
+        eina.Accessor<int> accessor = arr.GetAccessor();
+
+        var zipped = accessor.Zip(arr, (first, second) => new Tuple<int, 
int>(first, second));
+
+        foreach(Tuple<int, int> pair in zipped)
+        {
+            Test.AssertEquals(pair.Item1, pair.Item2);
+        }
+    }
+}
+
+
 }

-- 


Reply via email to