2001-10-04 Mike Kestner <mkestner@speakeasy.net>
* glib/SimpleSignal.cs : Reworked to parallel SimpleEvent. svn path=/trunk/gtk-sharp/; revision=1084
This commit is contained in:
parent
4c5e4f1d56
commit
26142a99ca
2 changed files with 70 additions and 31 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
2001-10-04 Mike Kestner <mkestner@speakeasy.net>
|
||||||
|
|
||||||
|
* glib/SimpleSignal.cs : Reworked to parallel SimpleEvent.
|
||||||
|
|
||||||
2001-10-04 Mike Kestner <mkestner@speakeasy.net>
|
2001-10-04 Mike Kestner <mkestner@speakeasy.net>
|
||||||
|
|
||||||
* gtk/Widget.cs : Implemented all the bool, string, and int props.
|
* gtk/Widget.cs : Implemented all the bool, string, and int props.
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
namespace GLib {
|
namespace GLib {
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using GLib;
|
using GLib;
|
||||||
|
|
||||||
|
@ -19,7 +20,7 @@ namespace GLib {
|
||||||
/// specific data.
|
/// specific data.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
|
|
||||||
public delegate void SimpleDelegate (IntPtr obj, String name);
|
public delegate void SimpleDelegate (IntPtr obj, int key);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// SimpleSignal Class
|
/// SimpleSignal Class
|
||||||
|
@ -31,47 +32,81 @@ namespace GLib {
|
||||||
|
|
||||||
public class SimpleSignal {
|
public class SimpleSignal {
|
||||||
|
|
||||||
private static int _RefCount = 0;
|
// 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 SimpleDelegate _Delegate;
|
||||||
private static GCHandle _GCHandle;
|
private static GCHandle _GCHandle;
|
||||||
|
|
||||||
private static void SimpleCallback(IntPtr obj, String name)
|
// Shared delegate that relays events to registered handlers.
|
||||||
|
private static void SimpleCallback(IntPtr obj, int inst_key)
|
||||||
{
|
{
|
||||||
Object o = Object.GetObject(obj);
|
if (!_Instances.Contains (inst_key))
|
||||||
EventHandler eh = (EventHandler) o.Events[name];
|
throw new Exception ("Unexpected signal key");
|
||||||
if (eh != null)
|
|
||||||
{
|
SimpleSignal ss = (SimpleSignal) _Instances [inst_key];
|
||||||
eh(o, EventArgs.Empty);
|
EventArgs args = new EventArgs ();
|
||||||
}
|
ss._handler (ss._obj, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleDelegate Delegate
|
// private instance members
|
||||||
{
|
private GLib.Object _obj;
|
||||||
get
|
private EventHandler _handler;
|
||||||
{
|
private int _key;
|
||||||
if (_Delegate == null)
|
|
||||||
|
/// <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);
|
_Delegate = new SimpleDelegate(SimpleCallback);
|
||||||
|
|
||||||
/* FIXME: Can't do this until a layout attribute is defined for SimpleCallback
|
/* FIXME: need layout attribute for
|
||||||
* apparently, since this throws an ArgumentException:Type does not have a
|
* SimpleCallback to avoid an exception.
|
||||||
* layout attribute.
|
* _GCHandle = GCHandle.Alloc (
|
||||||
*
|
* _Delegate, GCHandleType.Pinned);
|
||||||
* _GCHandle = GCHandle.Alloc (_Delegate, GCHandleType.Pinned);
|
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
_RefCount++;
|
|
||||||
return _Delegate;
|
_key = _NextKey++;
|
||||||
}
|
_obj = obj;
|
||||||
|
_handler = eh;
|
||||||
|
_Instances [_key] = this;
|
||||||
|
|
||||||
|
g_signal_connect_data (
|
||||||
|
raw, Marshal.StringToHGlobalAnsi (name),
|
||||||
|
_Delegate, _key, new IntPtr (0), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Unref()
|
// Destructor needed to release references from the instance
|
||||||
|
// table and unpin the delegate if no refs remain.
|
||||||
|
~SimpleSignal ()
|
||||||
{
|
{
|
||||||
_RefCount--;
|
_Instances.Remove (_key);
|
||||||
if (_RefCount < 1)
|
|
||||||
{
|
if (_Instances.Count == 0) {
|
||||||
_RefCount = 0;
|
// FIXME: when pin works _GCHandle.Free();
|
||||||
_GCHandle.Free();
|
|
||||||
_Delegate = null;
|
_Delegate = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue