diff --git a/Source/Libs/GLibSharp/InitiallyUnowned.cs b/Source/Libs/GLibSharp/InitiallyUnowned.cs index af0c43c34..049f1b093 100644 --- a/Source/Libs/GLibSharp/InitiallyUnowned.cs +++ b/Source/Libs/GLibSharp/InitiallyUnowned.cs @@ -21,55 +21,10 @@ namespace GLib { using System; - using System.Runtime.InteropServices; public class InitiallyUnowned : Object { protected InitiallyUnowned (IntPtr raw) : base (raw) {} - - public new static GLib.GType GType { - get { - return GType.Object; - } - } - - delegate void d_g_object_ref_sink(IntPtr raw); - static d_g_object_ref_sink g_object_ref_sink = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_ref_sink")); - - protected override IntPtr Raw { - get { - return base.Raw; - } - set { - if (value != IntPtr.Zero) - g_object_ref_sink (value); - base.Raw = value; - } - } - - delegate bool d_g_object_is_floating(IntPtr raw); - static d_g_object_is_floating g_object_is_floating = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_is_floating")); - - delegate void d_g_object_force_floating(IntPtr raw); - static d_g_object_force_floating g_object_force_floating = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_force_floating")); - - delegate void d_g_object_unref(IntPtr raw); - static d_g_object_unref g_object_unref = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.GObject), "g_object_unref")); - - public bool IsFloating { - get { - return g_object_is_floating (Handle); - } - set { - if (value == true) { - if (!IsFloating) - g_object_force_floating (Handle); - } else { - g_object_ref_sink (Handle); - g_object_unref (Handle); - } - } - } } } diff --git a/Source/Libs/GLibSharp/Object.cs b/Source/Libs/GLibSharp/Object.cs index 57bb28cc4..e090c1012 100644 --- a/Source/Libs/GLibSharp/Object.cs +++ b/Source/Libs/GLibSharp/Object.cs @@ -28,9 +28,11 @@ namespace GLib { using System.Collections.Generic; using System.Reflection; using System.Runtime.InteropServices; + using System.Linq; public class Object : IWrapper, IDisposable { + protected internal bool owned; IntPtr handle; ToggleRef tref; bool disposed = false; @@ -38,6 +40,50 @@ namespace GLib { static Dictionary Objects = new Dictionary(); static Dictionary> PropertiesToSet = new Dictionary>(); + static readonly List IgnoreAddresses = new List (); + static readonly Dictionary ConstructionTraces = new Dictionary (); + + public static void PrintHeldObjects () + { + Console.WriteLine ($"---- BEGIN HELD OBJECTS ({Objects.Count - IgnoreAddresses.Count}) [Total: {Objects.Count}]----:"); + lock (Objects) + { + foreach (var obj in Objects) + { + if (IgnoreAddresses.Contains (obj.Key.ToInt64 ())) + continue; + + Console.WriteLine (obj.Key.ToInt64 () + " -> " + obj.Value.Target.GetType ()); + if (ConstructionTraces.ContainsKey (obj.Key.ToInt64 ())) + Console.WriteLine (" AT: " + ConstructionTraces[obj.Key.ToInt64 ()].Split (Environment.NewLine.ToCharArray ()).FirstOrDefault (x => x.Contains ("OpenMedicus"))); //Aggregate((x,y) => x + Environment.NewLine + y) + } + } + + Console.WriteLine ($"---- END HELD OBJECTS ({Objects.Count - IgnoreAddresses.Count}) [Total: {Objects.Count}]----:"); + } + + public static void SetIgnore () + { + IgnoreAddresses.Clear (); + lock (Objects) + { + foreach (var address in Objects) + IgnoreAddresses.Add (address.Key.ToInt64 ()); + } + } + + static bool traceConstruction = true; + + public bool TraceConstruction + { + get => traceConstruction; + set + { + ConstructionTraces.Clear (); + traceConstruction = value; + } + } + ~Object () { if (WarnOnFinalize) @@ -65,10 +111,11 @@ namespace GLib { } } +// Console.WriteLine ("Disposed " + GetType() + " " + RefCount); handle = IntPtr.Zero; if (tref == null) return; - + if (disposing) tref.Dispose (); else @@ -85,6 +132,16 @@ namespace GLib { signals = null; } + public void FreeSignals () + { + if (signals != null) { + var copy = signals.Values; + signals = null; + foreach (Signal s in copy) + s.Free (); + } + } + public static bool WarnOnFinalize { get; set; } delegate IntPtr d_g_object_ref(IntPtr raw); @@ -133,9 +190,6 @@ namespace GLib { return obj; } - if (!owned_ref) - g_object_ref (o); - obj = GLib.ObjectManager.CreateObject(o); if (obj == null) { g_object_unref (o); diff --git a/Source/Libs/GLibSharp/ToggleRef.cs b/Source/Libs/GLibSharp/ToggleRef.cs index 06b758f53..73c6363ad 100644 --- a/Source/Libs/GLibSharp/ToggleRef.cs +++ b/Source/Libs/GLibSharp/ToggleRef.cs @@ -38,7 +38,8 @@ namespace GLib { gch = GCHandle.Alloc (this); reference = target; g_object_add_toggle_ref (target.Handle, ToggleNotifyCallback, (IntPtr) gch); - g_object_unref (target.Handle); + if (target.owned && !(target is InitiallyUnowned)) + g_object_unref (target.Handle); } public IntPtr Handle { @@ -66,7 +67,9 @@ namespace GLib { } void Free () - { + { + Target?.FreeSignals (); + if (hardened) g_object_unref (handle); else diff --git a/Source/Libs/GtkSharp/Widget.cs b/Source/Libs/GtkSharp/Widget.cs index ee40c215a..082ab066a 100644 --- a/Source/Libs/GtkSharp/Widget.cs +++ b/Source/Libs/GtkSharp/Widget.cs @@ -391,11 +391,16 @@ namespace Gtk { { if (Handle == IntPtr.Zero) return; + + if (disposing) + gtk_widget_destroy (Handle); + InternalDestroyed -= NativeDestroyHandler; + base.Dispose (disposing); } - protected override IntPtr Raw { + protected override IntPtr Raw { get { return base.Raw; } @@ -409,12 +414,9 @@ namespace Gtk { delegate void d_gtk_widget_destroy(IntPtr raw); static d_gtk_widget_destroy gtk_widget_destroy = FuncLoader.LoadFunction(FuncLoader.GetProcAddress(GLibrary.Load(Library.Gtk), "gtk_widget_destroy")); + [Obsolete("Use Dispose")] public virtual void Destroy () { - if (Handle == IntPtr.Zero) - return; - gtk_widget_destroy (Handle); - InternalDestroyed -= NativeDestroyHandler; } } } diff --git a/Source/Tools/GapiCodegen/Ctor.cs b/Source/Tools/GapiCodegen/Ctor.cs index ce8e9ada8..0736ce8d1 100644 --- a/Source/Tools/GapiCodegen/Ctor.cs +++ b/Source/Tools/GapiCodegen/Ctor.cs @@ -148,7 +148,10 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\t}"); } - Body.Initialize(gen_info, false, false, ""); + Body.Initialize(gen_info, false, false, ""); + if (container_type is ObjectGen) { + sw.WriteLine ("\t\t\towned = true;"); + } sw.WriteLine("\t\t\t{0} = {1}({2});", container_type.AssignToName, CName, Body.GetCallString (false)); Body.Finish (sw, ""); Body.HandleException (sw, "");