2001-10-04 Mike Kestner <mkestner@speakeasy.net>

* HACKING : Little bit of cleanup.
	* gdk/SimpleEvent.cs : Redesigned a bit. Docs.  Replaced refcounting
	mechanism with an instance hash and added ctor/dtor.  This class
	now completely encapsulates the signal attachment and forwarding
	mechanism for GdkEvent based signals.  It attaches to the raw signal,
	maintains a ref to the associated event handler, and uses the static
	callback to activate the event handler on signal receipt.
	* sample/makefile : killed one last CSC explicit reference.

svn path=/trunk/gtk-sharp/; revision=1076
This commit is contained in:
Mike Kestner 2001-10-04 19:12:55 +00:00
parent bda62ac3b7
commit bb326f46c9
4 changed files with 112 additions and 45 deletions

View file

@ -1,3 +1,14 @@
2001-10-04 Mike Kestner <mkestner@speakeasy.net>
* HACKING : Little bit of cleanup.
* gdk/SimpleEvent.cs : Redesigned a bit. Docs. Replaced refcounting
mechanism with an instance hash and added ctor/dtor. This class
now completely encapsulates the signal attachment and forwarding
mechanism for GdkEvent based signals. It attaches to the raw signal,
maintains a ref to the associated event handler, and uses the static
callback to activate the event handler on signal receipt.
* sample/makefile : killed one last CSC explicit reference.
2001-10-02 Mike Kestner <mkestner@speakeasy.net>
* glib/Value.cs : Tried adding CallingConvention.Cdecl to all the

24
HACKING
View file

@ -1,19 +1,15 @@
Please please please hack on gtk-sharp.
Okay, now for the details.
Before beginning work on something, please post your intentions to the
mailing list (gtk-sharp-list@ximian.com). Duplication of effort just gets
folks cranky in general.
Prior to checking anything into CVS, please send a patch to the mailing list
(gtk-sharp-list@ximian.com) for approval. Any patches should be submitted in
diff -u format. Also, it is assumed that the submitter has verified that the
patch does not break the build, and hopefully that it doesn't break runtime.
for approval. Any patches should be submitted in diff -u format. Also, it is
assumed that the submitter has verified that the patch does not break the
build, and hopefully that it doesn't break runtime.
Second, patches without Documentation comments will be seriously frowned upon,
Patches without Documentation comments will be seriously frowned upon,
if not outright rejected. All classes, methods, properties, events, etc...
that are non-private should be documented with XML comment tags. At a minimum,
the summary and remarks tags, plus returns and params, if applicable.
Third, Make a ChangeLog entry. Get credit for your hard work, and let me know
who I need to get cranky with at a glance, instead of having to do cvs history
reports. :-)
Fourth, please please please hack on gtk-sharp.
the summary and remarks tags, plus returns and params, if applicable. Doing
this as we go is the only feasible way to make sure that our docs won't end
up sucking bigtime.

View file

@ -6,6 +6,7 @@
namespace Gdk {
using System;
using System.Collections;
using System.Runtime.InteropServices;
using GLib;
using Gdk;
@ -29,42 +30,103 @@ namespace Gdk {
}
}
public delegate bool SimpleEventDelegate(IntPtr obj, IntPtr e, String name);
/// <summary>
/// SimpleEventDelegate Delegate
/// </summary>
///
/// <remarks>
/// Callback used to connect to GdkEvent based signals.
/// </remarks>
public delegate bool SimpleEventDelegate(IntPtr obj, IntPtr e,
int key);
/// <summary>
/// SimpleEvent Class
/// </summary>
///
/// <remarks>
/// Connects to a specified signal on a raw object and relays
/// events to an EventHandle when they occur.
/// </remarks>
public class SimpleEvent {
private static bool SimpleEventCallback (IntPtr obj, IntPtr e, String name)
{
GLib.Object o = GLib.Object.GetObject (obj);
EventHandler eh = (EventHandler) o.Events [name];
if (eh != null)
{
EventArgs args = new SimpleEventArgs (new Gdk.Event(e));
eh(o, args);
}
return true; //FIXME: How do we manage the return value?
}
private static int _RefCount;
// A Counter used to produce unique keys for instances.
private static int _NextKey = 0;
// A hash table containing refs to all current instances.
private static Hashtable _Instances = new Hashtable ();
// locals to create and pin the shared delegate.
private static SimpleEventDelegate _Delegate;
private static GCHandle _GCHandle;
public static SimpleEventDelegate Delegate
// Shared delegate that relays events to registered handlers
private static bool SimpleEventCallback (IntPtr obj, IntPtr e,
int inst_key)
{
get
{
if (_Delegate == null)
{
_Delegate = new SimpleEventDelegate(SimpleEventCallback);
_GCHandle = GCHandle.Alloc (_Delegate, GCHandleType.Pinned);
if (!_Instances.Contains (inst_key))
throw new Exception ("Unexpected event key");
SimpleEvent se = (SimpleEvent) _Instances [inst_key];
EventArgs args = new SimpleEventArgs (
new Gdk.Event (e));
se._handler (se._obj, args);
return true; //FIXME: How do we manage the return value?
}
_RefCount++;
return _Delegate;
}
}
public static void Unref()
// private instance members
private GLib.Object _obj;
private EventHandler _handler;
private int _key;
/// <summary>
/// SimpleEvent 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, SimpleEventDelegate eh,
int key, IntPtr p, int flags);
public SimpleEvent (GLib.Object obj, IntPtr raw,
String name, EventHandler eh)
{
_RefCount--;
if (_RefCount < 1)
if (_Delegate == null) {
_Delegate = new SimpleEventDelegate (
SimpleEventCallback);
_GCHandle = GCHandle.Alloc (
_Delegate, GCHandleType.Pinned);
}
_key = _NextKey++;
_Instances [_key] = this;
_obj = obj;
_handler = eh;
g_signal_connect_data (
raw, Marshal.StringToHGlobalAnsi (name),
_Delegate, _key, new IntPtr (0), 0);
}
// Destructor is needed to release references from the instance
// table and unpin the delegate if no refs remain.
~SimpleEvent ()
{
_RefCount = 0;
// FIXME: Disconnect the signal
_Instances.Remove (_key);
if (_Instances.Count == 0) {
_GCHandle.Free();
_Delegate = null;
}

View file

@ -1,5 +1,3 @@
CSC=/cygdrive/c/winnt/microsoft.net/framework/v1.0.2914/csc.exe
all:
@echo "You must use 'make windows' or 'make unix'."
@echo "'make unix' is broken for now."