summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-05-22 17:28:50 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-05-22 17:37:36 -0300
commitb81d5e3601ae1b75af0bbebd665eda9c57fa3be6 (patch)
treeae897d993a810753bee7bb43f6bb1de7f132955a
parent9a7a81a534c2bf71e7a7ad6e6938c22a7b47b80b (diff)
csharp: Move EoWrapper to a proper file
-rw-r--r--src/bindings/mono/eo_mono/EoWrapper.cs253
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs227
-rw-r--r--src/bindings/mono/eo_mono/meson.build1
3 files changed, 254 insertions, 227 deletions
diff --git a/src/bindings/mono/eo_mono/EoWrapper.cs b/src/bindings/mono/eo_mono/EoWrapper.cs
new file mode 100644
index 0000000000..b6ea619923
--- /dev/null
+++ b/src/bindings/mono/eo_mono/EoWrapper.cs
@@ -0,0 +1,253 @@
1using System;
2using System.Runtime.InteropServices;
3using System.Runtime.CompilerServices;
4using System.Threading;
5
6namespace Efl
7{
8
9namespace Eo
10{
11
12public abstract class EoWrapper : IWrapper, IDisposable
13{
14 protected readonly object eventLock = new object();
15 protected bool inherited = false;
16 protected System.IntPtr handle = IntPtr.Zero;
17
18 private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback);
19 private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback);
20
21 /// <summary>Initializes a new instance of the <see cref="Object"/> class.
22 /// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>
23 /// <param name="raw">The native pointer to be wrapped.</param>
24 protected EoWrapper(System.IntPtr raw)
25 {
26 handle = raw;
27 AddWrapperSupervisor();
28 }
29
30 /// <summary>Initializes a new instance of the <see cref="Object"/> class.
31 /// Internal usage: Constructor to actually call the native library constructors. C# subclasses
32 /// must use the public constructor only.</summary>
33 /// <param name="baseKlass">The pointer to the base native Eo class.</param>
34 /// <param name="managedType">The managed type of the public constructor that originated this call.</param>
35 /// <param name="parent">The Efl.Object parent of this instance.</param>
36 /// <param name="file">Name of the file from where the constructor is called.</param>
37 /// <param name="line">Number of the line from where the constructor is called.</param>
38 protected EoWrapper(IntPtr baseKlass, System.Type managedType, Efl.Object parent,
39 [CallerFilePath] string file = null,
40 [CallerLineNumber] int line = 0)
41 {
42 inherited = ((object)this).GetType() != managedType;
43 IntPtr actual_klass = baseKlass;
44 if (inherited)
45 {
46 actual_klass = Efl.Eo.ClassRegister.GetInheritKlassOrRegister(baseKlass, ((object)this).GetType());
47 }
48
49 // Creation of the unfinalized Eo handle
50 Eina.Log.Debug($"Instantiating from klass 0x{actual_klass.ToInt64():x}");
51 System.IntPtr parent_ptr = System.IntPtr.Zero;
52 if (parent != null)
53 {
54 parent_ptr = parent.NativeHandle;
55 }
56
57 handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0);
58 if (handle == System.IntPtr.Zero)
59 {
60 throw new Exception("Instantiation failed");
61 }
62
63 Eina.Log.Debug($"Eo instance right after internal_start 0x{handle.ToInt64():x} with refcount {Efl.Eo.Globals.efl_ref_count(handle)}");
64 Eina.Log.Debug($"Parent was 0x{parent_ptr.ToInt64()}");
65
66 // Creation of wrapper supervisor
67 AddWrapperSupervisor();
68 }
69
70 /// <summary>Destructor.</summary>
71 ~EoWrapper()
72 {
73 Dispose(false);
74 }
75
76 /// <summary>Pointer to the native instance.</summary>
77 public System.IntPtr NativeHandle
78 {
79 get { return handle; }
80 }
81
82 /// <summary>Pointer to the native class description.</summary>
83 public abstract System.IntPtr NativeClass
84 {
85 get;
86 }
87
88 /// <summary>Releases the underlying native instance.</summary>
89 protected virtual void Dispose(bool disposing)
90 {
91 if (disposing && handle != System.IntPtr.Zero)
92 {
93 IntPtr h = handle;
94 handle = IntPtr.Zero;
95 Efl.Eo.Globals.efl_mono_native_dispose(h);
96 }
97 else
98 {
99 Monitor.Enter(Efl.All.InitLock);
100 if (Efl.All.MainLoopInitialized)
101 {
102 Efl.Eo.Globals.efl_mono_thread_safe_native_dispose(handle);
103 }
104
105 Monitor.Exit(Efl.All.InitLock);
106 }
107 }
108
109 /// <summary>Turns the native pointer into a string representation.</summary>
110 /// <returns>A string with the type and the native pointer for this object.</returns>
111 public override String ToString()
112 {
113 return $"{this.GetType().Name}@[0x{(UInt64)handle:x}]";
114 }
115
116 /// <summary>Releases the underlying native instance.</summary>
117 public void Dispose()
118 {
119 Dispose(true);
120 GC.SuppressFinalize(this);
121 }
122
123 /// <summary>Releases the underlying Eo object.
124 ///
125 /// This method is a C# counterpart to the C `efl_del` function. It removes the parent of the object
126 /// and releases the Eo reference it was holding.
127 /// </summary>
128 public void Del()
129 {
130 // FIXME Implement this
131 ((Efl.Object)this).SetParent(null);
132 Dispose();
133 }
134
135 /// <summary>Finishes instantiating this object.
136 /// Internal usage by generated code.</summary>
137 protected void FinishInstantiation()
138 {
139 Eina.Log.Debug("calling efl_add_internal_end");
140 var h = Efl.Eo.Globals._efl_add_end(handle, 1, 0);
141 Eina.Log.Debug($"efl_add_end returned eo 0x{handle.ToInt64():x}");
142
143 // if (h == IntPtr.Zero) // TODO
144 // {
145 // }
146
147 handle = h;
148 }
149
150 /// <summary>Adds a new event handler, registering it to the native event. For internal use only.</summary>
151 /// <param name="lib">The name of the native library definining the event.</param>
152 /// <param name="key">The name of the native event.</param>
153 /// <param name="evtCaller">Delegate to be called by native code on event raising.</param>
154 /// <param name="evtDelegate">Managed delegate that will be called by evtCaller on event raising.</param>
155 protected void AddNativeEventHandler(string lib, string key, Efl.EventCb evtCaller, object evtDelegate)
156 {
157 IntPtr desc = Efl.EventDescription.GetNative(lib, key);
158 if (desc == IntPtr.Zero)
159 {
160 Eina.Log.Error($"Failed to get native event {key}");
161 return;
162 }
163
164 var wsPtr = Efl.Eo.Globals.efl_mono_wrapper_supervisor_get(handle);
165 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(wsPtr);
166 if (ws.EoEvents.ContainsKey((desc, evtDelegate)))
167 {
168 Eina.Log.Warning($"Event proxy for event {key} already registered!");
169 return;
170 }
171
172 IntPtr evtCallerPtr = Marshal.GetFunctionPointerForDelegate(evtCaller);
173 if (!Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evtCallerPtr, wsPtr))
174 {
175 Eina.Log.Error($"Failed to add event proxy for event {key}");
176 return;
177 }
178
179 ws.EoEvents[(desc, evtDelegate)] = (evtCallerPtr, evtCaller);
180 Eina.Error.RaiseIfUnhandledException();
181 }
182
183 /// <summary>Removes the given event handler for the given event. For internal use only.</summary>
184 /// <param name="lib">The name of the native library definining the event.</param>
185 /// <param name="key">The name of the native event.</param>
186 /// <param name="evtDelegate">The delegate to be removed.</param>
187 protected void RemoveNativeEventHandler(string lib, string key, object evtDelegate)
188 {
189 IntPtr desc = Efl.EventDescription.GetNative(lib, key);
190 if (desc == IntPtr.Zero)
191 {
192 Eina.Log.Error($"Failed to get native event {key}");
193 return;
194 }
195
196 var wsPtr = Efl.Eo.Globals.efl_mono_wrapper_supervisor_get(handle);
197 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(wsPtr);
198 var evtPair = (desc, evtDelegate);
199 if (ws.EoEvents.TryGetValue(evtPair, out var caller))
200 {
201 if (!Efl.Eo.Globals.efl_event_callback_del(handle, desc, caller.evtCallerPtr, wsPtr))
202 {
203 Eina.Log.Error($"Failed to remove event proxy for event {key}");
204 return;
205 }
206
207 ws.EoEvents.Remove(evtPair);
208 Eina.Error.RaiseIfUnhandledException();
209 }
210 else
211 {
212 Eina.Log.Error($"Trying to remove proxy for event {key} when it is not registered.");
213 }
214 }
215
216 private static void OwnershipUniqueCallback(IntPtr data, ref Efl.Event.NativeStruct evt)
217 {
218 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(data);
219 ws.MakeUnique();
220 }
221
222 private static void OwnershipSharedCallback(IntPtr data, ref Efl.Event.NativeStruct evt)
223 {
224 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(data);
225 ws.MakeShared();
226 }
227
228 /// <sumary>Create and set to the internal native state a C# supervisor for this Eo wrapper. For internal use only.</sumary>
229 private void AddWrapperSupervisor()
230 {
231 var ws = new Efl.Eo.WrapperSupervisor(this);
232 Efl.Eo.Globals.SetWrapperSupervisor(handle, ws);
233 if (Efl.Eo.Globals.efl_ref_count(handle) > 1)
234 {
235 ws.MakeShared();
236 }
237
238 AddOwnershipEventHandlers();
239 }
240
241 /// <summary>Register handlers to ownership events, in order to control the object lifetime. For internal use only.</summary>
242 private void AddOwnershipEventHandlers()
243 {
244 AddNativeEventHandler("eo", "_EFL_EVENT_INVALIDATE", ownershipUniqueDelegate, ownershipUniqueDelegate);
245 AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_UNIQUE", ownershipUniqueDelegate, ownershipUniqueDelegate);
246 AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_SHARED", ownershipSharedDelegate, ownershipSharedDelegate);
247 Eina.Error.RaiseIfUnhandledException();
248 }
249}
250
251} // namespace Global
252
253} // namespace Efl
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index f11bbda038..9e73ca4687 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -760,233 +760,6 @@ public interface IWrapper
760 } 760 }
761} 761}
762 762
763public abstract class EoWrapper : IWrapper, IDisposable
764{
765 protected readonly object eventLock = new object();
766 protected bool inherited = false;
767 protected System.IntPtr handle = IntPtr.Zero;
768
769 private static Efl.EventCb ownershipUniqueDelegate = new Efl.EventCb(OwnershipUniqueCallback);
770 private static Efl.EventCb ownershipSharedDelegate = new Efl.EventCb(OwnershipSharedCallback);
771
772 /// <summary>Initializes a new instance of the <see cref="Object"/> class.
773 /// Internal usage: Constructs an instance from a native pointer. This is used when interacting with C code and should not be used directly.</summary>
774 /// <param name="raw">The native pointer to be wrapped.</param>
775 protected EoWrapper(System.IntPtr raw)
776 {
777 handle = raw;
778 AddWrapperSupervisor();
779 }
780
781 /// <summary>Initializes a new instance of the <see cref="Object"/> class.
782 /// Internal usage: Constructor to actually call the native library constructors. C# subclasses
783 /// must use the public constructor only.</summary>
784 /// <param name="baseKlass">The pointer to the base native Eo class.</param>
785 /// <param name="managedType">The managed type of the public constructor that originated this call.</param>
786 /// <param name="parent">The Efl.Object parent of this instance.</param>
787 /// <param name="file">Name of the file from where the constructor is called.</param>
788 /// <param name="line">Number of the line from where the constructor is called.</param>
789 protected EoWrapper(IntPtr baseKlass, System.Type managedType, Efl.Object parent,
790 [CallerFilePath] string file = null,
791 [CallerLineNumber] int line = 0)
792 {
793 inherited = ((object)this).GetType() != managedType;
794 IntPtr actual_klass = baseKlass;
795 if (inherited)
796 {
797 actual_klass = Efl.Eo.ClassRegister.GetInheritKlassOrRegister(baseKlass, ((object)this).GetType());
798 }
799
800 // Creation of the unfinalized Eo handle
801 Eina.Log.Debug($"Instantiating from klass 0x{actual_klass.ToInt64():x}");
802 System.IntPtr parent_ptr = System.IntPtr.Zero;
803 if (parent != null)
804 {
805 parent_ptr = parent.NativeHandle;
806 }
807
808 handle = Efl.Eo.Globals._efl_add_internal_start(file, line, actual_klass, parent_ptr, 1, 0);
809 if (handle == System.IntPtr.Zero)
810 {
811 throw new Exception("Instantiation failed");
812 }
813
814 Eina.Log.Debug($"Eo instance right after internal_start 0x{handle.ToInt64():x} with refcount {Efl.Eo.Globals.efl_ref_count(handle)}");
815 Eina.Log.Debug($"Parent was 0x{parent_ptr.ToInt64()}");
816
817 // Creation of wrapper supervisor
818 AddWrapperSupervisor();
819 }
820
821 /// <summary>Destructor.</summary>
822 ~EoWrapper()
823 {
824 Dispose(false);
825 }
826
827 /// <summary>Pointer to the native instance.</summary>
828 public System.IntPtr NativeHandle
829 {
830 get { return handle; }
831 }
832
833 /// <summary>Pointer to the native class description.</summary>
834 public abstract System.IntPtr NativeClass
835 {
836 get;
837 }
838
839 /// <summary>Releases the underlying native instance.</summary>
840 protected virtual void Dispose(bool disposing)
841 {
842 if (disposing && handle != System.IntPtr.Zero)
843 {
844 IntPtr h = handle;
845 handle = IntPtr.Zero;
846 Efl.Eo.Globals.efl_mono_native_dispose(h);
847 }
848 else
849 {
850 Monitor.Enter(Efl.All.InitLock);
851 if (Efl.All.MainLoopInitialized)
852 {
853 Efl.Eo.Globals.efl_mono_thread_safe_native_dispose(handle);
854 }
855
856 Monitor.Exit(Efl.All.InitLock);
857 }
858 }
859
860 /// <summary>Turns the native pointer into a string representation.</summary>
861 /// <returns>A string with the type and the native pointer for this object.</returns>
862 public override String ToString()
863 {
864 return $"{this.GetType().Name}@[0x{(UInt64)handle:x}]";
865 }
866
867 /// <summary>Releases the underlying native instance.</summary>
868 public void Dispose()
869 {
870 Dispose(true);
871 GC.SuppressFinalize(this);
872 }
873
874 /// <summary>Finishes instantiating this object.
875 /// Internal usage by generated code.</summary>
876 protected void FinishInstantiation()
877 {
878 Eina.Log.Debug("calling efl_add_internal_end");
879 var h = Efl.Eo.Globals._efl_add_end(handle, 1, 0);
880 Eina.Log.Debug($"efl_add_end returned eo 0x{handle.ToInt64():x}");
881
882 // if (h == IntPtr.Zero) // TODO
883 // {
884 // }
885
886 handle = h;
887 }
888
889 /// <summary>Adds a new event handler, registering it to the native event. For internal use only.</summary>
890 /// <param name="lib">The name of the native library definining the event.</param>
891 /// <param name="key">The name of the native event.</param>
892 /// <param name="evtCaller">Delegate to be called by native code on event raising.</param>
893 /// <param name="evtDelegate">Managed delegate that will be called by evtCaller on event raising.</param>
894 protected void AddNativeEventHandler(string lib, string key, Efl.EventCb evtCaller, object evtDelegate)
895 {
896 IntPtr desc = Efl.EventDescription.GetNative(lib, key);
897 if (desc == IntPtr.Zero)
898 {
899 Eina.Log.Error($"Failed to get native event {key}");
900 return;
901 }
902
903 var wsPtr = Efl.Eo.Globals.efl_mono_wrapper_supervisor_get(handle);
904 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(wsPtr);
905 if (ws.EoEvents.ContainsKey((desc, evtDelegate)))
906 {
907 Eina.Log.Warning($"Event proxy for event {key} already registered!");
908 return;
909 }
910
911 IntPtr evtCallerPtr = Marshal.GetFunctionPointerForDelegate(evtCaller);
912 if (!Efl.Eo.Globals.efl_event_callback_priority_add(handle, desc, 0, evtCallerPtr, wsPtr))
913 {
914 Eina.Log.Error($"Failed to add event proxy for event {key}");
915 return;
916 }
917
918 ws.EoEvents[(desc, evtDelegate)] = (evtCallerPtr, evtCaller);
919 Eina.Error.RaiseIfUnhandledException();
920 }
921
922 /// <summary>Removes the given event handler for the given event. For internal use only.</summary>
923 /// <param name="lib">The name of the native library definining the event.</param>
924 /// <param name="key">The name of the native event.</param>
925 /// <param name="evtDelegate">The delegate to be removed.</param>
926 protected void RemoveNativeEventHandler(string lib, string key, object evtDelegate)
927 {
928 IntPtr desc = Efl.EventDescription.GetNative(lib, key);
929 if (desc == IntPtr.Zero)
930 {
931 Eina.Log.Error($"Failed to get native event {key}");
932 return;
933 }
934
935 var wsPtr = Efl.Eo.Globals.efl_mono_wrapper_supervisor_get(handle);
936 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(wsPtr);
937 var evtPair = (desc, evtDelegate);
938 if (ws.EoEvents.TryGetValue(evtPair, out var caller))
939 {
940 if (!Efl.Eo.Globals.efl_event_callback_del(handle, desc, caller.evtCallerPtr, wsPtr))
941 {
942 Eina.Log.Error($"Failed to remove event proxy for event {key}");
943 return;
944 }
945
946 ws.EoEvents.Remove(evtPair);
947 Eina.Error.RaiseIfUnhandledException();
948 }
949 else
950 {
951 Eina.Log.Error($"Trying to remove proxy for event {key} when it is not registered.");
952 }
953 }
954
955 private static void OwnershipUniqueCallback(IntPtr data, ref Efl.Event.NativeStruct evt)
956 {
957 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(data);
958 ws.MakeUnique();
959 }
960
961 private static void OwnershipSharedCallback(IntPtr data, ref Efl.Event.NativeStruct evt)
962 {
963 var ws = Efl.Eo.Globals.WrapperSupervisorPtrToManaged(data);
964 ws.MakeShared();
965 }
966
967 /// <sumary>Create and set to the internal native state a C# supervisor for this Eo wrapper. For internal use only.</sumary>
968 private void AddWrapperSupervisor()
969 {
970 var ws = new Efl.Eo.WrapperSupervisor(this);
971 Efl.Eo.Globals.SetWrapperSupervisor(handle, ws);
972 if (Efl.Eo.Globals.efl_ref_count(handle) > 1)
973 {
974 ws.MakeShared();
975 }
976
977 AddOwnershipEventHandlers();
978 }
979
980 /// <summary>Register handlers to ownership events, in order to control the object lifetime. For internal use only.</summary>
981 private void AddOwnershipEventHandlers()
982 {
983 AddNativeEventHandler("eo", "_EFL_EVENT_INVALIDATE", ownershipUniqueDelegate, ownershipUniqueDelegate);
984 AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_UNIQUE", ownershipUniqueDelegate, ownershipUniqueDelegate);
985 AddNativeEventHandler("eo", "_EFL_EVENT_OWNERSHIP_SHARED", ownershipSharedDelegate, ownershipSharedDelegate);
986 Eina.Error.RaiseIfUnhandledException();
987 }
988}
989
990public static class ClassRegister 763public static class ClassRegister
991{ 764{
992 public static System.Type GetManagedType(IntPtr klass) 765 public static System.Type GetManagedType(IntPtr klass)
diff --git a/src/bindings/mono/eo_mono/meson.build b/src/bindings/mono/eo_mono/meson.build
index 1724113a07..013b1cc97f 100644
--- a/src/bindings/mono/eo_mono/meson.build
+++ b/src/bindings/mono/eo_mono/meson.build
@@ -3,6 +3,7 @@ mono_files += files(
3 'workaround.cs', 3 'workaround.cs',
4 'FunctionWrapper.cs', 4 'FunctionWrapper.cs',
5 'NativeModule.cs', 5 'NativeModule.cs',
6 'EoWrapper.cs',
6 'WrapperSupervisor.cs' 7 'WrapperSupervisor.cs'
7) 8)
8 9