eina_mono: replace eina_list and eina_array with IList
authorYeongjong Lee <yj34.lee@samsung.com>
Tue, 14 Jan 2020 08:17:04 +0000 (17:17 +0900)
committerJongmin Lee <jm105.lee@samsung.com>
Tue, 14 Jan 2020 21:25:54 +0000 (06:25 +0900)
Summary:
Eina.List<T> => System.Collections.Generic.IList<T>
Eina.Array<T> => System.Collections.Generic.IList<T>

ref T8486

Depends On D10785

Test Plan: meson build -Dbindings=mono,cxx -Dmono-beta=true

Reviewers: felipealmeida, Jaehyun_Cho

Reviewed By: Jaehyun_Cho

Subscribers: cedric, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T8486, T8488

Differential Revision: https://phab.enlightenment.org/D10902

src/bin/eolian_mono/eolian/mono/events.hh
src/bin/eolian_mono/eolian/mono/parameter.hh
src/bin/eolian_mono/eolian/mono/struct_definition.hh
src/bin/eolian_mono/eolian/mono/type_impl.hh
src/bindings/mono/efl_mono/efl_csharp_application.cs
src/bindings/mono/eo_mono/iwrapper.cs
src/tests/efl_mono/Eina.cs
src/tests/efl_mono/Events.cs
src/tests/efl_mono/StructHelpers.cs

index 2acfcbb..7405f8c 100644 (file)
@@ -139,6 +139,10 @@ struct unpack_event_args_visitor
         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);
+      else 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
         return as_generator("new " << eolian_mono::type << "(info, false, false)").generate(sink, type, *context);
    }
@@ -229,19 +233,28 @@ struct pack_event_info_and_call_visitor
       return as_generator(
                           indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
                           << indent.inc() << "IntPtr info = e.arg.NativeHandle;\n"
-                          << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", IntPtr.Zero, null);\n"
+                          << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
                           ).generate(sink, attributes::unused, *context);
    }
    bool operator()(attributes::complex_type_def const& type) const
    {
       auto const& indent = current_indentation(*context);
-      if ((type.outer.base_type == "iterator") || (type.outer.base_type == "accessor"))
-        return true;
-
-      return as_generator(
-                          indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
-                          << indent.inc() << "IntPtr info = e.arg.Handle;\n"
-                          << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", IntPtr.Zero, null);\n"
+      bool is_own = type.outer.base_qualifier & attributes::qualifier_info::is_own;
+      std::string info_variable;
+
+      if (type.outer.base_type == "iterator")
+        info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToIterator(e.arg, ") + (is_own ? "true" : "false") + ");\n";
+      else if (type.outer.base_type == "accessor")
+        info_variable = std::string("IntPtr info = Efl.Eo.Globals.IEnumerableToAccessor(e.arg, ") + (is_own ? "true" : "false") + ");\n";
+      else if (type.outer.base_type == "array")
+        info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeArray(e.arg, ") + (is_own ? "true" : "false") + ");\n";
+      else if (type.outer.base_type == "list")
+        info_variable = std::string("IntPtr info = Efl.Eo.Globals.IListToNativeList(e.arg, ") + (is_own ? "true" : "false") + ");\n";
+      else
+        info_variable = "IntPtr info = e.arg.Handle;\n";
+      return as_generator(indent.inc() << "Contract.Requires(e != null, nameof(e));\n"
+                          << indent.inc() << info_variable
+                          << indent.inc() << "CallNativeEventCallback(" << library_name << ", \"_" << evt_c_name << "\", info, null);\n"
                           ).generate(sink, attributes::unused, *context);
    }
 };
index 91b29af..824dc0c 100644 (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,29 +736,25 @@ 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;
            if (!as_generator(
-                             "Contract.Requires(" << string << " != null, nameof(" << string << "));\n"
-                             << "var " << string << " = " << string << ".Handle;\n"
-                             ).generate(sink, std::make_tuple(escape_keyword(param.param_name), escape_keyword(param.param_name),
-                                                         in_variable_name(param.param_name), escape_keyword(param.param_name))
-                                        , context))
+                 "var " << string << " = " << "Efl.Eo.Globals.IListToNativeArray(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
+              ).generate(sink, in_variable_name(param.param_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 ((param.type.has_own && (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) << ", " << (param.type.has_own ? "true" : "false") << ");\n"
+              ).generate(sink, var_name, context))
              return false;
         }
       else if (param.type.c_type == "Eina_Iterator *" || param.type.c_type == "const Eina_Iterator *")
@@ -999,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)
@@ -1009,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")
-               << ", " << (param.type.has_own && (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);
         }
