summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-04-20 18:50:48 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2019-04-22 19:48:11 -0300
commit6f1cec4a991c6957388f7102bf42a4624ec81e38 (patch)
tree2b4029ace16cd12e1a86a218d0d404377ed0b596
parent9843304279135069e903f8c881f53a4ea38a9695 (diff)
efl-mono: (WIP) Get wrapper from key_get
-rw-r--r--src/Makefile_Efl_Mono.am3
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh2
-rw-r--r--src/bindings/mono/eo_mono/WrapperGetter.cs32
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs45
-rw-r--r--src/lib/efl_mono/efl_custom_exports_mono.c5
-rw-r--r--src/tests/efl_mono/Inheritance.cs78
6 files changed, 147 insertions, 18 deletions
diff --git a/src/Makefile_Efl_Mono.am b/src/Makefile_Efl_Mono.am
index 5c6d57e626..f718c7c0d1 100644
--- a/src/Makefile_Efl_Mono.am
+++ b/src/Makefile_Efl_Mono.am
@@ -6,7 +6,8 @@ efl_eo_mono_files = \
6 bindings/mono/eo_mono/iwrapper.cs \ 6 bindings/mono/eo_mono/iwrapper.cs \
7 bindings/mono/eo_mono/FunctionWrapper.cs \ 7 bindings/mono/eo_mono/FunctionWrapper.cs \
8 bindings/mono/eo_mono/NativeModule.cs \ 8 bindings/mono/eo_mono/NativeModule.cs \
9 bindings/mono/eo_mono/workaround.cs 9 bindings/mono/eo_mono/workaround.cs \
10 bindings/mono/eo_mono/WrapperGetter.cs
10 11
11if HAVE_WIN32 12if HAVE_WIN32
12 13
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index fd4c629ffd..12372b83ca 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -583,7 +583,7 @@ struct klass
583 583
584 << scope_tab << "protected void FinishInstantiation()\n" 584 << scope_tab << "protected void FinishInstantiation()\n"
585 << scope_tab << "{\n" 585 << scope_tab << "{\n"
586 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle);\n" 586 << scope_tab << scope_tab << "handle = Efl.Eo.Globals.instantiate_end(handle, this);\n"
587 << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n" 587 << scope_tab << scope_tab << "Eina.Error.RaiseIfUnhandledException();\n"
588 << scope_tab << "}\n" 588 << scope_tab << "}\n"
589 589
diff --git a/src/bindings/mono/eo_mono/WrapperGetter.cs b/src/bindings/mono/eo_mono/WrapperGetter.cs
new file mode 100644
index 0000000000..a71d151c47
--- /dev/null
+++ b/src/bindings/mono/eo_mono/WrapperGetter.cs
@@ -0,0 +1,32 @@
1using System;
2using System.Reflection;
3
4namespace Efl
5{
6
7namespace Eo
8{
9
10public class WrapperGetter
11{
12 System.WeakReference reference;
13
14 public WrapperGetter (Efl.Eo.IWrapper obj)
15 {
16 reference = new WeakReference (obj);
17 }
18
19 public Efl.Eo.IWrapper Target
20 {
21 get
22 {
23 return (Efl.Eo.IWrapper)reference.Target;
24 }
25 set {}
26
27 }
28}
29
30}
31}
32
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index a410a091bb..cc91d65b34 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -48,6 +48,19 @@ public class Globals
48 public delegate IntPtr 48 public delegate IntPtr
49 _efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line, 49 _efl_add_internal_start_delegate([MarshalAs(UnmanagedType.LPStr)] String file, int line,
50 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); 50 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
51
52 public delegate void efl_key_data_set_delegate(IntPtr obj, IntPtr key, IntPtr data);
53 public static FunctionWrapper<efl_key_data_set_delegate> efl_key_data_set_ptr =
54 new FunctionWrapper<efl_key_data_set_delegate>(efl.Libs.EoModule, "efl_key_data_set");
55 public static void efl_key_data_set(IntPtr obj, IntPtr key, IntPtr data) => efl_key_data_set_ptr.Value.Delegate(obj, key, data);
56
57 public delegate IntPtr efl_key_data_get_delegate(IntPtr obj, IntPtr key);
58 public static FunctionWrapper<efl_key_data_get_delegate> efl_key_data_get_ptr =
59 new FunctionWrapper<efl_key_data_get_delegate>(efl.Libs.EoModule, "efl_key_data_get");
60 public static IntPtr efl_key_data_get(IntPtr obj, IntPtr key) => efl_key_data_get_ptr.Value.Delegate(obj, key);
61
62 [DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_lifetime_key_get();
63
51 [DllImport(efl.Libs.Eo)] public static extern IntPtr 64 [DllImport(efl.Libs.Eo)] public static extern IntPtr
52 _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line, 65 _efl_add_internal_start([MarshalAs(UnmanagedType.LPStr)] String file, int line,
53 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback); 66 IntPtr klass, IntPtr parent, byte is_ref, byte is_fallback);
@@ -464,11 +477,16 @@ public class Globals
464 return eo; 477 return eo;
465 } 478 }
466 479
467 public static IntPtr instantiate_end(IntPtr eo) 480 public static IntPtr instantiate_end(IntPtr eo, Efl.Eo.IWrapper wrapper)
468 { 481 {
469 Eina.Log.Debug("calling efl_add_internal_end"); 482 Eina.Log.Debug("calling efl_add_internal_end");
470 eo = Efl.Eo.Globals._efl_add_end(eo, 1, 0); 483 eo = Efl.Eo.Globals._efl_add_end(eo, 1, 0);
471 Eina.Log.Debug($"efl_add_end returned eo 0x{eo.ToInt64():x}"); 484 Eina.Log.Debug($"efl_add_end returned eo 0x{eo.ToInt64():x}");
485
486 var getter = new Efl.Eo.WrapperGetter (wrapper);
487 GCHandle gch = GCHandle.Alloc (getter);
488 efl_key_data_set (eo, efl_mono_lifetime_key_get(), GCHandle.ToIntPtr(gch));
489
472 return eo; 490 return eo;
473 } 491 }
474 492
@@ -477,7 +495,7 @@ public class Globals
477 Eina.Log.Debug($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}"); 495 Eina.Log.Debug($"Calling data_scope_get with obj {obj.NativeHandle.ToInt64():x} and klass {obj.NativeClass.ToInt64():x}");
478 IntPtr pd = Efl.Eo.Globals.efl_data_scope_get(obj.NativeHandle, obj.NativeClass); 496 IntPtr pd = Efl.Eo.Globals.efl_data_scope_get(obj.NativeHandle, obj.NativeClass);
479 { 497 {
480 GCHandle gch = GCHandle.Alloc(obj); 498 GCHandle gch = GCHandle.Alloc(obj, GCHandleType.Weak);
481 EolianPD epd; 499 EolianPD epd;
482 epd.pointer = GCHandle.ToIntPtr(gch); 500 epd.pointer = GCHandle.ToIntPtr(gch);
483 Marshal.StructureToPtr(epd, pd, false); 501 Marshal.StructureToPtr(epd, pd, false);
@@ -601,6 +619,14 @@ public class Globals
601 return null; 619 return null;
602 } 620 }
603 621
622 IntPtr lifetime = efl_key_data_get (handle, efl_mono_lifetime_key_get());
623 if (lifetime != IntPtr.Zero)
624 {
625 GCHandle gch = GCHandle.FromIntPtr(lifetime);
626 WrapperGetter owner = (WrapperGetter)gch.Target;
627 return owner.Target;
628 }
629
604 IntPtr eoKlass = efl_class_get(handle); 630 IntPtr eoKlass = efl_class_get(handle);
605 631
606 if (eoKlass == IntPtr.Zero) 632 if (eoKlass == IntPtr.Zero)
@@ -618,20 +644,7 @@ public class Globals
618 throw new InvalidOperationException($"Can't get Managed class for object handle 0x{handle.ToInt64():x} with native class [{name}]"); 644 throw new InvalidOperationException($"Can't get Managed class for object handle 0x{handle.ToInt64():x} with native class [{name}]");
619 } 645 }
620 646
621 // Pure C# classes that inherit from generated classes store their C# instance in their 647 Debug.Assert (IsGeneratedClass(managedType));
622 // Eo private data field.
623 if (!IsGeneratedClass(managedType))
624 {
625 Efl.Eo.IWrapper instance = null;
626 IntPtr pd = efl_data_scope_get(handle, eoKlass);
627
628 if (pd != IntPtr.Zero)
629 {
630 instance = PrivateDataGet(pd);
631 }
632
633 return instance;
634 }
635 648
636 System.Reflection.ConstructorInfo constructor = null; 649 System.Reflection.ConstructorInfo constructor = null;
637 650
diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c
index c4a3b54bc5..b25ca1c548 100644
--- a/src/lib/efl_mono/efl_custom_exports_mono.c
+++ b/src/lib/efl_mono/efl_custom_exports_mono.c
@@ -29,6 +29,11 @@ typedef void (*Efl_Mono_Remove_Events_Cb)(Eo *obj, void *gchandle);
29static Efl_Mono_Free_GCHandle_Cb _efl_mono_free_gchandle_call = NULL; 29static Efl_Mono_Free_GCHandle_Cb _efl_mono_free_gchandle_call = NULL;
30static Efl_Mono_Remove_Events_Cb _efl_mono_remove_events_call = NULL; 30static Efl_Mono_Remove_Events_Cb _efl_mono_remove_events_call = NULL;
31 31
32EAPI const char* efl_mono_lifetime_key_get ()
33{
34 return "__c#__handle__wrapper__lifetime__";
35}
36
32EAPI void efl_mono_gchandle_callbacks_set(Efl_Mono_Free_GCHandle_Cb free_gchandle_cb, Efl_Mono_Remove_Events_Cb remove_events_cb) 37EAPI void efl_mono_gchandle_callbacks_set(Efl_Mono_Free_GCHandle_Cb free_gchandle_cb, Efl_Mono_Remove_Events_Cb remove_events_cb)
33{ 38{
34 _efl_mono_free_gchandle_call = free_gchandle_cb; 39 _efl_mono_free_gchandle_call = free_gchandle_cb;
diff --git a/src/tests/efl_mono/Inheritance.cs b/src/tests/efl_mono/Inheritance.cs
index befdd3a7b4..cfdd9e86f1 100644
--- a/src/tests/efl_mono/Inheritance.cs
+++ b/src/tests/efl_mono/Inheritance.cs
@@ -34,6 +34,44 @@ class TestInheritance
34 return "Hello World"; 34 return "Hello World";
35 } 35 }
36 } 36 }
37
38 internal class Inherit3Parent : Dummy.TestObject
39 {
40 public bool disposed = false;
41 public bool childDisposed = false;
42
43 ~Inherit3Parent()
44 {
45 Console.WriteLine ("finalizer called for parent");
46 }
47
48 protected override void Dispose (bool disposing)
49 {
50 Console.WriteLine ("Dispose parent");
51 base.Dispose(disposing);
52 }
53 }
54
55 internal class Inherit3Child : Dummy.TestObject
56 {
57 Inherit3Parent parent;
58 public Inherit3Child (Inherit3Parent parent) : base (parent)
59 {
60 this.parent = parent;
61 }
62
63 ~Inherit3Child()
64 {
65 Console.WriteLine ("finalizer called for child");
66 }
67
68 protected override void Dispose (bool disposing)
69 {
70 parent.childDisposed = true;
71 Console.WriteLine ("Dispose parent");
72 base.Dispose(disposing);
73 }
74 }
37 75
38 public static void test_inherit_from_regular_class() 76 public static void test_inherit_from_regular_class()
39 { 77 {
@@ -50,6 +88,46 @@ class TestInheritance
50 string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj); 88 string s = Dummy.InheritHelper.ReceiveDummyAndCallInStringshare(obj);
51 Test.AssertEquals ("Hello World", s); 89 Test.AssertEquals ("Hello World", s);
52 } 90 }
91
92 public static void test_inherit_lifetime()
93 {
94 WeakReference parent_wref;
95 WeakReference child_wref;
96 {
97 var parent = new Inherit3Parent();
98 var child = new Inherit3Child(parent);
99
100 parent_wref = new WeakReference (parent);
101 child_wref = new WeakReference (child);
102
103 Console.WriteLine ("Parent has {0} refs", Efl.Eo.Globals.efl_ref_count (parent.NativeHandle));
104 Console.WriteLine ("Child has {0} refs", Efl.Eo.Globals.efl_ref_count (child.NativeHandle));
105
106 child = null;
107
108 System.GC.Collect(System.GC.MaxGeneration, GCCollectionMode.Forced, true, true);
109 System.GC.WaitForPendingFinalizers();
110
111 child = (Inherit3Child)child_wref.Target;
112
113 Test.AssertNotEquals (parent, null);
114 Test.AssertNotEquals (child, null);
115 Test.AssertEquals (parent.disposed, false);
116 Test.AssertEquals (parent.childDisposed, false);
117
118 Console.WriteLine ("Parent has {0} refs", Efl.Eo.Globals.efl_ref_count (parent.NativeHandle));
119 Console.WriteLine ("Child has {0} refs", Efl.Eo.Globals.efl_ref_count (child.NativeHandle));
120 }
121
122 System.GC.Collect(System.GC.MaxGeneration, GCCollectionMode.Forced, true, true);
123 System.GC.WaitForPendingFinalizers();
124
125 Inherit3Parent parent2 = (Inherit3Parent)parent_wref.Target;
126 Inherit3Child child2 = (Inherit3Child)child_wref.Target;
127
128 Test.AssertEquals (parent2, null);
129 Test.AssertEquals (child2, null);
130 }
53} 131}
54 132
55} 133}