forked from enlightenment/efl
csharp: Fix event marshalling for value types
Summary: It was wrongly assuming value types were passed by value. As stated in the documentation, all arguments are passed with a single level of indirection. Fixes T7957 Reviewers: woohyun, felipealmeida, vitor.sousa, segfaultxavi Reviewed By: segfaultxavi Subscribers: cedric, #reviewers, #committers Tags: #efl Maniphest Tasks: T7957 Differential Revision: https://phab.enlightenment.org/D8889
This commit is contained in:
parent
b3d7e9128b
commit
f93eb3fc04
|
@ -45,11 +45,44 @@ struct unpack_event_args_visitor
|
|||
eina::optional<std::string> name;
|
||||
std::function<std::string()> function;
|
||||
}
|
||||
/// Sizes taken from https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/sizeof
|
||||
const match_table [] =
|
||||
{
|
||||
{"bool", [&arg] { return arg + " != IntPtr.Zero"; }}
|
||||
, {"int", [&arg] { return arg + ".ToInt32()"; }}
|
||||
, {"uint", [&arg] { return "(uint)" + arg + ".ToInt32()";}}
|
||||
{"bool", [&arg] { return "Marshal.ReadByte(" + arg + ") != 0"; }}
|
||||
|
||||
, {"ubyte", [&arg] { return "Marshal.ReadByte(" + arg + ")"; }}
|
||||
, {"byte", [&arg] { return "(sbyte) Marshal.ReadByte(" + arg + ")"; }}
|
||||
|
||||
, {"char", [&arg] { return "(char) Marshal.ReadByte(" + arg + ")"; }}
|
||||
|
||||
, {"short", [&arg] { return "Marshal.ReadInt16(" + arg + ")"; }}
|
||||
, {"ushort", [&arg] { return "(ushort) Marshal.ReadInt16(" + arg + ")"; }}
|
||||
|
||||
, {"int", [&arg] { return "Marshal.ReadInt32(" + arg + ")"; }}
|
||||
, {"uint", [&arg] { return "(uint) Marshal.ReadInt32(" + arg + ")"; }}
|
||||
|
||||
, {"long", [&arg] { return "Marshal.ReadInt64(" + arg + ")"; }}
|
||||
, {"ulong", [&arg] { return "(ulong) Marshal.ReadInt64(" + arg + ")"; }}
|
||||
|
||||
, {"llong", [&arg] { return "(long) Marshal.ReadInt64(" + arg + ")"; }}
|
||||
, {"ullong", [&arg] { return "(ulong) Marshal.ReadInt64(" + arg + ")"; }}
|
||||
|
||||
, {"int8", [&arg] { return "(sbyte)Marshal.ReadByte(" + arg + ")"; }}
|
||||
, {"uint8", [&arg] { return "Marshal.ReadByte(" + arg + ")"; }}
|
||||
|
||||
, {"int16", [&arg] { return "Marshal.ReadInt16(" + arg + ")"; }}
|
||||
, {"uint16", [&arg] { return "(ushort)Marshal.ReadInt16(" + arg + ")"; }}
|
||||
|
||||
, {"int32", [&arg] { return "Marshal.ReadInt32(" + arg + ")"; }}
|
||||
, {"uint32", [&arg] { return "(uint) Marshal.ReadInt32(" + arg + ")"; }}
|
||||
|
||||
// We don't support int128 as csharp has no similar datatype.
|
||||
, {"int64", [&arg] { return "Marshal.ReadInt64(" + arg + ")"; }}
|
||||
, {"uint64", [&arg] { return "(ulong) Marshal.ReadInt64(" + arg + ")"; }}
|
||||
|
||||
, {"float", [&arg] { return "Eina.PrimitiveConversion.PointerToManaged<float>(" + arg + ")"; }}
|
||||
, {"double", [&arg] { return "Eina.PrimitiveConversion.PointerToManaged<double>(" + arg + ")"; }}
|
||||
|
||||
, {"string", [&arg] { return "Eina.StringConversion.NativeUtf8ToManagedString(" + arg + ")"; }}
|
||||
, {"stringshare", [&arg] { return "Eina.StringConversion.NativeUtf8ToManagedString(" + arg + ")"; }}
|
||||
, {"Eina.Error", [&arg] { return "(Eina.Error)Marshal.PtrToStructure(" + arg + ", typeof(Eina.Error))"; }}
|
||||
|
|
|
@ -100,6 +100,33 @@ class TestEoEvents
|
|||
Test.AssertEquals<uint>(0xbeef, received_uint);
|
||||
}
|
||||
|
||||
public static void event_with_float_payload()
|
||||
{
|
||||
var obj = new Dummy.TestObject();
|
||||
float received_float = 0;
|
||||
obj.EvtWithFloatEvt += (object sender, Dummy.TestObjectEvtWithFloatEvt_Args e) => {
|
||||
received_float = e.arg;
|
||||
};
|
||||
|
||||
obj.EmitEventWithFloat(3.14f);
|
||||
|
||||
Test.AssertAlmostEquals(3.14f, received_float);
|
||||
}
|
||||
|
||||
public static void event_with_double_payload()
|
||||
{
|
||||
var obj = new Dummy.TestObject();
|
||||
double received_double = 0;
|
||||
double reference = float.MaxValue + 42;
|
||||
obj.EvtWithDoubleEvt += (object sender, Dummy.TestObjectEvtWithDoubleEvt_Args e) => {
|
||||
received_double = e.arg;
|
||||
};
|
||||
|
||||
obj.EmitEventWithDouble(reference);
|
||||
|
||||
Test.AssertAlmostEquals(reference, received_double);
|
||||
}
|
||||
|
||||
public static void event_with_object_payload()
|
||||
{
|
||||
var obj = new Dummy.TestObject();
|
||||
|
|
|
@ -1284,6 +1284,16 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
|
|||
@in data: uint;
|
||||
}
|
||||
}
|
||||
emit_event_with_float {
|
||||
params {
|
||||
@in data: float;
|
||||
}
|
||||
}
|
||||
emit_event_with_double {
|
||||
params {
|
||||
@in data: double;
|
||||
}
|
||||
}
|
||||
emit_event_with_obj {
|
||||
params {
|
||||
@in data: Dummy.Test_Object;
|
||||
|
@ -1422,11 +1432,38 @@ class Dummy.Test_Object extends Efl.Object implements Dummy.Test_Iface {
|
|||
evt,with,bool: bool;
|
||||
evt,with,int @hot: int;
|
||||
evt,with,uint @hot: uint;
|
||||
evt,with,float @hot: float;
|
||||
evt,with,double @hot: double;
|
||||
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;
|
||||
evt,with,array @hot: const(array<string>);
|
||||
evt_with,under @hot: void;
|
||||
|
||||
// Extra events to test generation, but not invocation
|
||||
evt,with,byte: byte;
|
||||
evt,with,ubyte: ubyte;
|
||||
|
||||
evt,with,char: char;
|
||||
|
||||
evt,with,short: short;
|
||||
evt,with,ushort: ushort;
|
||||
|
||||
evt,with,llong: llong;
|
||||
evt,with,ullong: ullong;
|
||||
|
||||
evt,with,int8 @hot: int8;
|
||||
evt,with,uint8 @hot: uint8;
|
||||
|
||||
evt,with,int16 @hot: int16;
|
||||
evt,with,uint16 @hot: uint16;
|
||||
|
||||
evt,with,int32 @hot: int32;
|
||||
evt,with,uint32 @hot: uint32;
|
||||
|
||||
evt,with,int64 @hot: int64;
|
||||
evt,with,uint64 @hot: uint64;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3782,17 +3782,27 @@ void _dummy_test_object_emit_event_with_string(Eo *obj, EINA_UNUSED Dummy_Test_O
|
|||
|
||||
void _dummy_test_object_emit_event_with_bool(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eina_Bool data)
|
||||
{
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_BOOL, (void *) (uintptr_t) data);
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_BOOL, &data);
|
||||
}
|
||||
|
||||
void _dummy_test_object_emit_event_with_int(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, int data)
|
||||
{
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_INT, (void *) (uintptr_t) data);
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_INT, &data);
|
||||
}
|
||||
|
||||
void _dummy_test_object_emit_event_with_uint(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, unsigned int data)
|
||||
{
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_UINT, (void *) (uintptr_t) data);
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_UINT, &data);
|
||||
}
|
||||
|
||||
void _dummy_test_object_emit_event_with_float(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, float data)
|
||||
{
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_FLOAT, &data);
|
||||
}
|
||||
|
||||
void _dummy_test_object_emit_event_with_double(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, double data)
|
||||
{
|
||||
efl_event_callback_legacy_call(obj, DUMMY_TEST_OBJECT_EVENT_EVT_WITH_DOUBLE, &data);
|
||||
}
|
||||
|
||||
void _dummy_test_object_emit_event_with_obj(Eo *obj, EINA_UNUSED Dummy_Test_Object_Data *pd, Eo *data)
|
||||
|
|
Loading…
Reference in New Issue