@@ -1084,6 +1095,17 @@ struct convert_in_ptr_assign_generator
                  string << " = " << in_variable_name(param.param_name) << ";\n"
              ).generate(sink, escape_keyword(param.param_name), context);
         }
+      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)
+              )
+        {
+           return as_generator(
+             scope_tab(2) << lit("Efl.Eo.Globals.UpdateListFromNativeArray(") << escape_keyword(param.param_name) << ", " << in_variable_name(param.param_name) << ");\n"
+           ).generate(sink, attributes::unused, context);
+        }
+
 
       return true;
    }
@@ -1141,17 +1163,23 @@ 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"}
-                   << ", " << (ret_type.has_own && (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 *")
@@ -1274,30 +1302,30 @@ 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 << ", " << (param.type.has_own ? "true" : "false")<< ");\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;
 
-           if ((param.type.has_own && (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 << ", " << (param.type.has_own ? "true" : "false")<<");\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)
@@ -1439,18 +1467,22 @@ 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(lit("return Efl.Eo.Globals.IListToNativeArray(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");")
+            .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;
 
-          return as_generator("return _ret_var.Handle;")
+          return as_generator(lit("return Efl.Eo.Globals.IListToNativeList(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");")
             .generate(sink, attributes::unused, context);
        }
      else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *")
index 24d0ff3..176b551 100644 (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 << ", " << (field.type.has_own ? "true" : "false") << ");\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 << ", " << (field.type.has_own ? "true" : "false") << ");\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 << " = 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 << " = new " << type << "(_internal_struct." << string << ", false, false);\n")
+                 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;
         }
index f365a0d..4475844 100644 (file)
@@ -368,13 +368,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
index 522ce56..fcacb1f 100644 (file)
@@ -202,7 +202,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
@@ -238,7 +238,6 @@ public abstract class Application
             OnTerminate();
         };
         app.Begin();
-        command_line.Dispose();
         Shutdown();
     }
 }
index 2a8ebf0..780735f 100644 (file)
@@ -875,33 +875,107 @@ internal static class Globals
         return ret;
     }
 
-    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));
+            list.Add(Eina.TraitFunctions.NativeToManaged<T>(Eina.ListNativeFunctions.eina_list_data_get_custom_export_mono(l)));
         }
+        return list;
     }
 
-    internal static IntPtr IEnumerableToList<T>(IEnumerable<T> enumerable)
+    internal static IntPtr IListToNativeList<T>(IList<T> list, bool isMoved)
     {
-        if (enumerable == null)
-            throw new ArgumentException("enumerable is null", nameof(enumerable));
+        if (list == null)
+            throw new ArgumentException("list is null", nameof(list));
 
-        IntPtr list = IntPtr.Zero;
-        foreach (T data in enumerable)
+        // If we are a wrapper around an existing Eina.List, we can just forward
+        // it and avoid unnecessary copying in non-owning transfers.
+        var wrappedList = list as Eina.List<T>;
+
+        if (wrappedList != null && !isMoved)
+        {
+            return wrappedList.Handle;
+        }
+
+        IntPtr nativeList = IntPtr.Zero;
+        foreach (T data in list)
         {
-            list = Eina.ListNativeFunctions.eina_list_append(list, Eina.TraitFunctions.ManagedToNativeAlloc(data));
+            nativeList = Eina.ListNativeFunctions.eina_list_append(nativeList, Eina.TraitFunctions.ManagedToNativeAlloc(data)); //FIXME: need to free
         }
+
+        if (!isMoved)
+        {
+            // FIXME Need to free ret and unpin pinnedArray in the future.
+        }
+
+        return nativeList;
+    }
+
+    internal static IList<T> NativeArrayToIList<T>(IntPtr nativeArray)
+    {
+        if (nativeArray == IntPtr.Zero)
+            throw new ArgumentException("nativeArray is null", nameof(nativeArray));
+
+        List<T> list = new List<T>();
+        UpdateListFromNativeArray(list, nativeArray);
+
         // FIXME need to free `list` if the returned list is not @moved
         return list;
     }
 
+    internal static IntPtr IListToNativeArray<T>(IList<T> list, bool isMoved)
+    {
+        if (list == null)
+            throw new ArgumentException("list is null", nameof(list));
+
+        // If we are a wrapper around an existing Eina.Array, we can just forward
+        // it and avoid unnecessary copying in non-owning transfers.
+        var wrappedArray = list as Eina.Array<T>;
+
+        if (wrappedArray != null && !isMoved)
+        {
+            return wrappedArray.Handle;
+        }
+
+        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
+        }
+
+        if (!isMoved)
+        {
+            // FIXME Need to free ret and unpin pinnedArray in the future.
+        }
+
+        return nativeArray;
+    }
+
+    internal static void UpdateListFromNativeArray<T>(IList<T> list, IntPtr nativeArray)
+    {
+        // Do not update if list Handle is same to nativeArray. They already updated in native code.
+        var wrappedArray = list as Eina.Array<T>;
+        if (wrappedArray != null && wrappedArray.Handle == nativeArray)
+            return;
+
+        list.Clear();
+        if (nativeArray == IntPtr.Zero)
+        {
+            return;
+        }
+
+        uint count = Eina.ArrayNativeFunctions.eina_array_count_custom_export_mono(nativeArray);
+        for (uint i = 0; i < count; i++)
+        {
+            list.Add(Eina.TraitFunctions.NativeToManaged<T>(Eina.ArrayNativeFunctions.eina_array_data_get_custom_export_mono(nativeArray, i)));
+        }
+    }
 
 } // Globals
 
index bee6216..461dee6 100644 (file)
@@ -937,7 +937,7 @@ class TestEinaArray
         var arr = new Eina.Array<int>();
         arr.Append(base_seq_int);
         Test.Assert(t.EinaArrayIntInOwn(arr));
-        Test.Assert(!arr.Own);
+        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(modified_seq_int));
         arr.Dispose();
         Test.Assert(arr.Handle == IntPtr.Zero);
@@ -948,13 +948,10 @@ class TestEinaArray
     public static void test_eina_array_int_out()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<int> arr;
+        IList<int> arr;
         Test.Assert(t.EinaArrayIntOut(out arr));
-        Test.Assert(!arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_int));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_int));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_int) != null);
         Test.Assert(t.CheckEinaArrayIntOut());
         t.Dispose();
     }
@@ -962,13 +959,10 @@ class TestEinaArray
     public static void test_eina_array_int_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<int> arr;
+        IList<int> arr;
         Test.Assert(t.EinaArrayIntOutOwn(out arr));
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_int));
-        Test.Assert(arr.Append(append_seq_int));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_int) != null);
         t.Dispose();
     }
 
@@ -976,12 +970,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayIntReturn();
-        Test.Assert(!arr.Own);
-        Test.Assert(!arr.OwnContent);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_int));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_int));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_int) != null);
         Test.Assert(t.CheckEinaArrayIntReturn());
         t.Dispose();
     }
@@ -990,11 +980,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayIntReturnOwn();
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_int));
-        Test.Assert(arr.Append(append_seq_int));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_int) != null);
         t.Dispose();
     }
 
@@ -1018,7 +1005,7 @@ class TestEinaArray
         var arr = new Eina.Array<string>();
         arr.Append(base_seq_str);
         Test.Assert(t.EinaArrayStrInOwn(arr));
-        Test.Assert(!arr.Own);
+        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(modified_seq_str));
         arr.Dispose();
         Test.Assert(arr.Handle == IntPtr.Zero);
@@ -1029,13 +1016,10 @@ class TestEinaArray
     public static void test_eina_array_str_out()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<string> arr;
+        IList<string> arr;
         Test.Assert(t.EinaArrayStrOut(out arr));
-        Test.Assert(!arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_str));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_str));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_str) != null);
         Test.Assert(t.CheckEinaArrayStrOut());
         t.Dispose();
     }
@@ -1043,13 +1027,10 @@ class TestEinaArray
     public static void test_eina_array_str_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<string> arr;
+        IList<string> arr;
         Test.Assert(t.EinaArrayStrOutOwn(out arr));
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_str));
-        Test.Assert(arr.Append(append_seq_str));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_str) != null);
         t.Dispose();
     }
 
