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:
parent
bda62ac3b7
commit
bb326f46c9
4 changed files with 112 additions and 45 deletions
11
ChangeLog
11
ChangeLog
|
@ -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
24
HACKING
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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."
|
||||
|
|
Loading…
Reference in a new issue