Skip to content

Instantly share code, notes, and snippets.

@MikeWey
Created November 6, 2018 22:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MikeWey/db74966fd4293b5ab7a72047d97a934a to your computer and use it in GitHub Desktop.
Save MikeWey/db74966fd4293b5ab7a72047d97a934a to your computer and use it in GitHub Desktop.
GC Test
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)&gtkd_container_add, null);
+ Signals.connect(this, "remove", cast(GCallback)&gtkd_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