-
-
Save MikeWey/db74966fd4293b5ab7a72047d97a934a to your computer and use it in GitHub Desktop.
GC Test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/generated/gtkd/gobject/DClosure.d b/generated/gtkd/gobject/DClosure.d | |
index 0f0746de..b47a748c 100644 | |
--- a/generated/gtkd/gobject/DClosure.d | |
+++ b/generated/gtkd/gobject/DClosure.d | |
@@ -54,6 +54,8 @@ struct DGClosure(T) | |
*/ | |
class DClosure : Closure | |
{ | |
+ private void* delegate_; | |
+ | |
/** Get the main Gtk struct */ | |
public GClosure* getDClosureStruct(bool transferOwnership = false) | |
{ | |
@@ -91,15 +93,16 @@ class DClosure : Closure | |
auto dClosure = cast(DGClosure!(T)*)gClosure; | |
dClosure.callback = callback; | |
- GC.addRange(gClosure, DGClosure!(T).sizeof, typeid(DGClosure!(T))); | |
+ //GC.addRange(gClosure, DGClosure!(T).sizeof, typeid(DGClosure!(T))); | |
+ delegate_ = callback.ptr; | |
super(gClosure, true); | |
} | |
- ~this() | |
- { | |
- GC.removeRange(gClosure); | |
- } | |
+ // ~this() | |
+ // { | |
+ // GC.removeRange(gClosure); | |
+ // } | |
extern(C) static void d_closure_marshal(T)(GClosure* closure, GValue* return_value, uint n_param_values, /*const*/ GValue* param_values, void* invocation_hint, void* marshal_data) | |
{ | |
diff --git a/generated/gtkd/gobject/ObjectG.d b/generated/gtkd/gobject/ObjectG.d | |
index 2bef0fc0..0109dc8a 100644 | |
--- a/generated/gtkd/gobject/ObjectG.d | |
+++ b/generated/gtkd/gobject/ObjectG.d | |
@@ -27,6 +27,7 @@ module gobject.ObjectG; | |
private import core.memory; | |
private import glib.ConstructionException; | |
private import glib.Str; | |
+private import glib.c.functions : g_datalist_get_flags; | |
private import gobject.Binding; | |
private import gobject.Closure; | |
private import gobject.DClosure; | |
@@ -153,8 +154,7 @@ public class ObjectG | |
isGcRoot = false; | |
} | |
- // We only have a toggle ref if the C object hods a reference to the D object. | |
- if ( g_object_get_data(gObject, cast(char*)"GObject") is cast(void*)this ) | |
+ if ( hasToggleRef() ) | |
g_object_remove_toggle_ref(gObject, cast(GToggleNotify)&toggleNotify, cast(void*)this); | |
else | |
g_object_unref(gObject); | |
@@ -293,6 +293,31 @@ public class ObjectG | |
return iface; | |
} | |
+ /** | |
+ * Is there a toggle ref connected to this object. | |
+ */ | |
+ private bool hasToggleRef() | |
+ { | |
+ enum TOGGLE_REF_FLAG = 0x1; | |
+ | |
+ return (g_datalist_get_flags(&gObject.qdata) & TOGGLE_REF_FLAG) != 0; | |
+ } | |
+ | |
+ public void removeGcRoot() | |
+ { | |
+ if ( hasToggleRef() ) | |
+ { | |
+ g_object_ref(gObject); | |
+ g_object_remove_toggle_ref(gObject, cast(GToggleNotify)&toggleNotify, cast(void*)this); | |
+ } | |
+ | |
+ if ( isGcRoot ) | |
+ { | |
+ GC.removeRoot(cast(void*)this); | |
+ isGcRoot = false; | |
+ } | |
+ } | |
+ | |
/** */ | |
public void setProperty(T)(string propertyName, T value) | |
{ | |
diff --git a/generated/gtkd/gtk/Container.d b/generated/gtkd/gtk/Container.d | |
index 14dd360f..b04f9838 100644 | |
--- a/generated/gtkd/gtk/Container.d | |
+++ b/generated/gtkd/gtk/Container.d | |
@@ -268,6 +268,9 @@ public class Container : Widget | |
{ | |
this.gtkContainer = gtkContainer; | |
super(cast(GtkWidget*)gtkContainer, ownedRef); | |
+ | |
+ Signals.connect(this, "add", cast(GCallback)>kd_container_add, null); | |
+ Signals.connect(this, "remove", cast(GCallback)>kd_container_remove, null); | |
} | |
/** | |
@@ -283,6 +286,29 @@ public class Container : Widget | |
} | |
} | |
+ Widget[] children; | |
+ | |
+ static extern(C) void gtkd_container_add(GtkContainer* c, GtkWidget* w) | |
+ { | |
+ Container container = ObjectG.getDObject!(Container)(c); | |
+ Widget widget = ObjectG.getDObject!(Widget)(w); | |
+ | |
+ container.children ~= widget; | |
+ widget.removeGcRoot(); | |
+ } | |
+ | |
+ static extern(C) void gtkd_container_remove(GtkContainer* c, GtkWidget* w) | |
+ { | |
+ import gobject.c.functions : g_object_get_data; | |
+ | |
+ if ( auto container = cast(Container)g_object_get_data(cast(GObject*)c, "GObject") ) | |
+ if ( auto widget = cast(Widget)g_object_get_data(cast(GObject*)w, "GObject") ) | |
+ { | |
+ import std.algorithm : remove; | |
+ container.children.remove!(a => a is widget)(); | |
+ } | |
+ } | |
+ | |
/** | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment