[Gtk-sharp-list] Returning Gdk.Events

Jonathan Pryor jonpryor@vt.edu
11 Mar 2003 15:25:35 -0500


--=-YXJwgzpvJSyoaDths0by
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

It sounds like the problem is that the GTK+ API is using unions.  If
that's the underlying problem, then why don't we just use unions in C#? 
It's still possible, though it uses a syntax only a mother could love
(the StructLayout and FieldOffset attributes).

See the attached file for an example.

The basic idea is to have an internal class/struct which acts as a union
of all supported GTK+ event types.  The Gdk.Event class then holds an
instance of the union and exposes properties to get at (1) the actual
type (GdkEventType) and (2) the event information held in the union.

In the attached file I throw exceptions if an illegal event is
referenced, but that might not be a good idea.  It's just a demo,
anyway...

The benefit to doing this is that we would avoid boxing/unboxing
penalties.  Alas, we lose the ability to use "is" on the returned type
for a EventButton vs. EventScroll...

 - Jon

On Tue, 2003-03-11 at 14:12, Miguel de Icaza wrote:
> Hello!
> 
> > My suggested solution is to use something like:
> > 
> >  		public static Gdk.Event CurrrentEvent {
> >  			IntPtr handle = gtk_get_current_event ();
> > 			GdkEventType type;
> > 
> > 			type = (GdkEventType)Marshal.Read32 (handle);
> > 			switch (type) {
> > 			case GdkEventType.Expose:
> > 				return (Gdk.Event)Marshal.PtrToStructure (handle, typeof (Gdk.EventExpose));
> > 			case GdkEventType.ButtonPress:
> > 				return (Gdk.Event)Marshal.PtrToStructure (handle, typeof (Gdk.ButtonPress));
> > 			...
> > 			}
> >  		}
> > 
> > Modulo some small details, it should work nicely.
> 
> There is only one problem here: Gdk.Event is a class, and the various
> Gdk.EventXXXX are structures that do not share a common base class.
> 
> I could change the signature to return an `object' instead of a
> Gdk.Event, and it would be up to the user to do an `is' compare on the
> result.
> 
> Miguel
> _______________________________________________
> Gtk-sharp-list maillist  -  Gtk-sharp-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/gtk-sharp-list

--=-YXJwgzpvJSyoaDths0by
Content-Disposition: attachment; filename=union.cs
Content-Type: text/plain; name=union.cs; charset=UTF-8
Content-Transfer-Encoding: 7bit

// Faking Unions in C#

using System;
using System.Runtime.InteropServices;

public enum EventTypes {Foo, Bar}

public struct FooEvent {public int n;}
public struct BarEvent {public long m;}

[StructLayout(LayoutKind.Explicit)]
internal struct EventInfo {
  [FieldOffset(0)] internal FooEvent f;
  [FieldOffset(0)] internal BarEvent b;
}

public class Event {
  private EventTypes type;
  public EventTypes EventType {
    get {return type;}
  }

  private EventInfo _event;

  public Event (FooEvent f) {
    _event.f = f;
    type = EventTypes.Foo;
  }

  public Event (BarEvent b) {
    _event.b = b;
    type = EventTypes.Bar;
  }

  public FooEvent FooEvent {
    get {
      if (type != EventTypes.Foo)
        throw new Exception ("invalid type");
      return _event.f;
    }
  }

  public BarEvent BarEvent {
    get {
      if (type != EventTypes.Bar)
        throw new Exception ("invalid type");
      return _event.b;
    }
  }
}

class R {
  public static void Main () {
    FooEvent f;
    f.n = 42;
    Event e = new Event (f);
    Console.WriteLine ("valid use: {0}", e.FooEvent);
    Console.WriteLine ("invalid use: {0}", e.BarEvent);
  }
}


--=-YXJwgzpvJSyoaDths0by--