diff options
author | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2019-12-03 17:47:27 -0300 |
---|---|---|
committer | Lauro Moura <lauromoura@expertisesolutions.com.br> | 2019-12-03 18:07:05 -0300 |
commit | 786bb1fe3bda57a4ee3736a489a589bb50930d6f (patch) | |
tree | 77ca31dfa0987558b14e485441aa1262eefaa552 | |
parent | 3cbe4d3e7ce01e0c56c8b7568300a95ab5a9c299 (diff) | |
download | efl-786bb1fe3bda57a4ee3736a489a589bb50930d6f.tar.gz |
csharp: Move collection conversions to a new file
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/events.hh | 4 | ||||
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/parameter.hh | 24 | ||||
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/struct_definition.hh | 4 | ||||
-rw-r--r-- | src/bindings/mono/eo_mono/CollectionConversions.cs | 173 | ||||
-rw-r--r-- | src/bindings/mono/eo_mono/iwrapper.cs | 139 | ||||
-rw-r--r-- | src/bindings/mono/eo_mono/meson.build | 1 |
6 files changed, 190 insertions, 155 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh index 5818763b5c..c4b9579d23 100644 --- a/src/bin/eolian_mono/eolian/mono/events.hh +++ b/src/bin/eolian_mono/eolian/mono/events.hh @@ -132,9 +132,9 @@ struct unpack_event_args_visitor bool operator()(attributes::complex_type_def const& types) const { if (types.outer.base_type == "iterator") - return as_generator("Efl.Eo.Globals.IteratorTo" << eolian_mono::type << "(info)").generate(sink, type, *context); + return as_generator("Efl.Eo.CollectionConversions.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); + return as_generator("Efl.Eo.CollectionConversions.AccessorTo" << eolian_mono::type << "(info)").generate(sink, type, *context); else return as_generator("new " << eolian_mono::type << "(info, false, false)").generate(sink, type, *context); } diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh index 37cb0d7ed7..d3f9a40df6 100644 --- a/src/bin/eolian_mono/eolian/mono/parameter.hh +++ b/src/bin/eolian_mono/eolian/mono/parameter.hh @@ -645,7 +645,7 @@ struct native_convert_in_variable_generator if (!complex) return false; return as_generator( - "var " << string << " = Efl.Eo.Globals.IteratorTo" << type << "(" << escape_keyword(param.param_name) + "var " << string << " = Efl.Eo.CollectionConversions.IteratorTo" << type << "(" << escape_keyword(param.param_name) << ");\n" ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); } @@ -655,7 +655,7 @@ struct native_convert_in_variable_generator if (!complex) return false; return as_generator( - "var " << string << " = Efl.Eo.Globals.AccessorTo" << type << "(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n" + "var " << string << " = Efl.Eo.CollectionConversions.AccessorTo" << type << "(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false") << ");\n" ).generate(sink, std::make_tuple(in_variable_name(param.param_name), param.type), context); } else if (param.type.c_type == "Eina_Value") @@ -758,7 +758,7 @@ struct convert_in_variable_generator return false; auto var_name = in_variable_name(param.param_name); if (!as_generator( - "var " << string << " = " << "Efl.Eo.Globals.IEnumerableToIterator(" << escape_keyword(param.param_name) << ");\n" + "var " << string << " = " << "Efl.Eo.CollectionConversions.IEnumerableToIterator(" << escape_keyword(param.param_name) << ");\n" ).generate(sink, var_name, context)) return false; } @@ -769,7 +769,7 @@ struct convert_in_variable_generator return false; auto var_name = in_variable_name(param.param_name); if (!as_generator( - "var " << string << " = Efl.Eo.Globals.IEnumerableToAccessor(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false")<< ");\n" + "var " << string << " = Efl.Eo.CollectionConversions.IEnumerableToAccessor(" << escape_keyword(param.param_name) << ", " << (param.type.has_own ? "true" : "false")<< ");\n" ).generate(sink, var_name, context)) return false; } @@ -1021,7 +1021,7 @@ struct convert_out_assign_generator if (!complex) return false; return as_generator( - string << " = Efl.Eo.Globals.AccessorTo" << type << "(" << string << ", " << (param.type.has_own ? "true" : "false") << ");\n" + string << " = Efl.Eo.CollectionConversions.AccessorTo" << type << "(" << string << ", " << (param.type.has_own ? "true" : "false") << ");\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_Iterator *", WANT_OWN, WANT_OUT) @@ -1034,7 +1034,7 @@ struct convert_out_assign_generator if (!complex) return false; return as_generator( - string << " = Efl.Eo.Globals.IteratorTo" << type << "(" << string + string << " = Efl.Eo.CollectionConversions.IteratorTo" << type << "(" << string << ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type, out_variable_name(param.param_name)), context); } @@ -1154,7 +1154,7 @@ struct convert_return_generator 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.AccessorTo" << type << "(_ret_var, " << (ret_type.has_own ? "true" : "false") << ");") + if (!as_generator("return Efl.Eo.CollectionConversions.AccessorTo" << type << "(_ret_var, " << (ret_type.has_own ? "true" : "false") << ");") .generate(sink, ret_type, context)) return false; } @@ -1163,7 +1163,7 @@ struct convert_return_generator 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.IteratorTo" << type << "(_ret_var);") + if (!as_generator("return Efl.Eo.CollectionConversions.IteratorTo" << type << "(_ret_var);") .generate(sink, ret_type, context)) return false; } @@ -1312,7 +1312,7 @@ struct native_convert_out_assign_generator return false; auto outvar = out_variable_name(param.param_name); if (!as_generator( - string << " = Efl.Eo.Globals.IEnumerableToAccessor(" << string << ", " << (param.type.has_own ? "true" : "false")<< ");\n" + string << " = Efl.Eo.CollectionConversions.IEnumerableToAccessor(" << string << ", " << (param.type.has_own ? "true" : "false")<< ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context)) return false; } @@ -1327,7 +1327,7 @@ struct native_convert_out_assign_generator return false; auto outvar = out_variable_name(param.param_name); if (!as_generator( - string << " = Efl.Eo.Globals.IEnumerableToIterator(" << string << ");\n" + string << " = Efl.Eo.CollectionConversions.IEnumerableToIterator(" << string << ");\n" ).generate(sink, std::make_tuple(escape_keyword(param.param_name), outvar), context)) return false; } @@ -1467,12 +1467,12 @@ struct native_convert_return_generator } else if (ret_type.c_type == "Eina_Accessor *" || ret_type.c_type == "const Eina_Accessor *") { - return as_generator(lit("return Efl.Eo.Globals.IEnumerableToAccessor(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");") + return as_generator(lit("return Efl.Eo.CollectionConversions.IEnumerableToAccessor(_ret_var, ") << (ret_type.has_own ? "true" : "false") << ");") .generate(sink, attributes::unused, context); } else if (ret_type.c_type == "Eina_Iterator *" || ret_type.c_type == "const Eina_Iterator *") { - return as_generator("return Efl.Eo.Globals.IEnumerableToIterator(_ret_var);") + return as_generator("return Efl.Eo.CollectionConversions.IEnumerableToIterator(_ret_var);") .generate(sink, attributes::unused, context); } else if (ret_type.c_type != "void") diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh index 79501b160d..4c3acc7029 100644 --- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh +++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh @@ -72,7 +72,7 @@ struct to_internal_field_convert_generator else if ((complex && (complex->outer.base_type == "iterator"))) { if (!as_generator( - indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.Globals.IEnumerableToIterator(_external_struct." << string << ");\n") + indent << scope_tab << scope_tab << "_internal_struct." << string << " = Efl.Eo.CollectionConversions.IEnumerableToIterator(_external_struct." << string << ");\n") .generate(sink, std::make_tuple(field_name, field_name), context)) return false; } @@ -212,7 +212,7 @@ struct to_external_field_convert_generator else if (complex && complex->outer.base_type == "iterator") { if (!as_generator( - indent << scope_tab << scope_tab << "_external_struct." << string << " = Efl.Eo.Globals.IteratorTo" << type << "(_internal_struct." << string << ");\n") + indent << scope_tab << scope_tab << "_external_struct." << string << " = Efl.Eo.CollectionConversions.IteratorTo" << type << "(_internal_struct." << string << ");\n") .generate(sink, std::make_tuple(field_name, field.type, field_name), context)) return false; } diff --git a/src/bindings/mono/eo_mono/CollectionConversions.cs b/src/bindings/mono/eo_mono/CollectionConversions.cs new file mode 100644 index 0000000000..18a8ff4b9a --- /dev/null +++ b/src/bindings/mono/eo_mono/CollectionConversions.cs @@ -0,0 +1,173 @@ +/* + * Copyright 2019 by its authors. See AUTHORS. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma warning disable 1591 + +using System; +using System.Runtime.InteropServices; +using System.Runtime.CompilerServices; +using System.Collections.Generic; +using System.Linq; + +namespace Efl +{ + namespace Eo + { + /// <summary> + /// Helper class with method to convert between managed and native collections + /// </summary> + internal class CollectionConversions + { + + internal static IEnumerable<T> AccessorToIEnumerable<T>(IntPtr accessor, bool isMoved) + { + if (accessor == IntPtr.Zero) + { + throw new ArgumentException("accessor is null", nameof(accessor)); + } + + IntPtr data = IntPtr.Zero; + uint position = 0; + + while (Eina.AccessorNativeFunctions.eina_accessor_data_get(accessor, position, out data)) + { + yield return Eina.TraitFunctions.NativeToManaged<T>(data); + position += 1; + } + + if (isMoved) + { + Eina.AccessorNativeFunctions.eina_accessor_free(accessor); + } + } + + internal static IntPtr IEnumerableToAccessor<T>(IEnumerable<T> enumerable, bool isMoved) + { + if (enumerable == null) + { + throw new ArgumentException("enumerable is null", nameof(enumerable)); + } + + // If we are a wrapper around an existing Eina.Accessor, we can just forward + // it and avoid unnecessary copying. + var wrappedAccessor = enumerable as Eina.Accessor<T>; + + if (wrappedAccessor != null) + { + if (isMoved) + { + wrappedAccessor.Own = false; + } + return wrappedAccessor.Handle; + } + + // TODO: Check if we're either an Eina.List or Eina.Collection? + // We could just rewrap their native accessors + IntPtr[] intPtrs = new IntPtr[enumerable.Count()]; + + int i = 0; + foreach (T data in enumerable) + { + intPtrs[i] = Eina.TraitFunctions.ManagedToNativeAlloc<T>(data); + i++; + } + IntPtr[] dataArray = intPtrs.ToArray(); + GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned); + + IntPtr nativeAccessor = IntPtr.Zero; + + if (isMoved) + { + // We need a custom accessor that would unpin the data when freed. + nativeAccessor = Eina.AccessorNativeFunctions.eina_mono_owned_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), + (uint)IntPtr.Size, + (uint)dataArray.Length, + Efl.Eo.Globals.free_gchandle, + GCHandle.ToIntPtr(pinnedArray)); + } + else + { + // FIXME: Leaking.... + nativeAccessor = Eina.AccessorNativeFunctions.eina_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length); + } + + if (nativeAccessor == IntPtr.Zero) + { + pinnedArray.Free(); + throw new InvalidOperationException("Failed to get native accessor for the given container"); + } + + return nativeAccessor; + } + + internal static IEnumerable<T> IteratorToIEnumerable<T>(IntPtr iterator) + { + if (iterator == IntPtr.Zero) + throw new ArgumentException("iterator is null", nameof(iterator)); + + while (Eina.IteratorNativeFunctions.eina_iterator_next(iterator, out IntPtr data)) + { + yield return Eina.TraitFunctions.NativeToManaged<T>(data); + } + } + + internal static IntPtr IEnumerableToIterator<T>(IEnumerable<T> enumerable) + { + if (enumerable == null) + throw new ArgumentException("enumerable is null", nameof(enumerable)); + + IntPtr[] intPtrs = new IntPtr[enumerable.Count()]; + + int i = 0; + foreach (T data in enumerable) + { + intPtrs[i] = Eina.TraitFunctions.ManagedToNativeAlloc<T>(data); + i++; + } + + IntPtr[] dataArray = intPtrs.ToArray(); + GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned); //FIXME: Need to free. + return Eina.IteratorNativeFunctions.eina_carray_length_iterator_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length); + } + + internal static IEnumerable<T> ListToIEnumerable<T>(IntPtr list) + { + if (list == IntPtr.Zero) + throw new ArgumentException("list is null", nameof(list)); + + IntPtr l; + + for (l = list; 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 + } + return list; + } + + } + } +}
\ No newline at end of file diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index c9e5992506..e5a357833f 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -758,145 +758,6 @@ public static class Globals } Monitor.Exit(Efl.All.InitLock); } - - internal static IEnumerable<T> AccessorToIEnumerable<T>(IntPtr accessor, bool isMoved) - { - if (accessor == IntPtr.Zero) - { - throw new ArgumentException("accessor is null", nameof(accessor)); - } - - IntPtr data = IntPtr.Zero; - uint position = 0; - - while (Eina.AccessorNativeFunctions.eina_accessor_data_get(accessor, position, out data)) - { - yield return Eina.TraitFunctions.NativeToManaged<T>(data); - position += 1; - } - - if (isMoved) - { - Eina.AccessorNativeFunctions.eina_accessor_free(accessor); - } - } - - internal static IntPtr IEnumerableToAccessor<T>(IEnumerable<T> enumerable, bool isMoved) - { - if (enumerable == null) - { - throw new ArgumentException("enumerable is null", nameof(enumerable)); - } - - // If we are a wrapper around an existing Eina.Accessor, we can just forward - // it and avoid unnecessary copying. - var wrappedAccessor = enumerable as Eina.Accessor<T>; - - if (wrappedAccessor != null) - { - if (isMoved) - { - wrappedAccessor.Own = false; - } - return wrappedAccessor.Handle; - } - - // TODO: Check if we're either an Eina.List or Eina.Collection? - // We could just rewrap their native accessors - IntPtr[] intPtrs = new IntPtr[enumerable.Count()]; - - int i = 0; - foreach (T data in enumerable) - { - intPtrs[i] = Eina.TraitFunctions.ManagedToNativeAlloc<T>(data); - i++; - } - IntPtr[] dataArray = intPtrs.ToArray(); - GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned); - - IntPtr nativeAccessor = IntPtr.Zero; - - if (isMoved) - { - // We need a custom accessor that would unpin the data when freed. - nativeAccessor = Eina.AccessorNativeFunctions.eina_mono_owned_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), - (uint)IntPtr.Size, - (uint)dataArray.Length, - free_gchandle, - GCHandle.ToIntPtr(pinnedArray)); - } - else - { - // FIXME: Leaking.... - nativeAccessor = Eina.AccessorNativeFunctions.eina_carray_length_accessor_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length); - } - - if (nativeAccessor == IntPtr.Zero) - { - pinnedArray.Free(); - throw new InvalidOperationException("Failed to get native accessor for the given container"); - } - - return nativeAccessor; - } - - internal static IEnumerable<T> IteratorToIEnumerable<T>(IntPtr iterator) - { - if (iterator == IntPtr.Zero) - throw new ArgumentException("iterator is null", nameof(iterator)); - - while (Eina.IteratorNativeFunctions.eina_iterator_next(iterator, out IntPtr data)) - { - yield return Eina.TraitFunctions.NativeToManaged<T>(data); - } - } - - internal static IntPtr IEnumerableToIterator<T>(IEnumerable<T> enumerable) - { - if (enumerable == null) - throw new ArgumentException("enumerable is null", nameof(enumerable)); - - IntPtr[] intPtrs = new IntPtr[enumerable.Count()]; - - int i = 0; - foreach (T data in enumerable) - { - intPtrs[i] = Eina.TraitFunctions.ManagedToNativeAlloc<T>(data); - i++; - } - - IntPtr[] dataArray = intPtrs.ToArray(); - GCHandle pinnedArray = GCHandle.Alloc(dataArray, GCHandleType.Pinned); //FIXME: Need to free. - return Eina.IteratorNativeFunctions.eina_carray_length_iterator_new(pinnedArray.AddrOfPinnedObject(), (uint)(IntPtr.Size), (uint)dataArray.Length); - } - - internal static IEnumerable<T> ListToIEnumerable<T>(IntPtr list) - { - if (list == IntPtr.Zero) - throw new ArgumentException("list is null", nameof(list)); - - IntPtr l; - - for (l = list; 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 - } - return list; - } - - } // Globals /// <summary> diff --git a/src/bindings/mono/eo_mono/meson.build b/src/bindings/mono/eo_mono/meson.build index 013b1cc97f..880d6e46a2 100644 --- a/src/bindings/mono/eo_mono/meson.build +++ b/src/bindings/mono/eo_mono/meson.build @@ -1,6 +1,7 @@ mono_files += files( 'iwrapper.cs', 'workaround.cs', + 'CollectionConversions.cs', 'FunctionWrapper.cs', 'NativeModule.cs', 'EoWrapper.cs', |