@@ -1057,11 +1038,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayStrReturn();
-        Test.Assert(!arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_str));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_str));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_str) != null);
         Test.Assert(t.CheckEinaArrayStrReturn());
         t.Dispose();
     }
@@ -1070,11 +1048,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayStrReturnOwn();
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_str));
-        Test.Assert(arr.Append(append_seq_str));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_str) != null);
         t.Dispose();
     }
 
@@ -1098,7 +1073,7 @@ class TestEinaArray
         var arr = new Eina.Array<Eina.Stringshare>();
         arr.Append(base_seq_strshare);
         Test.Assert(t.EinaArrayStrshareInOwn(arr));
-        Test.Assert(!arr.Own);
+        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(modified_seq_strshare));
         arr.Dispose();
         Test.Assert(arr.Handle == IntPtr.Zero);
@@ -1109,13 +1084,10 @@ class TestEinaArray
     public static void test_eina_array_strshare_out()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<Eina.Stringshare> arr;
+        IList<Eina.Stringshare> arr;
         Test.Assert(t.EinaArrayStrshareOut(out arr));
-        Test.Assert(!arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_strshare));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_strshare) != null);
         Test.Assert(t.CheckEinaArrayStrshareOut());
         t.Dispose();
     }
@@ -1123,13 +1095,10 @@ class TestEinaArray
     public static void test_eina_array_strshare_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<Eina.Stringshare> arr;
+        IList<Eina.Stringshare> arr;
         Test.Assert(t.EinaArrayStrshareOutOwn(out arr));
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare));
-        Test.Assert(arr.Append(append_seq_strshare));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_strshare) != null);
         t.Dispose();
     }
 
@@ -1137,11 +1106,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayStrshareReturn();
-        Test.Assert(!arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare));
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(append_seq_strshare));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_strshare) != null);
         Test.Assert(t.CheckEinaArrayStrshareReturn());
         t.Dispose();
     }
@@ -1150,11 +1116,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayStrshareReturnOwn();
-        Test.Assert(arr.Own);
         Test.Assert(arr.ToArray().SequenceEqual(base_seq_strshare));
-        Test.Assert(arr.Append(append_seq_strshare));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(append_seq_strshare) != null);
         t.Dispose();
     }
 
@@ -1179,7 +1142,7 @@ class TestEinaArray
         var arr = new Eina.Array<Dummy.Numberwrapper>();
         arr.Append(BaseSeqObj());
         Test.Assert(t.EinaArrayObjInOwn(arr));
-        Test.Assert(!arr.Own);
+        Test.Assert(arr.Own);
         NumberwrapperSequenceAssertEqual(arr.ToArray(), ModifiedSeqObj());
         arr.Dispose();
         Test.Assert(arr.Handle == IntPtr.Zero);
@@ -1190,13 +1153,10 @@ class TestEinaArray
     public static void test_eina_array_obj_out()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<Dummy.Numberwrapper> arr;
+        IList<Dummy.Numberwrapper> arr;
         Test.Assert(t.EinaArrayObjOut(out arr));
-        Test.Assert(!arr.Own);
         NumberwrapperSequenceAssertEqual(arr.ToArray(), BaseSeqObj());
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(AppendSeqObj()));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(AppendSeqObj()) != null);
         Test.Assert(t.CheckEinaArrayObjOut());
         t.Dispose();
     }
@@ -1204,13 +1164,10 @@ class TestEinaArray
     public static void test_eina_array_obj_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.Array<Dummy.Numberwrapper> arr;
+        IList<Dummy.Numberwrapper> arr;
         Test.Assert(t.EinaArrayObjOutOwn(out arr));
-        Test.Assert(arr.Own);
         NumberwrapperSequenceAssertEqual(arr.ToArray(), BaseSeqObj());
-        Test.Assert(arr.Append(AppendSeqObj()));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(AppendSeqObj()) != null);
         t.Dispose();
     }
 
@@ -1218,11 +1175,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayObjReturn();
-        Test.Assert(!arr.Own);
         NumberwrapperSequenceAssertEqual(arr.ToArray(), BaseSeqObj());
-        Test.AssertRaises<NotSupportedException>(() => arr.Append(AppendSeqObj()));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(AppendSeqObj()) != null);
         Test.Assert(t.CheckEinaArrayObjReturn());
         t.Dispose();
     }
