GtkSharp/glib/SimpleSignal.cs
Mike Kestner 26142a99ca 2001-10-04 Mike Kestner <mkestner@speakeasy.net>
* glib/SimpleSignal.cs : Reworked to parallel SimpleEvent.

svn path=/trunk/gtk-sharp/; revision=1084
2001-10-04 23:27:19 +00:00

114 lines
2.9 KiB
C#

// GLib.Signals.Simple.cs - GLib Simple Signal implementation
//
// Authors: Bob Smith <bob@thestuff.net>
// Mike Kestner <mkestner@speakeasy.net>
//
// (c) 2001 Bob Smith & Mike Kestner
namespace GLib {
using System;
using System.Collections;
using System.Runtime.InteropServices;
using GLib;
/// <summary>
/// SimpleDelegate Delegate
/// </summary>
///
/// <remarks>
/// Used to connect to simple signals which contain no signal-
/// specific data.
/// </remarks>
public delegate void SimpleDelegate (IntPtr obj, int key);
/// <summary>
/// SimpleSignal Class
/// </summary>
///
/// <remarks>
/// Wraps a simple signal which contains no single-specific data.
/// </remarks>
public class SimpleSignal {
// A counter used to produce unique keys for instances.
private static int _NextKey = 0;
// Hashtable containing refs to all current instances.
private static Hashtable _Instances = new Hashtable ();
// locals to create and pin the shared delegate.
private static SimpleDelegate _Delegate;
private static GCHandle _GCHandle;
// Shared delegate that relays events to registered handlers.
private static void SimpleCallback(IntPtr obj, int inst_key)
{
if (!_Instances.Contains (inst_key))
throw new Exception ("Unexpected signal key");
SimpleSignal ss = (SimpleSignal) _Instances [inst_key];
EventArgs args = new EventArgs ();
ss._handler (ss._obj, args);
}
// private instance members
private GLib.Object _obj;
private EventHandler _handler;
private int _key;
/// <summary>
/// SimpleSignal Constructor
/// </summary>
///
/// <remarks>
/// Registers a new event handler for a specified signal.
/// A connection to the raw object signal is made which
/// causes any events which occur to be relayed to the
/// event handler.
/// </remarks>
[DllImport ("gobject-1.3.dll", CharSet=CharSet.Ansi,
CallingConvention=CallingConvention.Cdecl)]
static extern void g_signal_connect_data (
IntPtr obj, IntPtr name,
SimpleDelegate cb,
int key, IntPtr p, int flags);
public SimpleSignal (GLib.Object obj, IntPtr raw,
String name, EventHandler eh)
{
if (_Delegate == null) {
_Delegate = new SimpleDelegate(SimpleCallback);
/* FIXME: need layout attribute for
* SimpleCallback to avoid an exception.
* _GCHandle = GCHandle.Alloc (
* _Delegate, GCHandleType.Pinned);
*/
}
_key = _NextKey++;
_obj = obj;
_handler = eh;
_Instances [_key] = this;
g_signal_connect_data (
raw, Marshal.StringToHGlobalAnsi (name),
_Delegate, _key, new IntPtr (0), 0);
}
// Destructor needed to release references from the instance
// table and unpin the delegate if no refs remain.
~SimpleSignal ()
{
_Instances.Remove (_key);
if (_Instances.Count == 0) {
// FIXME: when pin works _GCHandle.Free();
_Delegate = null;
}
}
}
}