eina_mono: replace eina_list, eina_array with IList

This commit is contained in:
Yeongjong Lee 2019-11-20 20:17:12 +09:00
parent 954950eb44
commit 8aa48d7fe7
8 changed files with 174 additions and 117 deletions

View File

@ -131,7 +131,11 @@ struct unpack_event_args_visitor
}
bool operator()(attributes::complex_type_def const& types) const
{
if (types.outer.base_type == "iterator")
if (types.outer.base_type == "array")
return as_generator("Efl.Eo.Globals.NativeArrayTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
else if (types.outer.base_type == "list")
return as_generator("Efl.Eo.Globals.NativeListTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
else if (types.outer.base_type == "iterator")
return as_generator("Efl.Eo.Globals.IteratorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
else if (types.outer.base_type == "accessor")
return as_generator("Efl.Eo.Globals.AccessorTo" << eolian_mono::type << "(info)").generate(sink, type, *context);
@ -245,13 +249,18 @@ struct pack_event_info_and_call_visitor
bool operator()(attributes::complex_type_def const& type) const
{
auto const& indent = current_indentation(*context);
if (type.outer.base_type == "iterator")
if (type.outer.base_type == "array")
return as_generator(indent << "IntPtr info = Efl.Eo.Globals.IListToNativeArray(e.arg);\n"
<< indent << this->native_call).generate(sink, attributes::unused, *context);
else if (type.outer.base_type == "list")
return as_generator(indent << "IntPtr info = Efl.Eo.Globals.IListToNativeList(e.arg);\n"
<< indent << this->native_call).generate(sink, attributes::unused, *context);
else if (type.outer.base_type == "iterator")
return as_generator(indent << "IntPtr info = Efl.Eo.Globals.IEnumerableToIterator(e.arg);\n"
<< indent << this->native_call).generate(sink, attributes::unused, *context);
else if (type.outer.base_type == "accessor")
return as_generator(indent << "IntPtr info = Efl.Eo.Globals.IEnumerableToAccessor(e.arg);\n"
<< indent << this->native_call).generate(sink, attributes::unused, *context);
else
return as_generator(indent << "IntPtr info = e.arg.Handle;\n"
<< indent << this->native_call).generate(sink, attributes::unused, *context);

View File

@ -625,20 +625,27 @@ struct native_convert_in_variable_generator
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
|| param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
)
else if (param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
"var " << string << " = new " << type << "(" << escape_keyword(param.param_name)
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
"var " << string << " = Efl.Eo.Globals.NativeListTo" << type << "(" << escape_keyword(param.param_name)
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
"var " << string << " = Efl.Eo.Globals.NativeArrayTo" << type << "(" << escape_keyword(param.param_name)
<< ");\n"
).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context);
}
else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
@ -729,27 +736,26 @@ struct convert_in_variable_generator
).generate(sink, attributes::unused, context))
return false;
}
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *"
|| param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *"
)
else if (param.type.c_type == "Eina_Array *" || param.type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
"var " << string << " = " << escape_keyword(param.param_name) << ".Handle;\n"
"var " << string << " = " << "Efl.Eo.Globals.IListToNativeArray(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, var_name, context))
return false;
if (param.type.has_own && !as_generator(
escape_keyword(param.param_name) << ".Own = false;\n"
).generate(sink, attributes::unused, context))
}
else if (param.type.c_type == "Eina_List *" || param.type.c_type == "const Eina_List *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
&& !as_generator(
escape_keyword(param.param_name) << ".OwnContent = false;\n"
).generate(sink, attributes::unused, context))
auto var_name = in_variable_name(param.param_name);
if (!as_generator(
"var " << string << " = " << "Efl.Eo.Globals.IListToNativeList(" << escape_keyword(param.param_name) << ");\n"
).generate(sink, var_name, context))
return false;
}
else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *")
@ -996,7 +1002,17 @@ struct convert_out_assign_generator
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
)
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
return as_generator(
string << " = Efl.Eo.Globals.NativeArrayTo" << type << "(" << string
<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
else if (param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
@ -1006,9 +1022,7 @@ struct convert_out_assign_generator
if (!complex)
return false;
return as_generator(
string << " = new " << type << "(" << string
<< ", " << (param.type.has_own ? "true" : "false")
<< ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
string << " = Efl.Eo.Globals.NativeListTo" << type << "(" << string
<< ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context);
}
@ -1138,17 +1152,22 @@ struct convert_return_generator
.generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
|| ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
)
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
if (!as_generator("return new " << type << "(_ret_var, " << std::string{ret_type.has_own ? "true" : "false"}
<< ", " << (complex->subtypes.front().is_value_type || complex->subtypes.front().has_own ? "true" : "false")
<< ");\n")
.generate(sink, ret_type, context))
if (!as_generator("return Efl.Eo.Globals.NativeArrayTo" << type << "(_ret_var);")
.generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
if (!as_generator("return Efl.Eo.Globals.NativeListTo" << type << "(_ret_var);")
.generate(sink, ret_type, context))
return false;
}
else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *")
@ -1271,36 +1290,29 @@ struct native_convert_out_assign_generator
else if (param_is_acceptable(param, "Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT)
)
|| param_is_acceptable(param, "const Eina_Array *", !WANT_OWN, WANT_OUT))
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
auto outvar = out_variable_name(param.param_name);
if (!as_generator(
string << " = " << string << ".Handle;\n"
string << " = Efl.Eo.Globals.IListToNativeArray(" << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
if (param.type.has_own && !as_generator(
string << ".Own = false;\n"
).generate(sink, outvar, context))
}
else if (param_is_acceptable(param, "Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "Eina_List *", !WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", WANT_OWN, WANT_OUT)
|| param_is_acceptable(param, "const Eina_List *", !WANT_OWN, WANT_OUT))
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&param.type.original_type);
if (!complex)
return false;
// Iterators and Accessors can't own their content.
if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *"
|| param.type.c_type == "Eina_Accessor *" || param.type.c_type == "const Eina_Accessor *"
)
return true;
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
&& !as_generator(
string << ".OwnContent = false;\n"
).generate(sink, outvar, context))
auto outvar = out_variable_name(param.param_name);
if (!as_generator(
string << " = Efl.Eo.Globals.IListToNativeList(" << string << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context))
return false;
}
else if (param_is_acceptable(param, "Eina_Accessor *", WANT_OWN, WANT_OUT)
@ -1442,29 +1454,20 @@ struct native_convert_return_generator
return as_generator("return _ret_var.Handle;")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *"
|| ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *"
)
else if (ret_type.c_type == "Eina_Array *" || ret_type.c_type == "const Eina_Array *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
if (ret_type.has_own && !as_generator("_ret_var.Own = false; ")
.generate(sink, attributes::unused, context))
return as_generator("return Efl.Eo.Globals.IListToNativeArray(_ret_var);")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_List *" || ret_type.c_type == "const Eina_List *")
{
attributes::complex_type_def const* complex = efl::eina::get<attributes::complex_type_def>(&ret_type.original_type);
if (!complex)
return false;
// Iterators and Accessors can't own their content.
if (ret_type.c_type != "Eina_Iterator *" && ret_type.c_type != "const Eina_Iterator *"
&& ret_type.c_type != "Eina_Accessor *" && ret_type.c_type != "const Eina_Accessor *"
)
{
if (!complex->subtypes.front().is_value_type && complex->subtypes.front().has_own
&& !as_generator("_ret_var.OwnContent = false; ")
.generate(sink, attributes::unused, context))
return false;
}
return as_generator("return _ret_var.Handle;")
return as_generator("return Efl.Eo.Globals.IListToNativeList(_ret_var);")
.generate(sink, attributes::unused, context);
}
else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *")

View File

@ -69,6 +69,20 @@ struct to_internal_field_convert_generator
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if ((complex && (complex->outer.base_type == "array")))
{
if (!as_generator(
indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IListToNativeArray(_external_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if ((complex && (complex->outer.base_type == "list")))
{
if (!as_generator(
indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IListToNativeList(_external_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if ((complex && (complex->outer.base_type == "iterator")))
{
if (!as_generator(
@ -76,9 +90,7 @@ struct to_internal_field_convert_generator
.generate(sink, std::make_tuple(field_name, field_name), context))
return false;
}
else if ((complex && (complex->outer.base_type == "array"
|| complex->outer.base_type == "list"
|| complex->outer.base_type == "hash"))
else if ((complex && (complex->outer.base_type == "hash"))
|| field.type.c_type == "Eina_Binbuf *" || field.type.c_type == "const Eina_Binbuf *")
{
// Always assumes pointer
@ -193,12 +205,19 @@ struct to_external_field_convert_generator
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (complex && (complex->outer.base_type == "array"
|| complex->outer.base_type == "list"))
else if (complex && (complex->outer.base_type == "array"))
{
// Always assumes pointer
if (!as_generator(
indent << scope_tab << scope_tab << "_external_struct." << string << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
indent << scope_tab << scope_tab << "_external_struct." << string << " = Efl.Eo.Globals.NativeArrayTo" << type << "(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
else if (complex && (complex->outer.base_type == "list"))
{
// Always assumes pointer
if (!as_generator(
indent << scope_tab << scope_tab << "_external_struct." << string << " = Efl.Eo.Globals.NativeListTo" << type << "(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}

View File

@ -380,13 +380,13 @@ struct visitor_generate
{"list", nullptr, nullptr, [&]
{
complex_type_def c = complex;
c.outer.base_type = "Eina.List";
c.outer.base_type = "IList";
return c;
}}
, {"array", nullptr, nullptr, [&]
{
complex_type_def c = complex;
c.outer.base_type = "Eina.Array";
c.outer.base_type = "IList";
return c;
}}
, {"hash", nullptr, nullptr

View File

@ -198,7 +198,7 @@ public abstract class Application
{
Init(components);
Efl.App app = Efl.App.AppMain;
var command_line = new Eina.Array<Eina.Stringshare>();
var command_line = new List<Eina.Stringshare>();
//command_line.Add(List.ConvertAll(Environment.GetCommandLineArgs(), s => (Eina.Stringshare)s));
//command_line.AddRange(Environment.GetCommandLineArgs());
#if EFL_BETA
@ -209,7 +209,7 @@ public abstract class Application
if (evt.arg.Initialization)
{
var evtArgv = evt.arg.Argv;
int n = evtArgv.Length;
int n = evtArgv.Count;
var argv = new string[n];
for (int i = 0; i < n; ++i)
{
@ -234,7 +234,6 @@ public abstract class Application
OnTerminate();
};
app.Begin();
command_line.Dispose();
Shutdown();
}
}

View File

@ -821,32 +821,59 @@ public static class Globals
return Eina.IteratorNativeFunctions.eina_carray_length_iterator_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length);
}
internal static IEnumerable<T> ListToIEnumerable<T>(IntPtr list)
internal static IList<T> NativeListToIList<T>(IntPtr nativeList)
{
if (list == IntPtr.Zero)
throw new ArgumentException("list is null", nameof(list));
if (nativeList == IntPtr.Zero)
throw new ArgumentException("nativeList is null", nameof(nativeList));
IntPtr l;
for (l = list; l != IntPtr.Zero; l = Eina.ListNativeFunctions.eina_list_next_custom_export_mono(l))
List<T> list = new List<T>();
for (l = nativeList; l != IntPtr.Zero; l = Eina.ListNativeFunctions.eina_list_next_custom_export_mono(l))
{
yield return Eina.TraitFunctions.NativeToManaged<T>(Eina.ListNativeFunctions.eina_list_data_get_custom_export_mono(l));
}
}
internal static IntPtr IEnumerableToList<T>(IEnumerable<T> enumerable)
{
if (enumerable == null)
throw new ArgumentException("enumerable is null", nameof(enumerable));
IntPtr list = IntPtr.Zero;
foreach (T data in enumerable)
{
list = Eina.ListNativeFunctions.eina_list_append(list, Eina.TraitFunctions.ManagedToNativeAlloc(data)); //FIXME: need to free
list.Add(Eina.TraitFunctions.NativeToManaged<T>(Eina.ListNativeFunctions.eina_list_data_get_custom_export_mono(l)));
}
return list;
}
internal static IntPtr IListToNativeList<T>(IList<T> list)
{
if (list == null)
throw new ArgumentException("list is null", nameof(list));
IntPtr nativeList = IntPtr.Zero;
foreach (T data in list)
{
nativeList = Eina.ListNativeFunctions.eina_list_append(nativeList, Eina.TraitFunctions.ManagedToNativeAlloc(data)); //FIXME: need to free
}
return nativeList;
}
internal static IList<T> NativeArrayToIList<T>(IntPtr nativeArray)
{
if (nativeArray == IntPtr.Zero)
throw new ArgumentException("nativeArray is null", nameof(nativeArray));
uint count = Eina.ArrayNativeFunctions.eina_array_count_custom_export_mono(nativeArray);
List<T> list = new List<T>();
for (uint i = 0; i < count; i++)
{
list.Add(Eina.TraitFunctions.NativeToManaged<T>(Eina.ArrayNativeFunctions.eina_array_data_get_custom_export_mono(nativeArray, i)));
}
return list;
}
internal static IntPtr IListToNativeArray<T>(IList<T> list)
{
if (list == null)
throw new ArgumentException("list is null", nameof(list));
IntPtr nativeArray = Eina.ArrayNativeFunctions.eina_array_new(4);
foreach (T data in list)
{
Eina.ArrayNativeFunctions.eina_array_push_custom_export_mono(nativeArray, Eina.TraitFunctions.ManagedToNativeAlloc(data)); //FIXME: need to free
}
return nativeArray;
}
} // Globals

View File

@ -15,6 +15,7 @@
*/
using System;
using System.Linq;
using System.Collections.Generic;
namespace TestSuite
{
@ -226,12 +227,12 @@ class TestEoEvents
public static void event_with_array_payload()
{
var obj = new Dummy.TestObject();
Eina.Array<string> received = null;
Eina.Array<string> sent = new Eina.Array<string>();
List<string> received = null;
List<string> sent = new List<string>();
sent.Append("Abc");
sent.Append("Def");
sent.Append("Ghi");
sent.Add("Abc");
sent.Add("Def");
sent.Add("Ghi");
obj.EvtWithArrayEvent += (object sender, Dummy.TestObjectEvtWithArrayEventArgs e) => {
received = e.arg;
@ -239,14 +240,12 @@ class TestEoEvents
obj.EmitEventWithArray(sent);
Test.AssertEquals(sent.Length, received.Length);
Test.AssertEquals(sent.Count, received.Count);
var pairs = sent.Zip(received, (string sentItem, string receivedItem) => new { Sent = sentItem, Received = receivedItem } );
foreach (var pair in pairs)
{
Test.AssertEquals(pair.Sent, pair.Received);
}
sent.Dispose();
received.Dispose();
obj.Dispose();
}
}

View File

@ -16,6 +16,7 @@
using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using static EinaTestData.BaseData;
@ -137,22 +138,22 @@ internal class StructHelpers
{
var complex = new Dummy.StructComplex();
complex.Farray = new Eina.Array<string>();
complex.Farray.Push("0x0");
complex.Farray.Push("0x2A");
complex.Farray.Push("0x42");
complex.Farray = new List<string>();
complex.Farray.Add("0x0");
complex.Farray.Add("0x2A");
complex.Farray.Add("0x42");
complex.Flist = new Eina.List<string>();
complex.Flist.Append("0x0");
complex.Flist.Append("0x2A");
complex.Flist.Append("0x42");
complex.Flist = new List<string>();
complex.Flist.Add("0x0");
complex.Flist.Add("0x2A");
complex.Flist.Add("0x42");
complex.Fhash = new Eina.Hash<string, string>();
complex.Fhash["aa"] = "aaa";
complex.Fhash["bb"] = "bbb";
complex.Fhash["cc"] = "ccc";
complex.Fiterator = complex.Farray.GetIterator();
complex.Fiterator = complex.Farray;
complex.Fany_value = new Eina.Value(Eina.ValueType.Double);
complex.Fany_value.Set(-9007199254740992.0);