aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2018-12-21 00:15:17 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-01-14 16:18:05 +0900
commitede219c45334afe88f4f6e08a05ac67dd289ac28 (patch)
treec6cde107a1fb50adabb0c5dd17bc3c5978646568
parentefl-mono: Share test data among other files. (diff)
downloadefl-ede219c45334afe88f4f6e08a05ac67dd289ac28.tar.gz
efl-mono: Fix marshalling of struct in event data.
Summary: Previously, we just converted through PtrToStructure, which didn't have the full marshalling info converting from the internal one to the external. This fixes the usage of the Efl.Loop.arguments event. Also renamed the ToExternal methods to ToManaged, to make clearer that the output struct is the one intended to be used from the managed code. Also fixed a minor styling in the generated code (making it easier to be inspected). Depends on https://phab.enlightenment.org/D7538 Reviewers: segfaultxavi, felipealmeida, bu5hm4n Reviewed By: bu5hm4n Subscribers: bu5hm4n, cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D7539
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh25
-rw-r--r--src/bin/eolian_mono/eolian/mono/parameter.hh8
-rw-r--r--src/bin/eolian_mono/eolian/mono/struct_definition.hh22
-rw-r--r--src/tests/efl_mono/Events.cs16
-rw-r--r--src/tests/efl_mono/dummy_test_object.eo7
-rw-r--r--src/tests/efl_mono/libefl_mono_native_test.c4
6 files changed, 62 insertions, 20 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index 6e02765366..22849a9fcb 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -25,10 +25,19 @@ struct unpack_event_args_visitor
std::string const& arg = "evt.Info";
std::string arg_type = name_helpers::type_full_managed_name(regular);
- // Structs are usually passed by pointer to events, like having a ptr<> modifier
- if (type.is_ptr || regular.is_struct())
- return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))")
+ if (regular.is_struct())
+ {
+ // Structs are usually passed by pointer to events, like having a ptr<> modifier
+ // Uses implicit conversion from IntPtr
+ return as_generator(
+ " evt.Info;"
+ ).generate(sink, attributes::unused, *context);
+ }
+ else if (type.is_ptr)
+ {
+ return as_generator("(" + arg_type + ")Marshal.PtrToStructure(" + arg + ", typeof(" + arg_type + "))")
.generate(sink, attributes::unused, *context);
+ }
using attributes::regular_type_def;
struct match
@@ -84,21 +93,15 @@ struct event_argument_wrapper_generator
return true;
std::string evt_name = name_helpers::managed_event_name(evt.name);
- std::string arg_type;
- if (!as_generator(type).generate(std::back_inserter(arg_type), *etype, efl::eolian::grammar::context_null()))
- {
- EINA_CXX_DOM_LOG_ERR(eolian_mono::domain) << "Failed to get argument type for event " << evt.name;
- return false;
- }
return as_generator("///<summary>Event argument wrapper for event <see cref=\""
<< join_namespaces(evt.klass.namespaces, '.', managed_namespace)
<< klass_interface_name(evt.klass) << "." << evt_name << "\"/>.</summary>\n"
<< "public class " << name_helpers::managed_event_args_short_name(evt) << " : EventArgs {\n"
<< scope_tab << "///<summary>Actual event payload.</summary>\n"
- << scope_tab << "public " << arg_type << " arg { get; set; }\n"
+ << scope_tab << "public " << type << " arg { get; set; }\n"
<< "}\n"
- ).generate(sink, attributes::unused, context);
+ ).generate(sink, *etype, context);
}
} const event_argument_wrapper {};
diff --git a/src/bin/eolian_mono/eolian/mono/parameter.hh b/src/bin/eolian_mono/eolian/mono/parameter.hh
index 70d22fb97e..416cacbe69 100644
--- a/src/bin/eolian_mono/eolian/mono/parameter.hh
+++ b/src/bin/eolian_mono/eolian/mono/parameter.hh
@@ -559,7 +559,7 @@ struct native_convert_in_variable_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
- "var " << string << " = " << type << "_StructConversion.ToExternal(" << escape_keyword(param.param_name) << ");\n"
+ "var " << string << " = " << type << "_StructConversion.ToManaged(" << 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_Binbuf *" || param.type.c_type == "const Eina_Binbuf *")
@@ -898,7 +898,7 @@ struct convert_out_assign_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
- string << " = " << type << "_StructConversion.ToExternal(" << out_variable_name(param.param_name) << ");\n"
+ string << " = " << type << "_StructConversion.ToManaged(" << out_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
else if (param_is_acceptable(param, "Eina_Binbuf *", WANT_OWN, WANT_OUT)
@@ -1002,7 +1002,7 @@ struct convert_in_ptr_assign_generator
if (param_should_use_in_var(param, true) && param.type.is_ptr && !param.type.has_own && helpers::need_struct_conversion(regular))
{
return as_generator(
- string << " = " << type << "_StructConversion.ToExternal(" << in_variable_name(param.param_name) << ");\n"
+ string << " = " << type << "_StructConversion.ToManaged(" << in_variable_name(param.param_name) << ");\n"
).generate(sink, std::make_tuple(escape_keyword(param.param_name), param.type), context);
}
@@ -1040,7 +1040,7 @@ struct convert_return_generator
else if (helpers::need_struct_conversion(regular))
{
return as_generator(
- "return " << type << "_StructConversion.ToExternal(_ret_var);\n"
+ "return " << type << "_StructConversion.ToManaged(_ret_var);\n"
).generate(sink, ret_type, context);
}
else if (ret_type.c_type == "Eina_Binbuf *" || ret_type.c_type == "const Eina_Binbuf *")
diff --git a/src/bin/eolian_mono/eolian/mono/struct_definition.hh b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
index 99347ed1dc..0eda387668 100644
--- a/src/bin/eolian_mono/eolian/mono/struct_definition.hh
+++ b/src/bin/eolian_mono/eolian/mono/struct_definition.hh
@@ -56,6 +56,8 @@ struct struct_definition_generator
return false;
}
+ auto struct_name = binding_struct_name(struct_);
+
// Check whether this is an extern struct without declared fields in .eo file and generate a
// placeholder field if positive.
// Mono's JIT is picky when generating function pointer for delegates with empty structs, leading to
@@ -68,7 +70,6 @@ struct struct_definition_generator
else
{
// Constructor with default parameters for easy struct initialization
- auto struct_name = binding_struct_name(struct_);
if(!as_generator(
scope_tab << "///<summary>Constructor for " << string << ".</summary>\n"
<< scope_tab << "public " << string << "(\n"
@@ -81,6 +82,16 @@ struct struct_definition_generator
return false;
}
+ if(!as_generator(
+ "public static implicit operator " << struct_name << "(IntPtr ptr)\n"
+ << scope_tab << "{\n"
+ << scope_tab << scope_tab << "var tmp = (" << struct_name << "_StructInternal)Marshal.PtrToStructure(ptr, typeof(" << struct_name << "_StructInternal));\n"
+ << scope_tab << scope_tab << "return " << struct_name << "_StructConversion.ToManaged(tmp);\n"
+ << scope_tab << "}\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+
+
if(!as_generator("}\n").generate(sink, attributes::unused, context)) return false;
return true;
@@ -120,7 +131,8 @@ struct struct_internal_definition_generator
.generate(sink, nullptr, context))
return false;
}
- else if (!as_generator(eolian_mono::marshall_annotation(false) << " public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
+ else if (!as_generator(scope_tab << eolian_mono::marshall_annotation(false) << "\n"
+ << scope_tab << "public " << eolian_mono::marshall_type(false) << " " << string << ";\n")
.generate(sink, std::make_tuple(field.type, field.type, field_name), context))
return false;
}
@@ -142,7 +154,7 @@ struct struct_internal_definition_generator
scope_tab << "///<summary>Implicit conversion to the internal/marshalling representation.</summary>\n"
<< scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
<< scope_tab << "{\n"
- << scope_tab << scope_tab << "return " << string << "_StructConversion.ToExternal(struct_);\n"
+ << scope_tab << scope_tab << "return " << string << "_StructConversion.ToManaged(struct_);\n"
<< scope_tab << "}\n"
<< scope_tab << "///<summary>Implicit conversion to the managed representation.</summary>\n"
<< scope_tab << "public static implicit operator " << string << "(" << string << " struct_)\n"
@@ -315,7 +327,7 @@ struct to_external_field_convert_generator
else if (helpers::need_struct_conversion(regular))
{
if (!as_generator(
- scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToExternal(_internal_struct." << string << ");\n")
+ scope_tab << scope_tab << "_external_struct." << string << " = " << type << "_StructConversion.ToManaged(_internal_struct." << string << ");\n")
.generate(sink, std::make_tuple(field_name, field.type, field_name), context))
return false;
}
@@ -406,7 +418,7 @@ struct struct_binding_conversion_functions_generator
// to external
if (!as_generator
(
- scope_tab << "internal static " << string << " ToExternal(" << string << " _internal_struct)\n"
+ scope_tab << "internal static " << string << " ToManaged(" << string << " _internal_struct)\n"
<< scope_tab << "{\n"
<< scope_tab << scope_tab << "var _external_struct = new " << string << "();\n\n"
)
diff --git a/src/tests/efl_mono/Events.cs b/src/tests/efl_mono/Events.cs
index 7387c1e1b4..84918b9ca8 100644
--- a/src/tests/efl_mono/Events.cs
+++ b/src/tests/efl_mono/Events.cs
@@ -148,6 +148,22 @@ class TestEoEvents
Test.AssertEquals(sent_struct.Fstring, received_struct.Fstring);
}
+ public static void event_with_struct_complex_payload()
+ {
+ var obj = new Dummy.TestObject();
+ Dummy.StructComplex received_struct = default(Dummy.StructComplex);
+
+ obj.EvtWithStructComplexEvt += (object sender, Dummy.TestObjectEvtWithStructComplexEvt_Args e) => {
+ received_struct = e.arg;
+ };
+
+ Dummy.StructComplex sent_struct = StructHelpers.structComplexWithValues();
+
+ obj.EmitEventWithStructComplex(sent_struct);
+
+ Test.AssertEquals(sent_struct.Fobj, received_struct.Fobj);
+ }
+
public static void event_in_init_callback()
{
int received = 0;
diff --git a/src/tests/efl_mono/dummy_test_object.eo b/src/tests/efl_mono/dummy_test_object.eo
index e37616c979..4a6ea5fcc6 100644
--- a/src/tests/efl_mono/dummy_test_object.eo
+++ b/src/tests/efl_mono/dummy_test_object.eo
@@ -1577,6 +1577,12 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface
}
}
+ emit_event_with_struct_complex {
+ params {
+ @in data: Dummy.StructComplex;
+ }
+ }
+
append_to_strbuf {
params {
@in buf: strbuf;
@@ -1671,5 +1677,6 @@ class Dummy.Test_Object extends Efl.Object implements Efl.Part, Dummy.Test_Iface
evt,with,obj @hot: Dummy.Test_Object;
evt,with,error @hot: Eina.Error;
evt,with,struct @hot: Dummy.StructSimple;
+ evt,with,struct,complex @hot: Dummy.StructComplex;
}
}
diff --git a/src/tests/efl_mono/libefl_mono_native_test.c b/src/tests/efl_mono/libefl_mono_native_test.c
index a861f7ba48..576690bb86 100644
--- a/src/tests/efl_mono/libefl_mono_native_test.c
+++ b/src/tests/efl_mono/libefl_mono_native_test.c
@@ -3754,6 +3754,10 @@ void _dummy_test_object_emit_event_with_struct(Eo *obj, EINA_UNUSED Dummy_Test_O
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT, &data);
}
+void _dummy_test_object_emit_event_with_struct_complex(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Dummy_StructComplex data)
+{
+ efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_STRUCT_COMPLEX, &data);
+}
Efl_Object *_dummy_test_object_efl_part_part_get(EINA_UNUSED const Eo *obj, Dummy_Test_Object_Data *pd, const char *name)
{