@@ -1231,11 +1185,8 @@ class TestEinaArray
     {
         var t = new Dummy.TestObject();
         var arr = t.EinaArrayObjReturnOwn();
-        Test.Assert(arr.Own);
         NumberwrapperSequenceAssertEqual(arr.ToArray(), BaseSeqObj());
-        Test.Assert(arr.Append(AppendSeqObj()));
-        arr.Dispose();
-        Test.Assert(arr.Handle == IntPtr.Zero);
+        Test.Assert(arr.Concat(AppendSeqObj()) != null);
         t.Dispose();
     }
 
@@ -2119,8 +2070,8 @@ class TestEinaList
         var lst = new Eina.List<int>();
         lst.Append(base_seq_int);
         Test.Assert(t.EinaListIntInOwn(lst));
-        Test.Assert(!lst.Own);
-        Test.Assert(!lst.OwnContent);
+        Test.Assert(lst.Own);
+        Test.Assert(lst.OwnContent);
         lst.Dispose();
         Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListIntInOwn());
@@ -2130,13 +2081,9 @@ class TestEinaList
     public static void test_eina_list_int_out()
     {
         var t = new Dummy.TestObject();
-        Eina.List<int> lst;
+        IList<int> lst;
         Test.Assert(t.EinaListIntOut(out lst));
-        Test.Assert(!lst.Own);
-        Test.Assert(!lst.OwnContent);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListIntOut());
         t.Dispose();
     }
@@ -2144,13 +2091,10 @@ class TestEinaList
     public static void test_eina_list_int_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.List<int> lst;
+        IList<int> lst;
         Test.Assert(t.EinaListIntOutOwn(out lst));
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
-        lst.Append(append_seq_int);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_int);
         t.Dispose();
     }
 
@@ -2158,11 +2102,7 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListIntReturn();
-        Test.Assert(!lst.Own);
-        Test.Assert(!lst.OwnContent);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListIntReturn());
         t.Dispose();
     }
@@ -2171,11 +2111,8 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListIntReturnOwn();
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_int));
-        lst.Append(append_seq_int);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_int);
         t.Dispose();
     }
 
@@ -2199,7 +2136,7 @@ class TestEinaList
         var lst = new Eina.List<string>();
         lst.Append(base_seq_str);
         Test.Assert(t.EinaListStrInOwn(lst));
-        Test.Assert(!lst.Own);
+        Test.Assert(lst.Own);
         lst.Dispose();
         Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrInOwn());
@@ -2209,12 +2146,9 @@ class TestEinaList
     public static void test_eina_list_str_out()
     {
         var t = new Dummy.TestObject();
-        Eina.List<string> lst;
+        IList<string> lst;
         Test.Assert(t.EinaListStrOut(out lst));
-        Test.Assert(!lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrOut());
         t.Dispose();
     }
@@ -2222,13 +2156,10 @@ class TestEinaList
     public static void test_eina_list_str_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.List<string> lst;
+        IList<string> lst;
         Test.Assert(t.EinaListStrOutOwn(out lst));
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
-        lst.Append(append_seq_str);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_str);
         t.Dispose();
     }
 
@@ -2236,10 +2167,7 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListStrReturn();
-        Test.Assert(!lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrReturn());
         t.Dispose();
     }
@@ -2248,11 +2176,8 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListStrReturnOwn();
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_str));
-        lst.Append(append_seq_str);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_str);
         t.Dispose();
     }
 
@@ -2276,7 +2201,7 @@ class TestEinaList
         var lst = new Eina.List<Eina.Stringshare>();
         lst.Append(base_seq_strshare);
         Test.Assert(t.EinaListStrshareInOwn(lst));
-        Test.Assert(!lst.Own);
+        Test.Assert(lst.Own);
         lst.Dispose();
         Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrshareInOwn());
@@ -2286,12 +2211,9 @@ class TestEinaList
     public static void test_eina_list_strshare_out()
     {
         var t = new Dummy.TestObject();
-        Eina.List<Eina.Stringshare> lst;
+        IList<Eina.Stringshare> lst;
         Test.Assert(t.EinaListStrshareOut(out lst));
-        Test.Assert(!lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrshareOut());
         t.Dispose();
     }
@@ -2299,13 +2221,10 @@ class TestEinaList
     public static void test_eina_list_strshare_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.List<Eina.Stringshare> lst;
