mirror of
https://github.com/Ryujinx/GtkSharp.git
synced 2024-09-09 00:13:20 +02:00
2008-01-22 Mike Kestner <mkestner@novell.com>
* glib/Object.cs: expose an internal ToggleRef prop. * glib/Signal.cs: use ToggleRef for lookups instead of Object. Add a Free method and release connections and gchandles. * glib/ToggleRef.cs: add signal hash and release signals on free. svn path=/trunk/gtk-sharp/; revision=93548
This commit is contained in:
parent
5ccb3ccd2f
commit
776aeccdbb
@ -1,3 +1,10 @@
|
||||
2008-01-22 Mike Kestner <mkestner@novell.com>
|
||||
|
||||
* glib/Object.cs: expose an internal ToggleRef prop.
|
||||
* glib/Signal.cs: use ToggleRef for lookups instead of Object. Add
|
||||
a Free method and release connections and gchandles.
|
||||
* glib/ToggleRef.cs: add signal hash and release signals on free.
|
||||
|
||||
2008-01-17 Mike Kestner <mkestner@novell.com>
|
||||
|
||||
* glib/Object.cs: remove ref from Objects hash prior to releasing it.
|
||||
|
@ -32,6 +32,7 @@ namespace GLib {
|
||||
public class Object : IWrapper, IDisposable {
|
||||
|
||||
IntPtr handle;
|
||||
ToggleRef tref;
|
||||
bool disposed = false;
|
||||
Hashtable data;
|
||||
static Hashtable Objects = new Hashtable();
|
||||
@ -295,14 +296,17 @@ namespace GLib {
|
||||
return;
|
||||
|
||||
if (handle != IntPtr.Zero) {
|
||||
ToggleRef tref = Objects [handle] as ToggleRef;
|
||||
Objects.Remove (handle);
|
||||
if (tref != null)
|
||||
if (tref != null) {
|
||||
tref.Free ();
|
||||
tref = null;
|
||||
}
|
||||
}
|
||||
handle = value;
|
||||
if (value != IntPtr.Zero)
|
||||
Objects [value] = new ToggleRef (this);
|
||||
if (value != IntPtr.Zero) {
|
||||
tref = new ToggleRef (this);
|
||||
Objects [value] = tref;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -327,23 +331,19 @@ namespace GLib {
|
||||
}
|
||||
}
|
||||
|
||||
internal ToggleRef ToggleRef {
|
||||
get {
|
||||
return tref;
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
Hashtable signals;
|
||||
internal Hashtable Signals {
|
||||
get {
|
||||
if (signals == null)
|
||||
signals = new Hashtable ();
|
||||
return signals;
|
||||
}
|
||||
}
|
||||
|
||||
Hashtable before_signals;
|
||||
|
||||
[Obsolete ("Replaced by GLib.Signal marshaling mechanism.")]
|
||||
protected Hashtable BeforeSignals {
|
||||
get {
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace GLib {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
[Flags]
|
||||
@ -51,19 +52,33 @@ namespace GLib {
|
||||
public class Signal {
|
||||
|
||||
GCHandle gc_handle;
|
||||
Object obj;
|
||||
ToggleRef tref;
|
||||
string name;
|
||||
uint before_id = UInt32.MaxValue;
|
||||
uint after_id = UInt32.MaxValue;
|
||||
Delegate marshaler;
|
||||
|
||||
~Signal ()
|
||||
{
|
||||
gc_handle.Free ();
|
||||
}
|
||||
|
||||
private Signal (GLib.Object obj, string signal_name, Delegate marshaler)
|
||||
{
|
||||
this.obj = obj;
|
||||
tref = obj.ToggleRef;
|
||||
name = signal_name;
|
||||
this.marshaler = marshaler;
|
||||
gc_handle = GCHandle.Alloc (this, GCHandleType.Weak);
|
||||
obj.Signals [name] = this;
|
||||
tref.Signals [name] = this;
|
||||
}
|
||||
|
||||
internal void Free ()
|
||||
{
|
||||
DisconnectHandler (before_id);
|
||||
DisconnectHandler (after_id);
|
||||
before_handler = after_handler = marshaler = null;
|
||||
gc_handle.Free ();
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
public static Signal Lookup (GLib.Object obj, string name)
|
||||
@ -73,7 +88,7 @@ namespace GLib {
|
||||
|
||||
public static Signal Lookup (GLib.Object obj, string name, Delegate marshaler)
|
||||
{
|
||||
Signal result = obj.Signals [name] as Signal;
|
||||
Signal result = obj.ToggleRef.Signals [name] as Signal;
|
||||
if (result == null)
|
||||
result = new Signal (obj, name, marshaler);
|
||||
return result as Signal;
|
||||
@ -84,7 +99,7 @@ namespace GLib {
|
||||
|
||||
public Delegate Handler {
|
||||
get {
|
||||
InvocationHint hint = (InvocationHint) Marshal.PtrToStructure (g_signal_get_invocation_hint (obj.Handle), typeof (InvocationHint));
|
||||
InvocationHint hint = (InvocationHint) Marshal.PtrToStructure (g_signal_get_invocation_hint (tref.Handle), typeof (InvocationHint));
|
||||
if (hint.run_type == SignalFlags.RunFirst)
|
||||
return before_handler;
|
||||
else
|
||||
@ -95,7 +110,7 @@ namespace GLib {
|
||||
uint Connect (int flags)
|
||||
{
|
||||
IntPtr native_name = GLib.Marshaller.StringToPtrGStrdup (name);
|
||||
uint id = g_signal_connect_data (obj.Handle, native_name, marshaler, (IntPtr) gc_handle, IntPtr.Zero, flags);
|
||||
uint id = g_signal_connect_data (tref.Handle, native_name, marshaler, (IntPtr) gc_handle, IntPtr.Zero, flags);
|
||||
GLib.Marshaller.Free (native_name);
|
||||
return id;
|
||||
}
|
||||
@ -134,13 +149,13 @@ namespace GLib {
|
||||
}
|
||||
|
||||
if (after_id == UInt32.MaxValue && before_id == UInt32.MaxValue)
|
||||
obj.Signals.Remove (name);
|
||||
tref.Signals.Remove (name);
|
||||
}
|
||||
|
||||
void DisconnectHandler (uint handler_id)
|
||||
{
|
||||
if (handler_id != UInt32.MaxValue && g_signal_handler_is_connected (obj.Handle, handler_id))
|
||||
g_signal_handler_disconnect (obj.Handle, handler_id);
|
||||
if (handler_id != UInt32.MaxValue && g_signal_handler_is_connected (tref.Handle, handler_id))
|
||||
g_signal_handler_disconnect (tref.Handle, handler_id);
|
||||
}
|
||||
|
||||
[CDeclCallback]
|
||||
|
@ -22,6 +22,7 @@
|
||||
namespace GLib {
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
internal class ToggleRef {
|
||||
@ -29,6 +30,7 @@ namespace GLib {
|
||||
IntPtr handle;
|
||||
object reference;
|
||||
GCHandle gch;
|
||||
Hashtable signals;
|
||||
|
||||
public ToggleRef (GLib.Object target)
|
||||
{
|
||||
@ -50,6 +52,20 @@ namespace GLib {
|
||||
}
|
||||
}
|
||||
|
||||
public IntPtr Handle {
|
||||
get {
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
|
||||
public Hashtable Signals {
|
||||
get {
|
||||
if (signals == null)
|
||||
signals = new Hashtable ();
|
||||
return signals;
|
||||
}
|
||||
}
|
||||
|
||||
public GLib.Object Target {
|
||||
get {
|
||||
if (reference is GLib.Object)
|
||||
@ -62,6 +78,9 @@ namespace GLib {
|
||||
|
||||
public void Free ()
|
||||
{
|
||||
foreach (Signal s in Signals.Values)
|
||||
s.Free ();
|
||||
Signals.Clear ();
|
||||
g_object_remove_toggle_ref (handle, ToggleNotifyCallback, (IntPtr) gch);
|
||||
reference = null;
|
||||
gch.Free ();
|
||||
|
Loading…
Reference in New Issue
Block a user