diff --git a/AUTHORS b/AUTHORS index fd7d3e1e0..80caabeb4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -12,4 +12,4 @@ Documentation: Jamin Philip Gray chris@turchin.net (Chris Turchin) jaspervp@gmx.net (Jasper van Putten) - wizito@gentelibre.org + wizito@gentelibre.org ( Néstor Salceda) diff --git a/ChangeLog b/ChangeLog index 7867ebd3f..0d4830a76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2004-09-18 Miguel de Icaza + + * glib/Source.cs: Add new base class to hold the method to be + called, and the proxy handler we use to keep references to them + and avoid a collection. + + Exposes a new variables that references all the active Timeouts + and Idle handlers to avoid collection/ + + * glib/Timeout.cs: Implement TimeoutProxy that acts as a filter to + remove the proxy when the timeout is removed. + + Register a TimeoutProxy when we create a timeout. + + * glib/Idle.cs: Implement IdleProxy that acts as a filter to + remove the proxy when the idle handler is removed. + + Register an IdleProxy when we create a timeout. + 2004-09-17 Mike Kestner * configure.in : bump version and tag for 1.0.2. diff --git a/glib/Idle.cs b/glib/Idle.cs index 3ec838606..7e52d3038 100755 --- a/glib/Idle.cs +++ b/glib/Idle.cs @@ -30,6 +30,24 @@ namespace GLib { public class Idle { + internal class IdleProxy : SourceProxy { + public IdleProxy (IdleHandler real) + { + real_handler = real; + proxy_handler = new IdleHandler (Handler); + } + + public bool Handler () + { + IdleHandler idle_handler = (IdleHandler) real_handler; + + bool cont = idle_handler (); + if (!cont) + Remove (); + return cont; + } + } + private Idle () { } @@ -39,7 +57,11 @@ namespace GLib { public static uint Add (IdleHandler hndlr) { - return g_idle_add (hndlr, IntPtr.Zero); + IdleProxy p = new IdleProxy (hndlr); + uint code = g_idle_add ((IdleHandler) p.proxy_handler, IntPtr.Zero); + Source.source_handlers [code] = p; + + return code; } [DllImport("libglib-2.0-0.dll")] @@ -47,9 +69,14 @@ namespace GLib { public static bool Remove (IdleHandler hndlr) { + foreach (int code in Source.source_handlers.Keys){ + IdleProxy p = (IdleProxy) Source.source_handlers [code]; + + if (p.real_handler == hndlr) + Source.source_handlers.Remove (p); + } return g_source_remove_by_funcs_user_data (hndlr, IntPtr.Zero); } - } } diff --git a/glib/Source.cs b/glib/Source.cs index 62ac0e172..76b3295c2 100644 --- a/glib/Source.cs +++ b/glib/Source.cs @@ -22,16 +22,37 @@ namespace GLib { using System; + using System.Collections; using System.Runtime.InteropServices; + // + // Base class for IdleProxy and TimeoutProxy + // + internal class SourceProxy { + internal Delegate real_handler; + internal Delegate proxy_handler; + + internal void Remove () + { + Source.source_handlers.Remove (this); + real_handler = null; + proxy_handler = null; + } + } + public class Source { private Source () {} + internal static Hashtable source_handlers = new Hashtable (); + [DllImport("libglib-2.0-0.dll")] static extern bool g_source_remove (uint tag); public static bool Remove (uint tag) { + if (source_handlers.Contains (tag)) + source_handlers.Remove (tag); + return g_source_remove (tag); } } diff --git a/glib/Timeout.cs b/glib/Timeout.cs index e09dad078..aa2218657 100755 --- a/glib/Timeout.cs +++ b/glib/Timeout.cs @@ -28,13 +28,36 @@ namespace GLib { public class Timeout { + internal class TimeoutProxy : SourceProxy { + public TimeoutProxy (TimeoutHandler real) + { + real_handler = real; + proxy_handler = new TimeoutHandler (Handler); + } + + public bool Handler () + { + TimeoutHandler timeout_handler = (TimeoutHandler) real_handler; + + bool cont = timeout_handler (); + if (!cont) + Remove (); + return cont; + } + } + private Timeout () {} [DllImport("libglib-2.0-0.dll")] static extern uint g_timeout_add (uint interval, TimeoutHandler d, IntPtr data); public static uint Add (uint interval, TimeoutHandler hndlr) { - return g_timeout_add (interval, hndlr, IntPtr.Zero); + TimeoutProxy p = new TimeoutProxy (hndlr); + + uint code = g_timeout_add (interval, (TimeoutHandler) p.proxy_handler, IntPtr.Zero); + Source.source_handlers [code] = p; + + return code; } } }