aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLauro Moura <lauromoura@expertisesolutions.com.br>2019-05-09 19:23:47 -0300
committerLauro Moura <lauromoura@expertisesolutions.com.br>2019-05-13 21:35:44 -0300
commit12f1c3689b8791aed1d74e864d8316a7fe205926 (patch)
tree7a59cec0d2ed2826ac181574c15727bf76950f80
parentcsharp: Slim Concrete classes. (diff)
downloadefl-devs/lauromoura/csharp_lifetime.tar.gz
csharp WIP: Make events work with dissociated wrappersdevs/lauromoura/csharp_lifetime
This is an alternative approach to the fix we are working on for https://phab.enlightenment.org/T7800 This commit keeps the C# wrappers dissociated from the Eo instances (i.e. the wrappers may die while the Eo is still alive). The events work by creating new wrappers upon event callback and keeping the dictionary with the event callback alive for the duraction of the Eo lifetime. Still to do: - Overload '==' ? - Dispose the dictionary when the object emits "DEL" - Attach the existing dictionary when creating the wrapper from the constructor receiving the raw Pointer.
-rw-r--r--src/bin/eolian_mono/eolian/mono/events.hh3
-rw-r--r--src/bin/eolian_mono/eolian/mono/klass.hh38
-rw-r--r--src/bindings/mono/eo_mono/iwrapper.cs11
-rw-r--r--src/lib/efl_mono/efl_custom_exports_mono.c9
4 files changed, 44 insertions, 17 deletions
diff --git a/src/bin/eolian_mono/eolian/mono/events.hh b/src/bin/eolian_mono/eolian/mono/events.hh
index dd4337300e..605c980290 100644
--- a/src/bin/eolian_mono/eolian/mono/events.hh
+++ b/src/bin/eolian_mono/eolian/mono/events.hh
@@ -431,10 +431,9 @@ struct event_definition_generator
<< scope_tab << scope_tab << "{\n"
<< scope_tab << scope_tab << scope_tab << "lock (eventLock)\n"
<< scope_tab << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "var wRef = new WeakReference(this);\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "Efl.EventCb callerCb = (IntPtr data, ref Efl.Event.NativeStruct evt) =>\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "var obj = wRef.Target as Efl.Eo.IWrapper;\n"
+ << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "var obj = Efl.Eo.Globals.CreateWrapperFor(evt.Object);\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "if (obj != null)\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << "{\n"
<< scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << scope_tab << event_args
diff --git a/src/bin/eolian_mono/eolian/mono/klass.hh b/src/bin/eolian_mono/eolian/mono/klass.hh
index fb74f16ecc..8c6c520f1f 100644
--- a/src/bin/eolian_mono/eolian/mono/klass.hh
+++ b/src/bin/eolian_mono/eolian/mono/klass.hh
@@ -47,6 +47,7 @@ static bool generate_equals_method(OutputIterator sink, Context const &context)
<< scope_tab << scope_tab << "}\n"
<< scope_tab << scope_tab << "return this.NativeHandle == other.NativeHandle;\n"
<< scope_tab << "}\n\n"
+
<< scope_tab << "/// <summary>Gets the hash code for this object based on the native pointer it points to.</summary>\n"
<< scope_tab << "/// <returns>The value of the pointer, to be used as the hash code of this object.</returns>\n"
<< scope_tab << "public override int GetHashCode()\n"
@@ -573,7 +574,7 @@ struct klass
}
// Detailed constructors go only in root classes.
- return as_generator(
+ if (!as_generator(
/// Actual root costructor that creates class and instantiates
scope_tab << "/// <summary>Initializes a new instance of the <see cref=\"" << inherit_name << "\"/> class.\n"
<< scope_tab << "/// Internal usage: Constructor to actually call the native library constructors. C# subclasses\n"
@@ -594,7 +595,18 @@ struct klass
<< scope_tab << scope_tab << "{\n"
<< scope_tab << scope_tab << scope_tab << "Efl.Eo.Globals.PrivateDataSet(this);\n"
<< scope_tab << scope_tab << "}\n"
- << scope_tab << "}\n\n"
+ ).generate(sink, attributes::unused, context))
+ return false;
+
+ if (cls.get_all_events().size() > 0)
+ if (!as_generator(
+ scope_tab << scope_tab << "var eventsHandle = GCHandle.Alloc(eoEvents);\n"
+ << scope_tab << scope_tab << "Efl.Eo.Globals.efl_key_data_set(handle, Efl.Eo.Globals.efl_mono_wrapper_supervisor_key_get(), GCHandle.ToIntPtr(eventsHandle));\n"
+ ).generate(sink,attributes::unused, context))
+ return false;
+
+ return as_generator(
+ scope_tab << "}\n\n"
<< scope_tab << "/// <summary>Finishes instantiating this object.\n"
<< scope_tab << "/// Internal usage by generated code.</summary>\n"
@@ -619,17 +631,17 @@ struct klass
auto inherit_name = name_helpers::klass_concrete_name(cls);
std::string events_gchandle;
- if (cls.get_all_events().size() > 0)
- {
- auto events_gchandle_sink = std::back_inserter(events_gchandle);
- if (!as_generator(scope_tab << scope_tab << scope_tab << "if (eoEvents.Count != 0)\n"
- << scope_tab << scope_tab << scope_tab << "{\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "GCHandle gcHandle = GCHandle.Alloc(eoEvents);\n"
- << scope_tab << scope_tab << scope_tab << scope_tab << "gcHandlePtr = GCHandle.ToIntPtr(gcHandle);\n"
- << scope_tab << scope_tab << scope_tab << "}\n\n")
- .generate(events_gchandle_sink, attributes::unused, context))
- return false;
- }
+ /* if (cls.get_all_events().size() > 0) */
+ /* { */
+ /* auto events_gchandle_sink = std::back_inserter(events_gchandle); */
+ /* if (!as_generator(scope_tab << scope_tab << scope_tab << "if (eoEvents.Count != 0)\n" */
+ /* << scope_tab << scope_tab << scope_tab << "{\n" */
+ /* << scope_tab << scope_tab << scope_tab << scope_tab << "GCHandle gcHandle = GCHandle.Alloc(eoEvents);\n" */
+ /* << scope_tab << scope_tab << scope_tab << scope_tab << "gcHandlePtr = GCHandle.ToIntPtr(gcHandle);\n" */
+ /* << scope_tab << scope_tab << scope_tab << "}\n\n") */
+ /* .generate(events_gchandle_sink, attributes::unused, context)) */
+ /* return false; */
+ /* } */
return as_generator(
diff --git a/src/bindings/mono/eo_mono/iwrapper.cs b/src/bindings/mono/eo_mono/iwrapper.cs
index a410a091bb..56c6e0c792 100644
--- a/src/bindings/mono/eo_mono/iwrapper.cs
+++ b/src/bindings/mono/eo_mono/iwrapper.cs
@@ -201,6 +201,17 @@ public class Globals
[DllImport(efl.Libs.Eo)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool
efl_event_callback_call(IntPtr obj, IntPtr desc, IntPtr event_info);
+public delegate void efl_key_data_set_delegate(IntPtr obj, IntPtr key, IntPtr data);
+public static FunctionWrapper<efl_key_data_set_delegate> efl_key_data_set_ptr = new FunctionWrapper<efl_key_data_set_delegate>(efl.Libs.EoModule, "efl_key_data_set");
+public static void efl_key_data_set(IntPtr obj, IntPtr key, IntPtr data) => efl_key_data_set_ptr.Value.Delegate(obj, key, data);
+
+public delegate IntPtr efl_key_data_get_delegate(IntPtr obj, IntPtr key);
+public static FunctionWrapper<efl_key_data_get_delegate> efl_key_data_get_ptr = new FunctionWrapper<efl_key_data_get_delegate>(efl.Libs.EoModule, "efl_key_data_get");
+public static IntPtr efl_key_data_get(IntPtr obj, IntPtr key) => efl_key_data_get_ptr.Value.Delegate(obj, key);
+
+[DllImport(efl.Libs.CustomExports)] public static extern IntPtr efl_mono_wrapper_supervisor_key_get();
+
+
public const int RTLD_NOW = 2;
public delegate byte class_initializer(IntPtr klass);
diff --git a/src/lib/efl_mono/efl_custom_exports_mono.c b/src/lib/efl_mono/efl_custom_exports_mono.c
index c4a3b54bc5..6096a6e3c1 100644
--- a/src/lib/efl_mono/efl_custom_exports_mono.c
+++ b/src/lib/efl_mono/efl_custom_exports_mono.c
@@ -37,9 +37,14 @@ EAPI void efl_mono_gchandle_callbacks_set(Efl_Mono_Free_GCHandle_Cb free_gchandl
EAPI void efl_mono_native_dispose(Eo *obj, void* gchandle)
{
- if (gchandle) _efl_mono_remove_events_call(obj, gchandle);
+ /* if (gchandle) _efl_mono_remove_events_call(obj, gchandle); */
efl_unref(obj);
- if (gchandle) _efl_mono_free_gchandle_call(gchandle);
+ /* if (gchandle) _efl_mono_free_gchandle_call(gchandle); */
+}
+
+EAPI const char *efl_mono_wrapper_supervisor_key_get()
+{
+ return "_c#_wrapper_supervisor";
}
typedef struct _Efl_Mono_Native_Dispose_Data