diff --git a/ChangeLog b/ChangeLog index bc391c000..751864ece 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,20 @@ +2003-02-26 Gonzalo Paniagua Javier + + * generator/Parser.cs: use XmlDocument.Load (Stream). The one using + (String) expects an uri. + + * generator/Signal.cs: always remove the delegate from the signal + callback (prior to this, the last handler was not being removed). + Dispose the callback (ie, disconnect from the signal) when there are + no registered delegates to handle it. + + * generator/SignalHandler.cs: added 2 new fields to hold the instance + and the handler ID. The finalization is now done in Dispose and + disconnects the signal handler when no delegate will handle the signal. + Changed gobject-2.0 to libgobject-2.0-0.dll. + + * glib/SignalCallback.cs: implemented IDisposable interface. + 2003-02-24 Mike Kestner * sample/TreeViewDemo.cs : fix Type ambiguities diff --git a/generator/Parser.cs b/generator/Parser.cs index 8e90710d7..dae7364f9 100644 --- a/generator/Parser.cs +++ b/generator/Parser.cs @@ -8,6 +8,7 @@ namespace GtkSharp.Generation { using System; using System.Collections; + using System.IO; using System.Xml; public class Parser { @@ -20,7 +21,9 @@ namespace GtkSharp.Generation { try { - doc.Load (filename); + Stream stream = File.OpenRead (filename); + doc.Load (stream); + stream.Close (); } catch (XmlException e) { diff --git a/generator/Signal.cs b/generator/Signal.cs index c2b189a9c..0efdcbde2 100644 --- a/generator/Signal.cs +++ b/generator/Signal.cs @@ -169,10 +169,16 @@ namespace GtkSharp.Generation { sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t\tremove {"); sw.WriteLine("\t\t\t\tEventList.RemoveHandler(" + cname + ", value);"); - sw.WriteLine("\t\t\t\tif (EventList[" + cname + "] == null)"); + sw.WriteLine("\t\t\t\tGtkSharp.SignalCallback cb = Signals [{0}] as GtkSharp.SignalCallback;", cname); + sw.WriteLine("\t\t\t\tif (cb == null)"); + sw.WriteLine("\t\t\t\t\treturn;"); + sw.WriteLine(); + sw.WriteLine("\t\t\t\tcb.RemoveDelegate (value);"); + sw.WriteLine(); + sw.WriteLine("\t\t\t\tif (EventList[" + cname + "] == null) {"); sw.WriteLine("\t\t\t\t\tSignals.Remove(" + cname + ");"); - sw.WriteLine("\t\t\t\telse"); - sw.WriteLine("\t\t\t\t\t((GtkSharp.SignalCallback) Signals [{0}]).RemoveDelegate (value);", cname); + sw.WriteLine("\t\t\t\t\tcb.Dispose ();"); + sw.WriteLine("\t\t\t\t}"); sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); sw.WriteLine(); diff --git a/generator/SignalHandler.cs b/generator/SignalHandler.cs index 858e9108e..3488c2386 100644 --- a/generator/SignalHandler.cs +++ b/generator/SignalHandler.cs @@ -109,6 +109,9 @@ namespace GtkSharp.Generation { sw.WriteLine(); sw.WriteLine("\t\tprivate static " + dname + " _Delegate;"); sw.WriteLine(); + sw.WriteLine("\t\tprivate IntPtr _raw;"); + sw.WriteLine("\t\tprivate uint _HandlerID;"); + sw.WriteLine(); sw.Write("\t\tprivate static " + p_ret + " "); sw.WriteLine(cbname + "(" + pinv + ", int key)"); sw.WriteLine("\t\t{"); @@ -162,8 +165,8 @@ namespace GtkSharp.Generation { sw.WriteLine("\t\t}"); sw.WriteLine(); } - sw.Write("\t\t[DllImport(\"gobject-2.0\")]"); - sw.Write("\t\tstatic extern void g_signal_connect_data("); + sw.WriteLine("\t\t[DllImport(\"libgobject-2.0-0.dll\")]"); + sw.Write("\t\tstatic extern uint g_signal_connect_data("); sw.Write("IntPtr obj, String name, " + dname + " cb, int key, IntPtr p,"); sw.WriteLine(" int flags);"); sw.WriteLine(); @@ -173,14 +176,19 @@ namespace GtkSharp.Generation { sw.WriteLine("\t\t\tif (_Delegate == null) {"); sw.WriteLine("\t\t\t\t_Delegate = new " + dname + "(" + cbname + ");"); sw.WriteLine("\t\t\t}"); - sw.Write("\t\t\tg_signal_connect_data(raw, name, "); + sw.WriteLine("\t\t\t_raw = raw;"); + sw.Write("\t\t\t_HandlerID = g_signal_connect_data(raw, name, "); sw.WriteLine("_Delegate, _key, new IntPtr(0), 0);"); sw.WriteLine("\t\t}"); sw.WriteLine(); - sw.WriteLine("\t\t~" + sname + "()"); + sw.WriteLine("\t\t[DllImport(\"libgobject-2.0-0.dll\")]"); + sw.WriteLine("\t\tstatic extern void g_signal_handler_disconnect (IntPtr instance, uint handler);"); + sw.WriteLine(); + sw.WriteLine("\t\tprotected override void Dispose (bool disposing)"); sw.WriteLine("\t\t{"); sw.WriteLine("\t\t\t_Instances.Remove(_key);"); sw.WriteLine("\t\t\tif(_Instances.Count == 0) {"); + sw.WriteLine("\t\t\t\tg_signal_handler_disconnect (_raw, _HandlerID);"); sw.WriteLine("\t\t\t\t_Delegate = null;"); sw.WriteLine("\t\t\t}"); sw.WriteLine("\t\t}"); diff --git a/glib/SignalCallback.cs b/glib/SignalCallback.cs index 6e1b2b3f7..f267176bf 100644 --- a/glib/SignalCallback.cs +++ b/glib/SignalCallback.cs @@ -18,7 +18,7 @@ namespace GtkSharp { /// Base Class for GSignal to C# event marshalling. /// - public abstract class SignalCallback { + public abstract class SignalCallback : IDisposable { // A counter used to produce unique keys for instances. protected static int _NextKey = 0; @@ -58,5 +58,26 @@ namespace GtkSharp { { _handler = Delegate.Remove (_handler, d); } + + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + + protected virtual void Dispose (bool disposing) + { + if (disposing) { + _obj = null; + _handler = null; + _argstype = null; + } + } + + ~SignalCallback () + { + Dispose (false); + } } } +