csharp: Allow improved cbs in eina comparators

Summary:
Instead of receiving a callback that compares two intptrs (which is
still used internally), expose a more C#-friendly delegate which is
wrapped into the native one.

Test Plan: run test suite

Reviewers: felipealmeida, segfaultxavi, brunobelo

Reviewed By: felipealmeida

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D10253
This commit is contained in:
Lauro Moura 2019-09-30 23:08:44 -03:00 committed by Felipe Magno de Almeida
parent 16e21c3314
commit 74e79b5ae2
5 changed files with 64 additions and 10 deletions

View File

@ -10,7 +10,7 @@ namespace Eina
namespace Callbacks
{
public delegate int EinaCompareCb(IntPtr data1, IntPtr data2);
internal delegate int EinaCompareCb(IntPtr data1, IntPtr data2);
public delegate void EinaFreeCb(IntPtr data);
}

View File

@ -494,7 +494,7 @@ public class EflObjectElementTraits<T> : IBaseElementTraits<T>
public abstract class PrimitiveElementTraits<T>
{
private Eina_Compare_Cb dlgt = null;
private Eina.Callbacks.EinaCompareCb dlgt = null;
public IntPtr ManagedToNativeAlloc(T man)
{
@ -571,7 +571,7 @@ public abstract class PrimitiveElementTraits<T>
{
if (dlgt == null)
{
dlgt = new Eina_Compare_Cb(PrimitiveCompareCb);
dlgt = new Eina.Callbacks.EinaCompareCb(PrimitiveCompareCb);
}
return Marshal.GetFunctionPointerForDelegate(dlgt);

View File

@ -110,6 +110,10 @@ public class List<T> : IEnumerable<T>, IDisposable
public bool Own {get;set;}
public bool OwnContent {get;set;}
/// <summary>Delegate for comparing two elements of this list.</summary>
/// <returns>-1, 0 or 1 for respectively smaller, equal or larger.</returns>
public delegate int Compare(T a, T b);
public int Length
{
get { return Count(); }
@ -256,10 +260,10 @@ public class List<T> : IEnumerable<T>, IDisposable
Handle = eina_list_sorted_insert(Handle, EinaCompareCb<T>(), ele);
}
public void SortedInsert(Eina_Compare_Cb compareCb, T val)
public void SortedInsert(Compare compareCb, T val)
{
IntPtr ele = ManagedToNativeAlloc(val);
Handle = eina_list_sorted_insert(Handle, Marshal.GetFunctionPointerForDelegate(compareCb), ele);
Handle = eina_list_sorted_insert(Handle, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)), ele);
}
public void Sort(int limit = 0)
@ -267,14 +271,21 @@ public class List<T> : IEnumerable<T>, IDisposable
Handle = eina_list_sort(Handle, (uint)limit, EinaCompareCb<T>());
}
public void Sort(Eina_Compare_Cb compareCb)
public void Sort(Compare compareCb)
{
Handle = eina_list_sort(Handle, 0, Marshal.GetFunctionPointerForDelegate(compareCb));
Handle = eina_list_sort(Handle, 0, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
}
public void Sort(int limit, Eina_Compare_Cb compareCb)
public void Sort(int limit, Compare compareCb)
{
Handle = eina_list_sort(Handle, (uint)limit, Marshal.GetFunctionPointerForDelegate(compareCb));
Handle = eina_list_sort(Handle, (uint)limit, Marshal.GetFunctionPointerForDelegate(GetNativeCompareCb(compareCb)));
}
private Eina.Callbacks.EinaCompareCb GetNativeCompareCb(Compare managedCb)
{
return (IntPtr a, IntPtr b) => {
return managedCb(NativeToManaged<T>(a), NativeToManaged<T>(b));
};
}
public T Nth(int n)

View File

@ -217,6 +217,5 @@ public struct ActionData
} // namespace Efl
// Global delegates
public delegate int Eina_Compare_Cb(IntPtr a, IntPtr b);
public delegate void EinaFreeCb(IntPtr data);
public delegate void EvasSmartCb(IntPtr data, IntPtr obj, IntPtr event_info);

View File

@ -1738,6 +1738,50 @@ class TestEinaList
}
public static void sorted_insert_custom_comparer_natural()
{
var lst = new Eina.List<int>();
Eina.List<int>.Compare comparator = (int a, int b) => a - b;
lst.SortedInsert(comparator, 1);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{1}));
lst.SortedInsert(comparator, 2);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{1, 2}));
lst.SortedInsert(comparator, 3);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{1, 2, 3}));
lst.SortedInsert(comparator, -1);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{-1, 1, 2, 3}));
}
public static void sorted_insert_custom_comparer_reversed()
{
var lst = new Eina.List<int>();
Eina.List<int>.Compare comparator = (int a, int b) => b - a;
lst.SortedInsert(comparator, 1);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{1}));
lst.SortedInsert(comparator, 2);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{2, 1}));
lst.SortedInsert(comparator, 3);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{3, 2, 1}));
lst.SortedInsert(comparator, -1);
Test.Assert(lst.ToArray().SequenceEqual(new int[]{3, 2, 1, -1}));
}
public static void sorted_insert_custom_comparer_string()
{
var lst = new Eina.List<string>();
Eina.List<string>.Compare comparator = (string a, string b) => b.Length - a.Length;
lst.SortedInsert(comparator, "The");
Test.Assert(lst.ToArray().SequenceEqual(new string[]{"The"}));
lst.SortedInsert(comparator, "Quick");
Test.Assert(lst.ToArray().SequenceEqual(new string[]{"Quick","The"}));
lst.SortedInsert(comparator, "Brown");
Test.Assert(lst.ToArray().SequenceEqual(new string[]{"Brown", "Quick", "The"}));
lst.SortedInsert(comparator, "Jumped");
Test.Assert(lst.ToArray().SequenceEqual(new string[]{"Jumped","Brown", "Quick", "The"}));
}
public static void sort_int()
{
var lst = new Eina.List<int>();