diff options
author | Vitor Sousa <vitorsousa@expertisesolutions.com.br> | 2019-06-04 18:43:07 -0300 |
---|---|---|
committer | Vitor Sousa <vitorsousa@expertisesolutions.com.br> | 2019-06-04 18:52:47 -0300 |
commit | 55d557e444f30135dc304e4e8e5eba7c959ea84f (patch) | |
tree | 3e634f35467545380f96e5fcca20d410a5a1292f | |
parent | c2865a90ef75320f5ceb00abb03076b8363aa867 (diff) | |
download | efl-devs/vitorsousa/constructible_eflsharp.tar.gz |
csharp: make inherited C# classes constructible from native Cdevs/vitorsousa/constructible_eflsharp
With this commit it is now possible for a class that inherits from a C# binding
class to be instantiated from native C code. It only has to provide a
constructor that receives an `Efl.Eo.EoWrapper.ConstructingHandle` struct,
and which calls the base binding constructor passing it.
For example:
`private Type(ConstructingHandle ch) : base(ch) {}`.
Add some test files to validate the proper behavior of this feature.
Add some small fixes in generation contexts in order to properly
generate base constructors.
-rw-r--r-- | src/Makefile_Efl_Mono.am | 9 | ||||
-rw-r--r-- | src/bin/eolian_mono/eolian/mono/klass.hh | 24 | ||||
-rw-r--r-- | src/bindings/mono/eo_mono/EoWrapper.cs | 105 | ||||
-rw-r--r-- | src/bindings/mono/eo_mono/iwrapper.cs | 11 | ||||
-rw-r--r-- | src/lib/efl_mono/efl_custom_exports_mono.c | 10 | ||||
-rw-r--r-- | src/tests/efl_mono/EoConstruction.cs | 79 | ||||
-rw-r--r-- | src/tests/efl_mono/dummy_constructible_object.c | 70 | ||||
-rw-r--r-- | src/tests/efl_mono/dummy_constructible_object.eo | 47 | ||||
-rw-r--r-- | src/tests/efl_mono/dummy_test_object.c | 6 | ||||
-rw-r--r-- | src/tests/efl_mono/libefl_mono_native_test.h | 1 | ||||
-rw-r--r-- | src/tests/efl_mono/meson.build | 3 |
11 files changed, 352 insertions, 13 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am index 0cf41589ff..3d04368ccf 100644 --- a/src/Makefile_Efl_Mono.am +++ b/src/Makefile_Efl_Mono.am @@ -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 \ diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh index 6ac4aa1c3c..8b018f6413 100644 --- a/src/bin/eolian_mono/eolian/mono/klass.hh +++ b/src/bin/eolian_mono/eolian/mono/klass.hh @@ -198,6 +198,17 @@ struct klass 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) << ")] internal static extern System.IntPtr\n" << scope_tab << scope_tab << name_helpers::klass_get_name(cls) << "();\n" @@ -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" diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs b/src/bindings/mono/eo_mono/EoWrapper.cs index e1174a9fe8..0899b8682c 100644 --- a/src/bindings/mono/eo_mono/EoWrapper.cs +++ b/src/bindings/mono/eo_mono/EoWrapper.cs @@ -2,6 +2,7 @@ using System; using System.Runtime.InteropServices; using System.Runtime.CompilerServices; using System.Threading; +using System.Reflection; namespace Efl { @@ -62,6 +63,32 @@ public abstract class EoWrapper : IWrapper, IDisposable 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> @@ -98,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"); @@ -297,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 diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs index 9e73ca4687..618d16ca0f 100644 --- a/src/bindings/mono/eo_mono/iwrapper.cs +++ b/src/bindings/mono/eo_mono/iwrapper.cs @@ -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); diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c index 55f0054da0..a11a11e4b6 100644 --- a/src/lib/efl_mono/efl_custom_exports_mono.c +++ b/src/lib/efl_mono/efl_custom_exports_mono.c @@ -166,6 +166,16 @@ 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 diff --git a/src/tests/efl_mono/EoConstruction.cs b/src/tests/efl_mono/EoConstruction.cs new file mode 100644 index 0000000000..cd4a774bd1 --- /dev/null +++ b/src/tests/efl_mono/EoConstruction.cs @@ -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(); + } +} + +} diff --git a/src/tests/efl_mono/dummy_constructible_object.c b/src/tests/efl_mono/dummy_constructible_object.c new file mode 100644 index 0000000000..96842709ba --- /dev/null +++ b/src/tests/efl_mono/dummy_constructible_object.c @@ -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" diff --git a/src/tests/efl_mono/dummy_constructible_object.eo b/src/tests/efl_mono/dummy_constructible_object.eo new file mode 100644 index 0000000000..f8ae944e6c --- /dev/null +++ b/src/tests/efl_mono/dummy_constructible_object.eo @@ -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; + } +} + diff --git a/src/tests/efl_mono/dummy_test_object.c b/src/tests/efl_mono/dummy_test_object.c index fa5d01888a..f9b276c085 100644 --- a/src/tests/efl_mono/dummy_test_object.c +++ b/src/tests/efl_mono/dummy_test_object.c @@ -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) diff --git a/src/tests/efl_mono/libefl_mono_native_test.h b/src/tests/efl_mono/libefl_mono_native_test.h index 9251118fc6..b726bd05c1 100644 --- a/src/tests/efl_mono/libefl_mono_native_test.h +++ b/src/tests/efl_mono/libefl_mono_native_test.h @@ -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> diff --git a/src/tests/efl_mono/meson.build b/src/tests/efl_mono/meson.build index f75a5b8bb9..e464cdd2a8 100644 --- a/src/tests/efl_mono/meson.build +++ b/src/tests/efl_mono/meson.build @@ -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', |