Compare commits
5 Commits
master
...
devs/vitor
Author | SHA1 | Date |
---|---|---|
|
6e83ee95c1 | |
|
2a99be2b52 | |
|
f6eeb3fb7c | |
|
c2865a90ef | |
|
82a320c683 |
|
@ -70,6 +70,7 @@ efl_mono_test_eolian_files = \
|
|||
tests/efl_mono/dummy_inherit_iface.eo \
|
||||
tests/efl_mono/dummy_inherit_helper.eo \
|
||||
tests/efl_mono/dummy_child.eo \
|
||||
tests/efl_mono/dummy_constructible_object.eo \
|
||||
tests/efl_mono/dummy_part_holder.eo \
|
||||
tests/efl_mono/dummy_numberwrapper.eo \
|
||||
tests/efl_mono/dummy_event_manager.eo
|
||||
|
@ -403,6 +404,7 @@ tests_efl_mono_libefl_mono_native_test_la_SOURCES = \
|
|||
tests/efl_mono/dummy_interfaces.c \
|
||||
tests/efl_mono/dummy_numberwrapper.c \
|
||||
tests/efl_mono/dummy_part_holder.c \
|
||||
tests/efl_mono/dummy_constructible_object.c \
|
||||
tests/efl_mono/dummy_test_object.c
|
||||
|
||||
efl_mono_test_eolian_c = $(efl_mono_test_eolian_files:%.eo=%.eo.c)
|
||||
|
@ -447,6 +449,11 @@ tests/efl_mono/dummy_part_holder.c: \
|
|||
$(efl_mono_test_eolian_h) \
|
||||
tests/efl_mono/libefl_mono_native_test.h
|
||||
|
||||
tests/efl_mono/dummy_constructible_object.c: \
|
||||
$(efl_mono_test_eolian_c) \
|
||||
$(efl_mono_test_eolian_h) \
|
||||
tests/efl_mono/libefl_mono_native_test.h
|
||||
|
||||
tests/efl_mono/dummy_test_object.c: \
|
||||
$(efl_mono_test_eolian_c) \
|
||||
$(efl_mono_test_eolian_h) \
|
||||
|
@ -455,6 +462,7 @@ tests/efl_mono/dummy_test_object.c: \
|
|||
# Intermediate C Sharp test DLL
|
||||
efl_mono_test_eolian_mono_files = tests/efl_mono/dummy_test_object.eo.cs \
|
||||
tests/efl_mono/dummy_test_iface.eo.cs \
|
||||
tests/efl_mono/dummy_constructible_object.eo.cs \
|
||||
tests/efl_mono/dummy_child.eo.cs \
|
||||
tests/efl_mono/dummy_event_manager.eo.cs \
|
||||
tests/efl_mono/dummy_part_holder.eo.cs \
|
||||
|
@ -509,6 +517,7 @@ tests_efl_mono_efl_mono_SOURCES = \
|
|||
tests/efl_mono/Eldbus.cs \
|
||||
tests/efl_mono/Eo.cs \
|
||||
tests/efl_mono/EoPromises.cs \
|
||||
tests/efl_mono/EoConstruction.cs \
|
||||
tests/efl_mono/Errors.cs \
|
||||
tests/efl_mono/Events.cs \
|
||||
tests/efl_mono/FunctionPointers.cs \
|
||||
|
|
|
@ -196,6 +196,17 @@ struct klass
|
|||
if (!generate_fields(sink, cls, concrete_cxt))
|
||||
return false;
|
||||
|
||||
if (!as_generator
|
||||
(
|
||||
scope_tab << "/// <summary>Constructor to be used when objects are expected to be constructed from native code.</summary>\n"
|
||||
<< scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
|
||||
<< scope_tab << "private " << concrete_name << "(ConstructingHandle ch) : base(ch)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << "}\n\n"
|
||||
)
|
||||
.generate(sink, attributes::unused, concrete_cxt))
|
||||
return false;
|
||||
|
||||
if (!as_generator
|
||||
(
|
||||
scope_tab << "[System.Runtime.InteropServices.DllImport(" << context_find_tag<library_context>(concrete_cxt).actual_library_name(cls.filename)
|
||||
|
@ -246,7 +257,7 @@ struct klass
|
|||
).generate(sink, attributes::unused, concrete_cxt))
|
||||
return false;
|
||||
|
||||
if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context)))
|
||||
if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), concrete_cxt)))
|
||||
return true;
|
||||
|
||||
if(!as_generator("}\n").generate(sink, attributes::unused, concrete_cxt)) return false;
|
||||
|
@ -318,7 +329,7 @@ struct klass
|
|||
).generate(sink, attributes::unused, inherit_cxt))
|
||||
return false;
|
||||
|
||||
if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), context)))
|
||||
if(!generate_native_inherit_class(sink, cls, change_indentation(indent.inc(), inherit_cxt)))
|
||||
return true;
|
||||
|
||||
if(!as_generator("}\n").generate(sink, attributes::unused, inherit_cxt)) return false;
|
||||
|
@ -357,7 +368,7 @@ struct klass
|
|||
(
|
||||
indent << lit("/// <summary>Wrapper for native methods and virtual method delegates.\n")
|
||||
<< indent << "/// For internal use by generated code only.</summary>\n"
|
||||
<< indent << "public " << (root ? "" : "new " ) << "class " << native_inherit_name << " " << (root ? " : Efl.Eo.NativeClass" : (": " + base_name)) <<"\n"
|
||||
<< indent << "public new class " << native_inherit_name << " : " << (root ? "Efl.Eo.EoWrapper.NativeMethods" : base_name) << "\n"
|
||||
<< indent << "{\n"
|
||||
).generate(sink, attributes::unused, inative_cxt))
|
||||
return false;
|
||||
|
@ -396,7 +407,7 @@ struct klass
|
|||
).generate(sink, attributes::unused, inative_cxt))
|
||||
return false;
|
||||
|
||||
if(!root)
|
||||
if (!root || context_find_tag<class_context>(context).current_wrapper_kind != class_context::concrete)
|
||||
if(!as_generator(indent << scope_tab << scope_tab << "descs.AddRange(base.GetEoOps(type));\n").generate(sink, attributes::unused, inative_cxt))
|
||||
return false;
|
||||
|
||||
|
@ -492,6 +503,11 @@ struct klass
|
|||
<< (*(scope_tab << scope_tab << constructor_invocation << "\n"))
|
||||
<< scope_tab << scope_tab << "FinishInstantiation();\n"
|
||||
<< scope_tab << "}\n\n"
|
||||
<< scope_tab << "/// <summary>Constructor to be used when objects are expected to be constructed from native code.</summary>\n"
|
||||
<< scope_tab << "/// <param name=\"ch\">Tag struct storing the native handle of the object being constructed.</param>\n"
|
||||
<< scope_tab << "protected " << inherit_name << "(ConstructingHandle ch) : base(ch)\n"
|
||||
<< scope_tab << "{\n"
|
||||
<< scope_tab << "}\n\n"
|
||||
<< scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
|
||||
<< scope_tab << "/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>\n"
|
||||
<< scope_tab << "/// <param name=\"raw\">The native pointer to be wrapped.</param>\n"
|
||||
|
|
|
@ -26,23 +26,26 @@ struct marshall_annotation_visitor_generate;
|
|||
*/
|
||||
struct marshall_type_generator
|
||||
{
|
||||
marshall_type_generator(bool is_return = false)
|
||||
: is_return(is_return) {}
|
||||
|
||||
marshall_type_generator(bool is_return = false, bool is_special_subtype = false)
|
||||
: is_return(is_return)
|
||||
, is_special_subtype(is_special_subtype)
|
||||
{}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
||||
{
|
||||
return type.original_type.visit(detail::marshall_type_visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr });
|
||||
return type.original_type.visit(detail::marshall_type_visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr, is_special_subtype});
|
||||
}
|
||||
/* Some types may require a different conversion when they are in @out parameters. */
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return param.type.original_type.visit(detail::marshall_type_visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr});
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_special_subtype});
|
||||
}
|
||||
|
||||
bool is_return;
|
||||
bool is_special_subtype;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -73,9 +76,9 @@ struct marshall_annotation_generator
|
|||
|
||||
struct marshall_type_terminal
|
||||
{
|
||||
marshall_type_generator const operator()(bool is_return) const
|
||||
marshall_type_generator const operator()(bool is_return, bool is_special_subtype = false) const
|
||||
{
|
||||
return marshall_type_generator(is_return);
|
||||
return marshall_type_generator(is_return, is_special_subtype);
|
||||
}
|
||||
} const marshall_type = {};
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ struct marshall_type_visitor_generate
|
|||
bool is_out;
|
||||
bool is_return;
|
||||
bool is_ptr;
|
||||
bool is_special_subtype;
|
||||
|
||||
typedef marshall_type_visitor_generate<OutputIterator, Context> visitor_type;
|
||||
typedef bool result_type;
|
||||
|
@ -70,12 +71,16 @@ struct marshall_type_visitor_generate
|
|||
{
|
||||
regular_type_def r = regular;
|
||||
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
|
||||
if (is_special_subtype)
|
||||
return replace_base_type(r, "Eina.StringShare");
|
||||
return replace_base_type(r, "System.String");
|
||||
}}
|
||||
, {"stringshare", false, [&]
|
||||
{
|
||||
regular_type_def r = regular;
|
||||
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
|
||||
if (is_special_subtype)
|
||||
return replace_base_type(r, "Eina.StringShare");
|
||||
return replace_base_type(r, "System.String");
|
||||
}}
|
||||
, {"strbuf", nullptr, [&]
|
||||
|
@ -171,16 +176,16 @@ struct marshall_type_visitor_generate
|
|||
regular_type_def r = regular;
|
||||
r.base_type = "System.IntPtr";
|
||||
r.namespaces.clear();
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(r);
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr, is_special_subtype}(r);
|
||||
}
|
||||
else
|
||||
{
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(regular);
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr, is_special_subtype}(regular);
|
||||
}
|
||||
}
|
||||
bool operator()(attributes::klass_name klass_name) const
|
||||
{
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(klass_name);
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr, is_special_subtype}(klass_name);
|
||||
}
|
||||
bool operator()(attributes::complex_type_def const& complex) const
|
||||
{
|
||||
|
@ -225,7 +230,7 @@ struct marshall_type_visitor_generate
|
|||
{
|
||||
regular_type_def no_pointer_regular = complex.outer;
|
||||
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
|
||||
&& as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context);
|
||||
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context);
|
||||
};
|
||||
|
||||
if(eina::optional<bool> b = call_match
|
||||
|
@ -250,7 +255,7 @@ struct marshall_type_visitor_generate
|
|||
return *b;
|
||||
}
|
||||
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr}(complex);
|
||||
return visitor_generate<OutputIterator, Context>{sink, context, c_type, is_out, is_return, is_ptr, is_special_subtype}(complex);
|
||||
}
|
||||
};
|
||||
} }
|
||||
|
|
|
@ -14,29 +14,32 @@ struct visitor_generate;
|
|||
|
||||
struct type_generator
|
||||
{
|
||||
type_generator(bool is_return = false, bool is_optional = false)
|
||||
: is_return(is_return), is_optional(is_optional) {}
|
||||
|
||||
type_generator(bool is_return = false, bool is_optional = false, bool is_special_subtype = false)
|
||||
: is_return(is_return)
|
||||
, is_optional(is_optional)
|
||||
, is_special_subtype(is_special_subtype)
|
||||
{}
|
||||
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::type_def const& type, Context const& context) const
|
||||
{
|
||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr, is_optional});
|
||||
return type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, type.c_type, false, is_return, type.is_ptr, is_optional, is_special_subtype});
|
||||
}
|
||||
template <typename OutputIterator, typename Context>
|
||||
bool generate(OutputIterator sink, attributes::parameter_def const& param, Context const& context) const
|
||||
{
|
||||
return param.type.original_type.visit(visitor_generate<OutputIterator, Context>{sink, &context, param.type.c_type
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_optional});
|
||||
, param.direction != attributes::parameter_direction::in, false, param.type.is_ptr, is_optional, is_special_subtype});
|
||||
}
|
||||
|
||||
bool is_return, is_optional;
|
||||
bool is_return, is_optional, is_special_subtype;
|
||||
};
|
||||
|
||||
struct type_terminal
|
||||
{
|
||||
type_generator const operator()(bool is_return, bool is_optional = false) const
|
||||
type_generator const operator()(bool is_return, bool is_optional = false, bool is_special_subtype = false) const
|
||||
{
|
||||
return type_generator(is_return, is_optional);
|
||||
return type_generator(is_return, is_optional, is_special_subtype);
|
||||
}
|
||||
} const type = {};
|
||||
|
||||
|
|
|
@ -99,6 +99,7 @@ struct visitor_generate
|
|||
bool is_return;
|
||||
bool is_ptr;
|
||||
mutable bool is_optional;
|
||||
bool is_special_subtype;
|
||||
|
||||
typedef visitor_generate<OutputIterator, Context> visitor_type;
|
||||
typedef bool result_type;
|
||||
|
@ -205,6 +206,8 @@ struct visitor_generate
|
|||
{
|
||||
regular_type_def r = regular;
|
||||
r.base_qualifier.qualifier ^= qualifier_info::is_ref;
|
||||
if (is_special_subtype)
|
||||
return replace_base_type(r, "Eina.StringShare");
|
||||
return replace_base_type(r, "System.String");
|
||||
}}
|
||||
, {"strbuf", nullptr, [&]
|
||||
|
@ -400,7 +403,7 @@ struct visitor_generate
|
|||
// if(is_out)
|
||||
// pointers.push_back({{attributes::qualifier_info::is_none, {}}, true});
|
||||
return visitor_type{sink, context, c_type, false}(no_pointer_regular)
|
||||
&& as_generator("<" << (type % ", ") << ">").generate(sink, complex.subtypes, *context)
|
||||
&& as_generator("<" << (type(false, false, true) % ", ") << ">").generate(sink, complex.subtypes, *context)
|
||||
;
|
||||
// && detail::generate_pointers(sink, pointers, *context, false);
|
||||
};
|
||||
|
|
|
@ -88,7 +88,7 @@ public abstract class Application
|
|||
/// <summary>
|
||||
/// Called when the application is started. Arguments from the command line are passed here.
|
||||
/// </summary>
|
||||
protected abstract void OnInitialize(Eina.Array<System.String> args);
|
||||
protected abstract void OnInitialize(string[] args);
|
||||
|
||||
/// <summary>
|
||||
/// Arguments are passed here, Additional calls to this function may occure,
|
||||
|
@ -130,8 +130,8 @@ public abstract class Application
|
|||
{
|
||||
Init(components);
|
||||
Efl.App app = Efl.App.AppMain;
|
||||
Eina.Array<String> command_line = new Eina.Array<String>();
|
||||
command_line.Append(Environment.GetCommandLineArgs());
|
||||
var command_line = new Eina.Array<Eina.StringShare>();
|
||||
command_line.Append(Array.ConvertAll(Environment.GetCommandLineArgs(), s => (Eina.StringShare)s));
|
||||
#if EFL_BETA
|
||||
app.SetCommandArray(command_line);
|
||||
#endif
|
||||
|
@ -139,7 +139,14 @@ public abstract class Application
|
|||
{
|
||||
if (evt.arg.Initialization)
|
||||
{
|
||||
OnInitialize(evt.arg.Argv);
|
||||
int n = evt.arg.Argv.Length;
|
||||
var argv = new string[n];
|
||||
for (int i = 0; i < n; ++i)
|
||||
{
|
||||
argv[i] = evt.arg.Argv[i];
|
||||
}
|
||||
|
||||
OnInitialize(argv);
|
||||
}
|
||||
|
||||
OnArguments(evt.arg);
|
||||
|
|
|
@ -41,6 +41,19 @@ internal static class NativeCustomExportFunctions
|
|||
efl_mono_native_efl_unref_addr_get();
|
||||
}
|
||||
|
||||
// TODO: move all native functions to a "NativeFunctions" class
|
||||
internal static partial class NativeFunctions
|
||||
{
|
||||
[DllImport(efl.Libs.Eina)] public static extern IntPtr
|
||||
eina_stringshare_add(string str);
|
||||
[DllImport(efl.Libs.Eina)] public static extern void
|
||||
eina_stringshare_del(IntPtr str);
|
||||
[DllImport(efl.Libs.CustomExports)] public static extern void
|
||||
efl_mono_native_stringshare_del_ref(IntPtr str);
|
||||
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr
|
||||
efl_mono_native_stringshare_del_addr_get();
|
||||
}
|
||||
|
||||
/// <summary>Wrapper around native memory DllImport'd functions</summary>
|
||||
public static class MemoryNative
|
||||
{
|
||||
|
@ -75,6 +88,21 @@ public static class MemoryNative
|
|||
return NativeCustomExportFunctions.efl_mono_native_strdup(str);
|
||||
}
|
||||
|
||||
public static IntPtr AddStringShare(string str)
|
||||
{
|
||||
return NativeFunctions.eina_stringshare_add(str);
|
||||
}
|
||||
|
||||
public static void DelStringShare(IntPtr str)
|
||||
{
|
||||
NativeFunctions.eina_stringshare_del(str);
|
||||
}
|
||||
|
||||
public static void DelStringShareRef(IntPtr ptr)
|
||||
{
|
||||
NativeFunctions.efl_mono_native_stringshare_del_ref(ptr);
|
||||
}
|
||||
|
||||
// IntPtr's for some native functions
|
||||
public static IntPtr PtrCompareFuncPtrGet()
|
||||
{
|
||||
|
@ -91,6 +119,11 @@ public static class MemoryNative
|
|||
return NativeCustomExportFunctions.efl_mono_native_free_addr_get();
|
||||
}
|
||||
|
||||
public static IntPtr StringShareDelFuncPtrGet()
|
||||
{
|
||||
return NativeFunctions.efl_mono_native_stringshare_del_addr_get();
|
||||
}
|
||||
|
||||
public static IntPtr EflUnrefFuncPtrGet()
|
||||
{
|
||||
return NativeCustomExportFunctions.efl_mono_native_efl_unref_addr_get();
|
||||
|
@ -163,4 +196,121 @@ public enum Ownership
|
|||
Unmanaged
|
||||
}
|
||||
|
||||
/// TODO: reword this \/ \/ \/ \/ \/ \/ \/
|
||||
/// Convert to a String the quickest possible.
|
||||
/// Implements Equality/Inequality methods just because they have standard System.Object implementations that would not signal a compilation fail. The intent is not to provide full string API.
|
||||
public class StringShare : IEquatable<StringShare>, IEquatable<string>
|
||||
{
|
||||
public StringShare()
|
||||
{
|
||||
}
|
||||
|
||||
public StringShare(string s)
|
||||
{
|
||||
Str = s;
|
||||
}
|
||||
|
||||
public string Str { get; set; }
|
||||
|
||||
public static implicit operator string(StringShare ss)
|
||||
{
|
||||
if (ss == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ss.Str;
|
||||
}
|
||||
|
||||
public static implicit operator StringShare(string s)
|
||||
{
|
||||
if (s == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return new StringShare(s);
|
||||
}
|
||||
|
||||
public static bool operator==(StringShare ss1, StringShare ss2)
|
||||
{
|
||||
return ((string)ss1) == ((string)ss2);
|
||||
}
|
||||
|
||||
public static bool operator==(StringShare ss, string s)
|
||||
{
|
||||
return ((string)ss) == s;
|
||||
}
|
||||
|
||||
public static bool operator==(string s, StringShare ss)
|
||||
{
|
||||
return ss == s;
|
||||
}
|
||||
|
||||
public static bool operator!=(StringShare ss1, StringShare ss2)
|
||||
{
|
||||
return !(ss1 == ss2);
|
||||
}
|
||||
|
||||
public static bool operator!=(StringShare ss, string s)
|
||||
{
|
||||
return !(ss == s);
|
||||
}
|
||||
|
||||
public static bool operator!=(string s, StringShare ss)
|
||||
{
|
||||
return !(ss == s);
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Str;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return Str == null ? 0 : Str.GetHashCode();
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
if (ReferenceEquals(null, other))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, other))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (other.GetType() == typeof(string))
|
||||
{
|
||||
return this.Str == (string)other;
|
||||
}
|
||||
|
||||
return other.GetType() == typeof(StringShare) && this == ((StringShare)other);
|
||||
}
|
||||
|
||||
public bool Equals(StringShare other)
|
||||
{
|
||||
return this == other;
|
||||
}
|
||||
|
||||
public bool Equals(string other)
|
||||
{
|
||||
return this.Str == other;
|
||||
}
|
||||
|
||||
public void Set(string s)
|
||||
{
|
||||
Str = s;
|
||||
}
|
||||
|
||||
public string Get()
|
||||
{
|
||||
return Str;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ public enum ElementType
|
|||
{
|
||||
NumericType,
|
||||
StringType,
|
||||
StringShareType,
|
||||
ObjectType
|
||||
};
|
||||
|
||||
|
@ -195,6 +196,144 @@ public class StringElementTraits : IBaseElementTraits<string>
|
|||
}
|
||||
}
|
||||
|
||||
public class StringShareElementTraits : IBaseElementTraits<Eina.StringShare>
|
||||
{
|
||||
public StringShareElementTraits()
|
||||
{
|
||||
}
|
||||
|
||||
public IntPtr ManagedToNativeAlloc(Eina.StringShare man)
|
||||
{
|
||||
IntPtr newstring = MemoryNative.AddStringShare(man);
|
||||
return newstring;
|
||||
}
|
||||
|
||||
public IntPtr ManagedToNativeAllocInlistNode(Eina.StringShare man)
|
||||
{
|
||||
var node = new InlistNode<IntPtr>();
|
||||
node.Val = ManagedToNativeAlloc(man);
|
||||
GCHandle pinnedData = GCHandle.Alloc(node, GCHandleType.Pinned);
|
||||
IntPtr ptr = pinnedData.AddrOfPinnedObject();
|
||||
IntPtr nat = MemoryNative.AllocCopy(ptr, Marshal.SizeOf<InlistMem>() + Marshal.SizeOf<IntPtr>());
|
||||
pinnedData.Free();
|
||||
return nat;
|
||||
}
|
||||
|
||||
public void ManagedToNativeCopyTo(Eina.StringShare man, IntPtr mem)
|
||||
{
|
||||
IntPtr stringptr = ManagedToNativeAlloc(man);
|
||||
Marshal.WriteIntPtr(mem, stringptr);
|
||||
}
|
||||
|
||||
public void NativeFree(IntPtr nat)
|
||||
{
|
||||
if (nat != IntPtr.Zero)
|
||||
{
|
||||
MemoryNative.DelStringShare(nat);
|
||||
}
|
||||
}
|
||||
|
||||
public void NativeFreeInlistNodeElement(IntPtr nat)
|
||||
{
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var val = Marshal.PtrToStructure<IntPtr>
|
||||
(nat + Marshal.SizeOf<InlistMem>());
|
||||
NativeFree(val);
|
||||
}
|
||||
|
||||
public void NativeFreeInlistNode(IntPtr nat, bool freeElement)
|
||||
{
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (freeElement)
|
||||
{
|
||||
NativeFreeInlistNodeElement(nat);
|
||||
}
|
||||
|
||||
MemoryNative.Free(nat);
|
||||
}
|
||||
|
||||
public void NativeFreeInplace(IntPtr nat)
|
||||
{
|
||||
MemoryNative.DelStringShareRef(nat);
|
||||
}
|
||||
|
||||
public void ResidueFreeInplace(IntPtr nat)
|
||||
{
|
||||
}
|
||||
|
||||
public Eina.StringShare NativeToManaged(IntPtr nat)
|
||||
{
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
return default(Eina.StringShare);
|
||||
}
|
||||
|
||||
return StringConversion.NativeUtf8ToManagedString(nat);
|
||||
}
|
||||
|
||||
public Eina.StringShare NativeToManagedInlistNode(IntPtr nat)
|
||||
{
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
Eina.Log.Error("Null pointer for Inlist node.");
|
||||
return default(Eina.StringShare);
|
||||
}
|
||||
|
||||
IntPtr ptr_location = nat + Marshal.SizeOf<InlistMem>();
|
||||
return NativeToManaged(Marshal.ReadIntPtr(ptr_location));
|
||||
}
|
||||
|
||||
// Strings inplaced are always a pointer, because they are variable-sized
|
||||
public Eina.StringShare NativeToManagedInplace(IntPtr nat)
|
||||
{
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
return default(Eina.StringShare);
|
||||
}
|
||||
|
||||
nat = Marshal.ReadIntPtr(nat);
|
||||
if (nat == IntPtr.Zero)
|
||||
{
|
||||
return default(Eina.StringShare);
|
||||
}
|
||||
|
||||
return NativeToManaged(nat);
|
||||
}
|
||||
|
||||
public IntPtr EinaCompareCb()
|
||||
{
|
||||
return MemoryNative.StrCompareFuncPtrGet();
|
||||
}
|
||||
|
||||
public IntPtr EinaFreeCb()
|
||||
{
|
||||
return MemoryNative.StringShareDelFuncPtrGet();
|
||||
}
|
||||
|
||||
public IntPtr EinaHashNew()
|
||||
{
|
||||
return eina_hash_stringshared_new(IntPtr.Zero);
|
||||
}
|
||||
|
||||
public IntPtr EinaInarrayNew(uint step)
|
||||
{
|
||||
return eina_inarray_new((uint)Marshal.SizeOf<IntPtr>(), step);
|
||||
}
|
||||
|
||||
public IntPtr EinaHashIteratorKeyNew(IntPtr hash)
|
||||
{
|
||||
return eina_hash_iterator_key_new(hash);
|
||||
}
|
||||
}
|
||||
|
||||
public class EflObjectElementTraits<T> : IBaseElementTraits<T>
|
||||
{
|
||||
public IntPtr ManagedToNativeAlloc(T man)
|
||||
|
@ -709,6 +848,11 @@ public static class TraitFunctions
|
|||
return type == typeof(string);
|
||||
}
|
||||
|
||||
public static bool IsStringShare(System.Type type)
|
||||
{
|
||||
return type == typeof(Eina.StringShare);
|
||||
}
|
||||
|
||||
public static Eina.ElementType GetElementTypeCode(System.Type type)
|
||||
{
|
||||
if (IsEflObject(type))
|
||||
|
@ -719,6 +863,10 @@ public static class TraitFunctions
|
|||
{
|
||||
return ElementType.StringType;
|
||||
}
|
||||
else if (IsStringShare(type))
|
||||
{
|
||||
return ElementType.StringShareType;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ElementType.NumericType;
|
||||
|
@ -764,6 +912,10 @@ public static class TraitFunctions
|
|||
{
|
||||
traits = new StringElementTraits();
|
||||
}
|
||||
else if (IsStringShare(type))
|
||||
{
|
||||
traits = new StringShareElementTraits();
|
||||
}
|
||||
else if (type.IsValueType)
|
||||
{
|
||||
if (type == typeof(int))
|
||||
|
|
|
@ -2,6 +2,7 @@ using System;
|
|||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Efl
|
||||
{
|
||||
|
@ -9,15 +10,85 @@ namespace Efl
|
|||
namespace Eo
|
||||
{
|
||||
|
||||
#if EFL_DEBUG
|
||||
|
||||
public class SafeIntPtr
|
||||
{
|
||||
private IntPtr handle;
|
||||
private bool disposed;
|
||||
|
||||
private SafeIntPtr(IntPtr ptr)
|
||||
{
|
||||
handle = ptr;
|
||||
}
|
||||
|
||||
public static implicit operator IntPtr(SafeIntPtr ptr)
|
||||
{
|
||||
if (ptr.disposed)
|
||||
{
|
||||
throw new ObjectDisposedException("Object has been disposed");
|
||||
}
|
||||
return ptr.handle;
|
||||
}
|
||||
|
||||
public static implicit operator SafeIntPtr(IntPtr ptr)
|
||||
{
|
||||
return new SafeIntPtr(ptr);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
disposed = true;
|
||||
handle = IntPtr.Zero;
|
||||
}
|
||||
|
||||
public long ToInt64()
|
||||
{
|
||||
return handle.ToInt64();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public abstract class EoWrapper : IWrapper, IDisposable
|
||||
{
|
||||
protected readonly object eventLock = new object();
|
||||
protected bool inherited = false;
|
||||
protected System.IntPtr handle = IntPtr.Zero;
|
||||
#if EFL_DEBUG
|
||||
protected SafeIntPtr handle;
|
||||
#else
|
||||
protected IntPtr handle;
|
||||
#endif
|
||||
|
||||
private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback);
|
||||
private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback);
|
||||
|
||||
|
||||
/// <summary>Constructor to be used when objects are expected to be constructed from native code.
|
||||
/// For a class that inherited from an EFL# class to be properly constructed from native code
|
||||
/// one must create a constructor with this signature and calls this base constructor from it.
|
||||
/// This constructor will take care of calling base constructors of the native classes and
|
||||
/// perform additional setup so objects are ready to use.
|
||||
/// It is advisable to check for the <see cref="NativeHandle"/> property in the top level
|
||||
/// constructor and signal an error when it has a value of IntPtr.Zero after this
|
||||
/// constructor completion.
|
||||
/// Warning: Do not use this constructor directly from a `new` statement.</summary>
|
||||
/// <param name="ch">Tag struct storing the native handle of the object being constructed.</param>
|
||||
protected EoWrapper(ConstructingHandle ch)
|
||||
{
|
||||
handle = Efl.Eo.Globals.efl_constructor(Efl.Eo.Globals.efl_super(ch.NativeHandle, Efl.Eo.Globals.efl_class_get(ch.NativeHandle)));
|
||||
if (handle == IntPtr.Zero)
|
||||
{
|
||||
Eina.Log.Warning("Natice constructor returned NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
AddWrapperSupervisor();
|
||||
// Make an additional reference to C#
|
||||
// - Will also call EVENT_OWNERSHIP_SHARED
|
||||
Efl.Eo.Globals.efl_ref(handle);
|
||||
}
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="Object"/> class.
|
||||
/// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>
|
||||
/// <param name="raw">The native pointer to be wrapped.</param>
|
||||
|
@ -54,7 +125,17 @@ public abstract class EoWrapper : IWrapper, IDisposable
|
|||
parent_ptr = parent.NativeHandle;
|
||||
}
|
||||
|
||||
handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0);
|
||||
if (!inherited)
|
||||
{
|
||||
handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
handle = Efl.Eo.Globals._efl_add_internal_start_bindings(file, line, actual_klass, parent_ptr, 1, 0,
|
||||
Efl.Eo.Globals.efl_mono_avoid_top_level_constructor_callback_addr_get(),
|
||||
IntPtr.Zero);
|
||||
}
|
||||
|
||||
if (handle == System.IntPtr.Zero)
|
||||
{
|
||||
throw new Exception("Instantiation failed");
|
||||
|
@ -91,7 +172,11 @@ public abstract class EoWrapper : IWrapper, IDisposable
|
|||
if (disposing && handle != System.IntPtr.Zero)
|
||||
{
|
||||
IntPtr h = handle;
|
||||
#if EFL_DEBUG
|
||||
handle.Dispose();
|
||||
#else
|
||||
handle = IntPtr.Zero;
|
||||
#endif
|
||||
Efl.Eo.Globals.efl_mono_native_dispose(h);
|
||||
}
|
||||
else
|
||||
|
@ -103,6 +188,9 @@ public abstract class EoWrapper : IWrapper, IDisposable
|
|||
}
|
||||
|
||||
Monitor.Exit(Efl.All.InitLock);
|
||||
#if EFL_DEBUG
|
||||
handle.Dispose();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,7 +198,7 @@ public abstract class EoWrapper : IWrapper, IDisposable
|
|||
/// <returns>A string with the type and the native pointer for this object.</returns>
|
||||
public override String ToString()
|
||||
{
|
||||
return $"{this.GetType().Name}@[0x{(UInt64)handle:x}]";
|
||||
return $"{this.GetType().Name}@[0x{handle.ToInt64():x}]";
|
||||
}
|
||||
|
||||
/// <summary>Releases the underlying native instance.</summary>
|
||||
|
@ -246,8 +334,72 @@ public abstract class EoWrapper : IWrapper, IDisposable
|
|||
AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_SHARED", ownershipSharedDelegate, ownershipSharedDelegate);
|
||||
Eina.Error.RaiseIfUnhandledException();
|
||||
}
|
||||
|
||||
protected struct ConstructingHandle
|
||||
{
|
||||
public ConstructingHandle(IntPtr h)
|
||||
{
|
||||
NativeHandle = h;
|
||||
}
|
||||
|
||||
public IntPtr NativeHandle { get; set; }
|
||||
}
|
||||
|
||||
public abstract class NativeMethods : Efl.Eo.NativeClass
|
||||
{
|
||||
private static EflConstructorSelegate csharpEflConstructorStaticDelegate = new EflConstructorSelegate(Constructor);
|
||||
private static Efl.Eo.NativeModule EoModule = new Efl.Eo.NativeModule("eo");
|
||||
|
||||
private delegate IntPtr EflConstructorSelegate(IntPtr obj, IntPtr pd);
|
||||
|
||||
public override System.Collections.Generic.List<Efl_Op_Description> GetEoOps(Type type)
|
||||
{
|
||||
var descs = new System.Collections.Generic.List<Efl_Op_Description>();
|
||||
|
||||
descs.Add(new Efl_Op_Description()
|
||||
{
|
||||
api_func = Efl.Eo.FunctionInterop.LoadFunctionPointer(EoModule.Module, "efl_constructor"),
|
||||
func = Marshal.GetFunctionPointerForDelegate(csharpEflConstructorStaticDelegate)
|
||||
});
|
||||
|
||||
return descs;
|
||||
}
|
||||
|
||||
private static IntPtr Constructor(IntPtr obj, IntPtr pd)
|
||||
{
|
||||
try
|
||||
{
|
||||
var eoKlass = Efl.Eo.Globals.efl_class_get(obj);
|
||||
var managedType = ClassRegister.GetManagedType(eoKlass);
|
||||
if (managedType == null)
|
||||
{
|
||||
IntPtr nativeName = Efl.Eo.Globals.efl_class_name_get(eoKlass);
|
||||
var name = Eina.StringConversion.NativeUtf8ToManagedString(nativeName);
|
||||
Eina.Log.Warning($"Can't get Managed class for object handle 0x{(UInt64)obj:x} with native class [{name}]");
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
var flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
ConstructorInfo constructor = managedType.GetConstructor(flags, null, new Type[1] { typeof(ConstructingHandle) }, null);
|
||||
var eoWrapper = (Efl.Eo.IWrapper) constructor.Invoke(new object[1] { new ConstructingHandle(obj) });
|
||||
if (eoWrapper == null)
|
||||
{
|
||||
Eina.Log.Warning("Constructor was unable to create a new object");
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
|
||||
return eoWrapper.NativeHandle;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Eina.Log.Warning($"Inherited constructor error: {e.ToString()}");
|
||||
Eina.Error.Set(Eina.Error.UNHANDLED_EXCEPTION);
|
||||
return IntPtr.Zero;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Global
|
||||
} // namespace Eo
|
||||
|
||||
} // namespace Efl
|
||||
|
|
|
@ -44,10 +44,6 @@ public class Globals
|
|||
public static FunctionWrapper<efl_object_shutdown_delegate> efl_object_shutdown_ptr = new FunctionWrapper<efl_object_shutdown_delegate>(efl.Libs.EoModule, "efl_object_shutdown");
|
||||
public static void efl_object_shutdown() => efl_object_shutdown_ptr.Value.Delegate();
|
||||
// [DllImport(efl.Libs.Eo)] public static extern void efl_object_shutdown();
|
||||
public static FunctionWrapper<_efl_add_internal_start_delegate> _efl_add_internal_start_ptr = new FunctionWrapper<_efl_add_internal_start_delegate>(efl.Libs.EoModule, "_efl_add_internal_start");
|
||||
public delegate IntPtr
|
||||
_efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line,
|
||||
IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
|
||||
|
||||
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_wrapper_supervisor_get(IntPtr eo);
|
||||
[DllImport(efl.Libs.CustomExports)] public static extern void efl_mono_wrapper_supervisor_set(IntPtr eo, IntPtr ws);
|
||||
|
@ -55,6 +51,9 @@ public class Globals
|
|||
[DllImport(efl.Libs.Eo)] public static extern IntPtr
|
||||
_efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line,
|
||||
IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
|
||||
[DllImport(efl.Libs.Eo)] public static extern IntPtr
|
||||
_efl_add_internal_start_bindings([MarshalAs(UnmanagedType.LPStr)] String file, int line, IntPtr klass, IntPtr parent,
|
||||
byte is_ref, byte is_fallback, IntPtr substitute_ctor, IntPtr data);
|
||||
public delegate IntPtr
|
||||
_efl_add_end_delegate(IntPtr eo, byte is_ref, byte is_fallback);
|
||||
[DllImport(efl.Libs.Eo)] public static extern IntPtr
|
||||
|
@ -196,6 +195,10 @@ public class Globals
|
|||
public delegate IntPtr dlerror_delegate();
|
||||
[DllImport(efl.Libs.Evil)] public static extern IntPtr dlerror();
|
||||
|
||||
[DllImport(efl.Libs.Eo)] public static extern IntPtr efl_constructor(IntPtr obj);
|
||||
|
||||
[DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_avoid_top_level_constructor_callback_addr_get();
|
||||
|
||||
[DllImport(efl.Libs.Eo)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
|
||||
efl_event_callback_priority_add(IntPtr obj, IntPtr desc, short priority, IntPtr cb, IntPtr data);
|
||||
|
||||
|
|
|
@ -148,6 +148,10 @@ if get_option('mono-beta')
|
|||
extra_cs_args += '-d:EFL_BETA'
|
||||
endif
|
||||
|
||||
if get_option('buildtype') == 'debug'
|
||||
extra_cs_args += '-d:EFL_DEBUG'
|
||||
endif
|
||||
|
||||
efl_mono_install_dir = join_paths(dir_lib, 'efl-mono-'+version_major)
|
||||
efl_mono_xml_doc = join_paths(meson.current_build_dir(), 'efl_mono.xml')
|
||||
|
||||
|
|
|
@ -125,6 +125,12 @@ EAPI void efl_mono_native_free_ref(void **ptr)
|
|||
free(*ptr);
|
||||
}
|
||||
|
||||
EAPI void efl_mono_native_stringshare_del_ref(void **str)
|
||||
{
|
||||
if (!str) return;
|
||||
eina_stringshare_del(*str);
|
||||
}
|
||||
|
||||
EAPI void *efl_mono_native_alloc_copy(const void *val, unsigned int size)
|
||||
{
|
||||
if (!val) return NULL;
|
||||
|
@ -161,11 +167,26 @@ EAPI Eina_Free_Cb efl_mono_native_free_addr_get()
|
|||
return (Eina_Free_Cb)free;
|
||||
}
|
||||
|
||||
EAPI Eina_Free_Cb efl_mono_native_stringshare_del_addr_get()
|
||||
{
|
||||
return (Eina_Free_Cb)eina_stringshare_del;
|
||||
}
|
||||
|
||||
EAPI Eina_Free_Cb efl_mono_native_efl_unref_addr_get()
|
||||
{
|
||||
return (Eina_Free_Cb)efl_mono_thread_safe_efl_unref;
|
||||
}
|
||||
|
||||
static Eo *_efl_mono_avoid_top_level_constructor_cb(void *data EINA_UNUSED, Eo *obj)
|
||||
{
|
||||
return efl_constructor(efl_super(obj, efl_class_get(obj)));
|
||||
}
|
||||
|
||||
EAPI Efl_Substitute_Ctor_Cb efl_mono_avoid_top_level_constructor_callback_addr_get()
|
||||
{
|
||||
return &_efl_mono_avoid_top_level_constructor_cb;
|
||||
}
|
||||
|
||||
// Iterator Wrapper //
|
||||
|
||||
typedef struct _Eina_Iterator_Wrapper_Mono
|
||||
|
|
|
@ -1539,6 +1539,35 @@ EAPI Eo *_efl_added_get(void);
|
|||
|
||||
EAPI Eo * _efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent, Eina_Bool ref, Eina_Bool is_fallback);
|
||||
|
||||
/**
|
||||
* @typedef Efl_Substitute_Ctor_Cb
|
||||
* Callback to be called instead of the object constructor.
|
||||
*
|
||||
* Only intended for binding creators.
|
||||
*
|
||||
* @param data Additional data previously supplied by the user
|
||||
* @param obj_id The object being constructed.
|
||||
* @return The constructed object in case of success, NULL otherwise.
|
||||
*/
|
||||
typedef Eo *(*Efl_Substitute_Ctor_Cb)(void *data, Eo *obj_id);
|
||||
|
||||
/**
|
||||
* @brief Just like _efl_add_internal_start() but with additional options
|
||||
*
|
||||
* Only intended for binding creators.
|
||||
*
|
||||
* @param file File name of the call site, used for debug logs.
|
||||
* @param line Line number of the call site, used for debug logs.
|
||||
* @param klass_id Pointer for the class being instantiated.
|
||||
* @param ref Whether or not the object will have an additional reference if it has a parent.
|
||||
* @param parent Object parent, can be NULL.
|
||||
* @param is_fallback Whether or not the fallback @c efl_added behaviour is to be used.
|
||||
* @param substitute_ctor Optional callback to replace the call for efl_constructor(), if NULL efl_constructor() will be called normally.
|
||||
* @param sub_ctor_data Additional data to be passed to the @p substitute_ctor callback.
|
||||
* @return An handle to the new object on success, NULL otherwise.
|
||||
*/
|
||||
EAPI Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data);
|
||||
|
||||
/**
|
||||
* @brief Unrefs the object and reparents it to NULL.
|
||||
*
|
||||
|
|
|
@ -857,8 +857,8 @@ err_klass:
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
EAPI Eo *
|
||||
_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback)
|
||||
static Eo *
|
||||
_efl_add_internal_start_do(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data)
|
||||
{
|
||||
const char *func_name = __FUNCTION__;
|
||||
_Eo_Object *obj;
|
||||
|
@ -918,7 +918,8 @@ _efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, E
|
|||
if (parent_id) efl_parent_set(eo_id, parent_id);
|
||||
|
||||
/* eo_id can change here. Freeing is done on the resolved object. */
|
||||
eo_id = efl_constructor(eo_id);
|
||||
if (!substitute_ctor) eo_id = efl_constructor(eo_id);
|
||||
else eo_id = substitute_ctor(sub_ctor_data, eo_id);
|
||||
// not likely so use goto to alleviate l1 instruction cache of rare code
|
||||
if (!eo_id) goto err_noid;
|
||||
// not likely so use goto to alleviate l1 instruction cache of rare code
|
||||
|
@ -962,6 +963,17 @@ err_parent:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
EAPI Eo *
|
||||
_efl_add_internal_start(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback)
|
||||
{
|
||||
return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, NULL, NULL);
|
||||
}
|
||||
|
||||
EAPI Eo * _efl_add_internal_start_bindings(const char *file, int line, const Efl_Class *klass_id, Eo *parent_id, Eina_Bool ref, Eina_Bool is_fallback, Efl_Substitute_Ctor_Cb substitute_ctor, void *sub_ctor_data)
|
||||
{
|
||||
return _efl_add_internal_start_do(file, line, klass_id, parent_id, ref, is_fallback, substitute_ctor, sub_ctor_data);
|
||||
}
|
||||
|
||||
static Eo *
|
||||
_efl_add_internal_end(Eo *eo_id, Eo *finalized_id)
|
||||
{
|
||||
|
|
|
@ -492,6 +492,14 @@ class TestEinaArray
|
|||
Test.AssertEquals("test string §éΨبÿツ", a[0]);
|
||||
}
|
||||
|
||||
public static void push_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.StringShare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Push("test string §éΨبÿツ"));
|
||||
Test.AssertEquals("test string §éΨبÿツ", a[0].Str);
|
||||
}
|
||||
|
||||
public static void push_obj()
|
||||
{
|
||||
var a = new Eina.Array<Dummy.Numberwrapper>();
|
||||
|
@ -521,6 +529,15 @@ class TestEinaArray
|
|||
Test.Assert(a.Count() == 0);
|
||||
}
|
||||
|
||||
public static void pop_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.StringShare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Push("test string"));
|
||||
Test.Assert(a.Pop() == "test string");
|
||||
Test.Assert(a.Count() == 0);
|
||||
}
|
||||
|
||||
public static void pop_obj()
|
||||
{
|
||||
var a = new Eina.Array<Dummy.Numberwrapper>();
|
||||
|
@ -558,6 +575,18 @@ class TestEinaArray
|
|||
Test.Assert(a[0] == "abc");
|
||||
}
|
||||
|
||||
public static void data_set_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.StringShare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Push("test string"));
|
||||
Test.Assert(a[0] == "test string");
|
||||
a.DataSet(0, "other string");
|
||||
Test.Assert(a[0] == "other string");
|
||||
a[0] = "abc";
|
||||
Test.Assert(a[0] == "abc");
|
||||
}
|
||||
|
||||
public static void data_set_obj()
|
||||
{
|
||||
var a = new Eina.Array<Dummy.Numberwrapper>();
|
||||
|
@ -617,6 +646,22 @@ class TestEinaArray
|
|||
Test.Assert(a.Count() == 3);
|
||||
}
|
||||
|
||||
public static void count_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.StringShare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Count() == 0);
|
||||
Test.Assert(a.Push("a"));
|
||||
Test.Assert(a[0] == "a");
|
||||
Test.Assert(a.Count() == 1);
|
||||
Test.Assert(a.Push("b"));
|
||||
Test.Assert(a[1] == "b");
|
||||
Test.Assert(a.Count() == 2);
|
||||
Test.Assert(a.Push("c"));
|
||||
Test.Assert(a[2] == "c");
|
||||
Test.Assert(a.Count() == 3);
|
||||
}
|
||||
|
||||
public static void count_obj()
|
||||
{
|
||||
var a = new Eina.Array<Dummy.Numberwrapper>();
|
||||
|
@ -678,6 +723,22 @@ class TestEinaArray
|
|||
Test.Assert(a.Length == 3);
|
||||
}
|
||||
|
||||
public static void length_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.Stringshare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Length == 0);
|
||||
Test.Assert(a.Push("a"));
|
||||
Test.Assert(a[0] == "a");
|
||||
Test.Assert(a.Length == 1);
|
||||
Test.Assert(a.Push("b"));
|
||||
Test.Assert(a[1] == "b");
|
||||
Test.Assert(a.Length == 2);
|
||||
Test.Assert(a.Push("c"));
|
||||
Test.Assert(a[2] == "c");
|
||||
Test.Assert(a.Length == 3);
|
||||
}
|
||||
|
||||
public static void eina_array_as_ienumerable_int()
|
||||
{
|
||||
var a = new Eina.Array<int>();
|
||||
|
@ -710,6 +771,22 @@ class TestEinaArray
|
|||
}
|
||||
}
|
||||
|
||||
public static void eina_array_as_ienumerable_stringshare()
|
||||
{
|
||||
var a = new Eina.Array<Eina.StringShare>();
|
||||
Test.Assert(a.Handle != IntPtr.Zero);
|
||||
Test.Assert(a.Push("X"));
|
||||
Test.Assert(a.Push("XX"));
|
||||
Test.Assert(a.Push("XXX"));
|
||||
|
||||
string cmp = "X";
|
||||
foreach (string e in a)
|
||||
{
|
||||
Test.AssertEquals(cmp, e);
|
||||
cmp = cmp + "X";
|
||||
}
|
||||
}
|
||||
|
||||
public static void eina_array_as_ienumerable_obj()
|
||||
{
|
||||
var a = new Dummy.Numberwrapper();
|
||||
|
@ -888,6 +965,80 @@ class TestEinaArray
|
|||
Test.Assert(arr.Handle == IntPtr.Zero);
|
||||
}
|
||||
|
||||
// Eina.Stringshare //
|
||||
public static void test_eina_array_strshare_in()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var arr = new Eina.Array<Eina.StringShare>();
|
||||
arr.Append(base_seq_str);
|
||||
Test.Assert(t.EinaArrayStrShareIn(arr));
|
||||
Test.Assert(arr.Own);
|
||||
Test.Assert(arr.ToArray().SequenceEqual(modified_seq_str));
|
||||
arr.Dispose();
|
||||
Test.Assert(arr.Handle == IntPtr.Zero);
|
||||
}
|
||||
|
||||
public static void test_eina_array_strshare_in_own()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var arr = new Eina.Array<Eina.StringShare>();
|
||||
arr.Append(base_seq_str);
|
||||
Test.Assert(t.EinaArrayStrShareInOwn(arr));
|
||||
Test.Assert(!arr.Own);
|
||||
Test.Assert(arr.ToArray().SequenceEqual(modified_seq_str));
|
||||
arr.Dispose();
|
||||
Test.Assert(arr.Handle == IntPtr.Zero);
|
||||
Test.Assert(t.CheckEinaArrayStrShareInOwn());
|
||||
}
|
||||
|
||||
public static void test_eina_array_strshare_out()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
Eina.Array<Eina.StringShare> arr;
|
||||
Test.Assert(t.EinaArrayStrShareOut(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(t.CheckEinaArrayStrShareOut());
|
||||
}
|
||||
|
||||
public static void test_eina_array_strshare_out_own()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
Eina.Array<Eina.StringShare> arr;
|
||||
Test.Assert(t.EinaArrayStrShareOutOwn(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);
|
||||
}
|
||||
|
||||
public static void test_eina_array_strshare_return()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var arr = t.EinaArrayStrShareReturn();
|
||||
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(t.CheckEinaArrayStrShareReturn());
|
||||
}
|
||||
|
||||
public static void test_eina_array_strshare_return_own()
|
||||
{
|
||||
var t = new Dummy.TestObject();
|
||||
var arr = t.EinaArrayStrShareReturnOwn();
|
||||
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);
|
||||
}
|
||||
|
||||
// Object //
|
||||
|
||||
public static void test_eina_array_obj_in()
|
||||
|
|
|
@ -522,6 +522,10 @@ class TestObjectDeletion
|
|||
part.Del();
|
||||
|
||||
Test.AssertNull(obj.OnePart);
|
||||
|
||||
#if EFL_DEBUG
|
||||
Test.AssertRaises<ObjectDisposedException>(() => part.SetParent(null));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,79 @@
|
|||
using System;
|
||||
|
||||
class InheritedConstructibleObject : Dummy.ConstructibleObject
|
||||
{
|
||||
public InheritedConstructibleObject()
|
||||
{
|
||||
if (this.NativeConstructionCount != 1)
|
||||
{
|
||||
DefaultConstrutorCallCount = -100;
|
||||
}
|
||||
|
||||
++DefaultConstrutorCallCount;
|
||||
this.IncrementDefaultConstructionCount();
|
||||
}
|
||||
|
||||
private InheritedConstructibleObject(ConstructingHandle ch) : base(ch)
|
||||
{
|
||||
if (this.NativeConstructionCount != 1)
|
||||
{
|
||||
SpecialConstrutorCallCount = -100;
|
||||
}
|
||||
|
||||
++SpecialConstrutorCallCount;
|
||||
this.IncrementSpecialConstructionCount();
|
||||
}
|
||||
|
||||
public int DefaultConstrutorCallCount { get; set; } = 0;
|
||||
public int SpecialConstrutorCallCount { get; set; } = 0;
|
||||
}
|
||||
|
||||
namespace TestSuite
|
||||
{
|
||||
|
||||
class TestEoConstruction
|
||||
{
|
||||
public static void TestGeneratedEoDirectConstruction()
|
||||
{
|
||||
var obj = new Dummy.ConstructibleObject();
|
||||
Test.AssertEquals(obj.NativeConstructionCount, 1);
|
||||
Test.AssertEquals(obj.DefaultConstructionCount, 0);
|
||||
Test.AssertEquals(obj.SpecialConstructionCount, 0);
|
||||
obj.Dispose();
|
||||
}
|
||||
|
||||
public static void TestInheritedEoDirectConstruction()
|
||||
{
|
||||
var obj = new InheritedConstructibleObject();
|
||||
Test.AssertEquals(obj.NativeConstructionCount, 1);
|
||||
Test.AssertEquals(obj.DefaultConstructionCount, 1);
|
||||
Test.AssertEquals(obj.SpecialConstructionCount, 0);
|
||||
Test.AssertEquals(obj.DefaultConstrutorCallCount, 1);
|
||||
Test.AssertEquals(obj.SpecialConstrutorCallCount, 0);
|
||||
obj.Dispose();
|
||||
}
|
||||
|
||||
public static void TestInheritedEoIndirectConstruction()
|
||||
{
|
||||
var obj = new Dummy.ConstructibleObject();
|
||||
Test.AssertEquals(obj.NativeConstructionCount, 1);
|
||||
Test.AssertEquals(obj.DefaultConstructionCount, 0);
|
||||
Test.AssertEquals(obj.SpecialConstructionCount, 0);
|
||||
|
||||
var obj2 = (InheritedConstructibleObject) obj.ConstructTypeAndStore(typeof(InheritedConstructibleObject));
|
||||
Test.AssertEquals(obj2.NativeConstructionCount, 1);
|
||||
Test.AssertEquals(obj2.DefaultConstructionCount, 0);
|
||||
Test.AssertEquals(obj2.SpecialConstructionCount, 1);
|
||||
Test.AssertEquals(obj2.DefaultConstrutorCallCount, 0);
|
||||
Test.AssertEquals(obj2.SpecialConstrutorCallCount, 1);
|
||||
|
||||
var internalObj = obj.InternalObject;
|
||||
Test.Assert(obj2 == internalObj); // Ensure it always use the same object instance
|
||||
Test.AssertEquals(obj2.NativeConstructionCount, 1); // And that constructors are not called again
|
||||
|
||||
obj.Dispose();
|
||||
obj2.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
#include "libefl_mono_native_test.h"
|
||||
|
||||
typedef struct _Dummy_Constructible_Object_Data
|
||||
{
|
||||
Eo *internal_obj;
|
||||
int native_construction_count;
|
||||
int default_construction_count;
|
||||
int special_construction_count;
|
||||
} Dummy_Constructible_Object_Data;
|
||||
|
||||
|
||||
EOLIAN static Eo *
|
||||
_dummy_constructible_object_efl_object_constructor(Eo *obj, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
++(pd->native_construction_count);
|
||||
return efl_constructor(efl_super(obj, DUMMY_CONSTRUCTIBLE_OBJECT_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_dummy_constructible_object_efl_object_destructor(Eo *obj, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
if (pd->internal_obj)
|
||||
efl_unref(pd->internal_obj);
|
||||
efl_destructor(efl_super(obj, DUMMY_CONSTRUCTIBLE_OBJECT_CLASS));
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_dummy_constructible_object_construct_type_and_store(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd, const Efl_Class *klass)
|
||||
{
|
||||
pd->internal_obj = efl_add_ref(klass, NULL);
|
||||
return pd->internal_obj;
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_dummy_constructible_object_increment_default_construction_count(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
++(pd->default_construction_count);
|
||||
}
|
||||
|
||||
EOLIAN static void
|
||||
_dummy_constructible_object_increment_special_construction_count(Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
++(pd->special_construction_count);
|
||||
}
|
||||
|
||||
EOLIAN static int
|
||||
_dummy_constructible_object_native_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
return pd->native_construction_count;
|
||||
}
|
||||
|
||||
EOLIAN static int
|
||||
_dummy_constructible_object_default_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
return pd->default_construction_count;
|
||||
}
|
||||
|
||||
EOLIAN static int
|
||||
_dummy_constructible_object_special_construction_count_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
return pd->special_construction_count;
|
||||
}
|
||||
|
||||
EOLIAN static Efl_Object *
|
||||
_dummy_constructible_object_internal_object_get(const Eo *obj EINA_UNUSED, Dummy_Constructible_Object_Data *pd)
|
||||
{
|
||||
return pd->internal_obj;
|
||||
}
|
||||
|
||||
#include "dummy_constructible_object.eo.c"
|
|
@ -0,0 +1,47 @@
|
|||
class Dummy.Constructible_Object extends Efl.Object {
|
||||
methods {
|
||||
construct_type_and_store {
|
||||
params {
|
||||
@in type: const(Efl.Class);
|
||||
}
|
||||
return: Efl.Object;
|
||||
}
|
||||
increment_default_construction_count {
|
||||
}
|
||||
increment_special_construction_count {
|
||||
}
|
||||
@property native_construction_count {
|
||||
get {
|
||||
}
|
||||
values {
|
||||
value: int;
|
||||
}
|
||||
}
|
||||
@property default_construction_count {
|
||||
get {
|
||||
}
|
||||
values {
|
||||
value: int;
|
||||
}
|
||||
}
|
||||
@property special_construction_count {
|
||||
get {
|
||||
}
|
||||
values {
|
||||
value: int;
|
||||
}
|
||||
}
|
||||
@property internal_object {
|
||||
get {
|
||||
}
|
||||
values {
|
||||
value: Efl.Object;
|
||||
}
|
||||
}
|
||||
}
|
||||
implements {
|
||||
Efl.Object.constructor;
|
||||
Efl.Object.destructor;
|
||||
}
|
||||
}
|
||||
|
|
@ -56,9 +56,9 @@ Dummy_Numberwrapper **_new_obj_ref(int n)
|
|||
return &r;
|
||||
}
|
||||
|
||||
// ############ //
|
||||
// Test.Testing //
|
||||
// ############ //
|
||||
// ################# //
|
||||
// Dummy.Test_Object //
|
||||
// ################# //
|
||||
|
||||
static Efl_Object*
|
||||
_dummy_test_object_efl_object_constructor(Eo *obj, Dummy_Test_Object_Data *pd)
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "dummy_inherit_helper.eo.h"
|
||||
#include "dummy_part_holder.eo.h"
|
||||
#include "dummy_event_manager.eo.h"
|
||||
#include "dummy_constructible_object.eo.h"
|
||||
|
||||
#include <interfaces/efl_part.eo.h>
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ eo_files = [
|
|||
'dummy_inherit_iface.eo',
|
||||
'dummy_part_holder.eo',
|
||||
'dummy_event_manager.eo',
|
||||
'dummy_constructible_object.eo',
|
||||
]
|
||||
|
||||
eo_file_targets = []
|
||||
|
@ -33,6 +34,7 @@ efl_mono_native_test = library('efl_mono_native_test',
|
|||
'dummy_part_holder.c',
|
||||
'dummy_test_object.c',
|
||||
'dummy_event_manager.c',
|
||||
'dummy_constructible_object.c',
|
||||
],
|
||||
dependencies : [ecore, eo, efl],
|
||||
)
|
||||
|
@ -65,6 +67,7 @@ efl_mono_src = [
|
|||
'Eldbus.cs',
|
||||
'Eo.cs',
|
||||
'EoPromises.cs',
|
||||
'EoConstruction.cs',
|
||||
'Errors.cs',
|
||||
'Events.cs',
|
||||
'FunctionPointers.cs',
|
||||
|
|
Loading…
Reference in New Issue