+        IList<Eina.Stringshare> lst;
         Test.Assert(t.EinaListStrshareOutOwn(out lst));
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
-        lst.Append(append_seq_strshare);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_strshare);
         t.Dispose();
     }
 
@@ -2313,10 +2232,7 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListStrshareReturn();
-        Test.Assert(!lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListStrshareReturn());
         t.Dispose();
     }
@@ -2325,11 +2241,8 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListStrshareReturnOwn();
-        Test.Assert(lst.Own);
         Test.Assert(lst.ToArray().SequenceEqual(base_seq_strshare));
-        lst.Append(append_seq_strshare);
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(append_seq_strshare);
         t.Dispose();
     }
 
@@ -2354,7 +2267,7 @@ class TestEinaList
         var lst = new Eina.List<Dummy.Numberwrapper>();
         lst.Append(BaseSeqObj());
         Test.Assert(t.EinaListObjInOwn(lst));
-        Test.Assert(!lst.Own);
+        Test.Assert(lst.Own);
         lst.Dispose();
         Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListObjInOwn());
@@ -2364,12 +2277,9 @@ class TestEinaList
     public static void test_eina_list_obj_out()
     {
         var t = new Dummy.TestObject();
-        Eina.List<Dummy.Numberwrapper> lst;
+        IList<Dummy.Numberwrapper> lst;
         Test.Assert(t.EinaListObjOut(out lst));
-        Test.Assert(!lst.Own);
         NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListObjOut());
         t.Dispose();
     }
@@ -2377,13 +2287,10 @@ class TestEinaList
     public static void test_eina_list_obj_out_own()
     {
         var t = new Dummy.TestObject();
-        Eina.List<Dummy.Numberwrapper> lst;
+        IList<Dummy.Numberwrapper> lst;
         Test.Assert(t.EinaListObjOutOwn(out lst));
-        Test.Assert(lst.Own);
         NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
-        lst.Append(AppendSeqObj());
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(AppendSeqObj());
         t.Dispose();
     }
 
@@ -2391,10 +2298,7 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListObjReturn();
-        Test.Assert(!lst.Own);
         NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
         Test.Assert(t.CheckEinaListObjReturn());
         t.Dispose();
     }
@@ -2403,11 +2307,8 @@ class TestEinaList
     {
         var t = new Dummy.TestObject();
         var lst = t.EinaListObjReturnOwn();
-        Test.Assert(lst.Own);
         NumberwrapperSequenceAssertEqual(lst.ToArray(), BaseSeqObj());
-        lst.Append(AppendSeqObj());
-        lst.Dispose();
-        Test.Assert(lst.Handle == IntPtr.Zero);
+        lst.Concat(AppendSeqObj());
         t.Dispose();
     }
 
index 824d9a1..5f8cc0f 100644 (file)
@@ -15,6 +15,7 @@
  */
 using System;
 using System.Linq;
+using System.Collections.Generic;
 
 namespace TestSuite
 {
@@ -226,7 +227,7 @@ class TestEoEvents
     public static void event_with_array_payload()
     {
         var obj = new Dummy.TestObject();
-        Eina.Array<string> received = null;
+        List<string> received = null;
         Eina.Array<string> sent = new Eina.Array<string>();
 
         sent.Append("Abc");
@@ -234,7 +235,7 @@ class TestEoEvents
         sent.Append("Ghi");
 
         obj.EvtWithArrayEvent += (object sender, Dummy.TestObjectEvtWithArrayEventArgs e) => {
-            received = e.arg;
+            received = e.arg as List<string>;
         };
 
         obj.EmitEventWithArray(sent);
@@ -246,7 +247,6 @@ class TestEoEvents
             Test.AssertEquals(pair.Sent, pair.Received);
         }
         sent.Dispose();
-        received.Dispose();
         obj.Dispose();
     }
 }
index 9c9f750..5e6dc50 100644 (file)
@@ -16,6 +16,7 @@
 using System;
 using System.Linq;
 using System.Runtime.InteropServices;
+using System.Collections.Generic;
 
 using Eina;
 using static EinaTestData.BaseData;
@@ -139,21 +140,21 @@ 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.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.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 = ((Eina.Array<string>)complex.Farray).GetIterator();
 
         complex.Fany_value = new Eina.Value(Eina.ValueType.Double);
         complex.Fany_value.Set(-9007199254740992.0);