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
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 {};
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 *")
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)
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);
}
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 *")
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
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"
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;
.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;
}
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"
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;
}
// 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"
)
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;
}
}
+ emit_event_with_struct_complex {
+ params {
+ @in data: Dummy.StructComplex;
+ }
+ }
+
append_to_strbuf {
params {
@in buf: strbuf;
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;
}
}
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)
{