2002-07-16 Mike Kestner <mkestner@speakeasy.net>

* generator/ClassBase.cs : make MarshalType virtual.
	* generator/Parameters.cs : add Parameter class and Indexer.
	* generator/Signal.cs : Now use Parameters.
	(GetHandlerName): New abstraction of name handling.
	(GenerateDecls): use GetHandlerName.
	(GenComments): make private.
	(GenHandler): New. Generate custom event handlers and args.
	(Generate): use GenHandler. Pass args type to SignalHandler.
	* generate/SignalHandler.cs : store args type. Generate handler
	  dependent args and use MulticastDelegate.DynamicInvoke.
	* generate/StructGen.cs : override MarshalType.
	* glib/SignalCallback.cs : store a MulticastDelegate and args type
	* sample/*.cs : use new DeleteEventHandler

svn path=/trunk/gtk-sharp/; revision=5834
This commit is contained in:
Mike Kestner 2002-07-16 23:14:35 +00:00
parent caf4397b04
commit 8b85bf647a
10 changed files with 223 additions and 58 deletions

View File

@ -1,3 +1,19 @@
2002-07-16 Mike Kestner <mkestner@speakeasy.net>
* generator/ClassBase.cs : make MarshalType virtual.
* generator/Parameters.cs : add Parameter class and Indexer.
* generator/Signal.cs : Now use Parameters.
(GetHandlerName): New abstraction of name handling.
(GenerateDecls): use GetHandlerName.
(GenComments): make private.
(GenHandler): New. Generate custom event handlers and args.
(Generate): use GenHandler. Pass args type to SignalHandler.
* generate/SignalHandler.cs : store args type. Generate handler
dependent args and use MulticastDelegate.DynamicInvoke.
* generate/StructGen.cs : override MarshalType.
* glib/SignalCallback.cs : store a MulticastDelegate and args type
* sample/*.cs : use new DeleteEventHandler
2002-07-13 Rachel Hestilow <hestilow@ximian.com>
* generator/Parameters.cs: Allow nulls if null_ok set.

View File

@ -84,7 +84,7 @@ namespace GtkSharp.Generation {
}
}
public String MarshalType {
public virtual String MarshalType {
get
{
return "IntPtr";

View File

@ -10,6 +10,54 @@ namespace GtkSharp.Generation {
using System.IO;
using System.Xml;
public class Parameter {
private XmlElement elem;
public Parameter (XmlElement e)
{
elem = e;
}
public string CSType {
get {
return SymbolTable.GetCSType( elem.GetAttribute("type"));
}
}
public string Name {
get {
string name = elem.GetAttribute("name");
switch (name) {
case "string":
return "str1ng";
case "event":
return "evnt";
case "object":
return "objekt";
default:
break;
}
return name;
}
}
public string StudlyName {
get {
string name = elem.GetAttribute("name");
string[] segs = name.Split('_');
string studly = "";
foreach (string s in segs) {
studly += (s.Substring(0,1).ToUpper() + s.Substring(1));
}
return studly;
}
}
}
public class Parameters {
private XmlElement elem;
@ -29,6 +77,17 @@ namespace GtkSharp.Generation {
}
}
public Parameter this [int idx] {
get {
int count = 0;
foreach (XmlNode node in elem.ChildNodes) {
if ((node is XmlElement) && (idx == count++))
return new Parameter ((XmlElement) node);
}
return null;
}
}
public string ImportSig {
get {
return import_sig;

View File

@ -16,12 +16,15 @@ namespace GtkSharp.Generation {
private string marsh;
private string name;
private XmlElement elem;
private Parameters parms;
private ClassBase container_type;
public Signal (XmlElement elem, ClassBase container_type)
{
this.elem = elem;
this.name = elem.GetAttribute ("name");
if (elem["parameters"] != null)
parms = new Parameters (elem["parameters"]);
this.container_type = container_type;
}
@ -43,19 +46,27 @@ namespace GtkSharp.Generation {
return false;
}
if (parms != null && !parms.Validate ())
return false;
return true;
}
public void GenerateDecl (StreamWriter sw)
{
public void GenerateDecl (StreamWriter sw)
{
string argsname;
string handler = GetHandlerName (out argsname);
if (handler != "EventHandler")
handler = "GtkSharp." + handler;
GenComments (sw);
if (elem.HasAttribute("new_flag") || (container_type != null && container_type.GetSignalRecursively (Name) != null))
sw.Write("new ");
sw.WriteLine ("\t\tevent EventHandler " + Name + ";");
sw.WriteLine ("\t\tevent " + handler + " " + Name + ";");
}
public void GenComments (StreamWriter sw)
private void GenComments (StreamWriter sw)
{
sw.WriteLine();
sw.WriteLine("\t\t/// <summary> " + Name + " Event </summary>");
@ -63,22 +74,95 @@ namespace GtkSharp.Generation {
// FIXME: Generate some signal docs
sw.WriteLine("\t\t/// </remarks>");
}
private string GetHandlerName (out string argsname)
{
if (marsh == "voidObjectSignal") {
argsname = "EventArgs";
return "EventHandler";
}
argsname = Name + "Args";
return Name + "Handler";
}
private string GenHandler (out string argsname)
{
string handler = GetHandlerName (out argsname);
if (handler == "EventHandler")
return handler;
char sep = Path.DirectorySeparatorChar;
string dir = ".." + sep + container_type.NS.ToLower() + sep + "generated";
if (!Directory.Exists (dir))
Directory.CreateDirectory (dir);
string filename = dir + sep + "GtkSharp." + handler + ".cs";
FileStream stream = new FileStream (filename, FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter (stream);
sw.WriteLine ("// Generated File. Do not modify.");
sw.WriteLine ("// <c> 2001-2002 Mike Kestner");
sw.WriteLine ();
sw.WriteLine ("namespace GtkSharp {");
sw.WriteLine ();
sw.WriteLine ("\tusing System;");
sw.WriteLine ();
sw.WriteLine ("\t/// <summary> " + handler + " Delegate </summary>");
sw.WriteLine ("\t/// <remarks>");
sw.WriteLine ("\t///\tDelegate signature for " + Name + " Event handlers");
sw.WriteLine ("\t/// </remarks>");
sw.WriteLine ();
sw.WriteLine ("\tpublic delegate void " + handler + "(object o, " + argsname + " args);");
sw.WriteLine ();
sw.WriteLine ("\t/// <summary> " + argsname + " Class </summary>");
sw.WriteLine ("\t/// <remarks>");
sw.WriteLine ("\t///\tArguments for " + Name + " Event handlers");
sw.WriteLine ("\t/// </remarks>");
sw.WriteLine ();
sw.WriteLine ("\tpublic class " + argsname + " : GtkSharp.SignalArgs {");
if (parms != null) {
for (int i = 1; i < parms.Count; i++) {
sw.WriteLine ("\t\tpublic " + parms[i].CSType + " " + parms[i].StudlyName + "{");
sw.WriteLine ("\t\t\tget {");
sw.WriteLine ("\t\t\t\treturn (" + parms[i].CSType + ") Args[" + (i - 1) + "];");
sw.WriteLine ("\t\t\t}");
sw.WriteLine ("\t\t}");
sw.WriteLine ();
}
}
sw.WriteLine ("\t}");
sw.WriteLine ("}");
sw.Close ();
argsname = "GtkSharp." + argsname;
return "GtkSharp." + handler;
}
public void Generate (StreamWriter sw, ClassBase implementor, bool gen_docs)
{
string cname = "\"" + elem.GetAttribute("cname") + "\"";
marsh = "GtkSharp." + marsh;
string qual_marsh = "GtkSharp." + marsh;
if (gen_docs)
GenComments (sw);
string argsname;
string handler = GenHandler (out argsname);
sw.Write("\t\tpublic ");
if (elem.HasAttribute("new_flag") || (container_type != null && container_type.GetSignalRecursively (Name) != null) || (implementor != null && implementor.GetSignalRecursively (Name) != null))
sw.Write("new ");
sw.WriteLine("event EventHandler " + Name + " {");
sw.WriteLine("event " + handler + " " + Name + " {");
sw.WriteLine("\t\t\tadd {");
sw.WriteLine("\t\t\t\tif (EventList[" + cname + "] == null)");
sw.Write("\t\t\t\t\tSignals[" + cname + "] = new " + marsh);
sw.WriteLine("(this, Handle, " + cname + ", value);");
sw.Write("\t\t\t\t\tSignals[" + cname + "] = new " + qual_marsh);
sw.Write("(this, Handle, " + cname + ", value, System.Type.GetType(\"" + argsname);
if (argsname != "EventArgs")
sw.Write("," + container_type.NS.ToLower() + "-sharp");
sw.WriteLine("\"));");
sw.WriteLine("\t\t\t\tEventList.AddHandler(" + cname + ", value);");
sw.WriteLine("\t\t\t}");
sw.WriteLine("\t\t\tremove {");

View File

@ -14,6 +14,7 @@ namespace GtkSharp.Generation {
public class SignalHandler {
private static Hashtable handlers = new Hashtable ();
private string args_type;
public static String GetName(XmlElement sig)
{
@ -23,22 +24,23 @@ namespace GtkSharp.Generation {
return "";
}
String retval = ret_elem.GetAttribute("type");
string retval = ret_elem.GetAttribute("type");
if (retval == "") {
Console.Write("Invalid return-type ");
return "";
}
String s_ret = SymbolTable.GetCSType(retval);
String p_ret = SymbolTable.GetMarshalType(retval);
string s_ret = SymbolTable.GetCSType(retval);
string p_ret = SymbolTable.GetMarshalType(retval);
if ((s_ret == "") || (p_ret == "")) {
Console.Write("Funky type: " + retval);
return "";
}
String key = retval;
String pinv = "";
String name = SymbolTable.GetName(retval);
string key = retval;
string pinv = "";
string name = SymbolTable.GetName(retval);
string argfields = "";
int pcnt = 0;
ArrayList parms = new ArrayList();
@ -53,8 +55,8 @@ namespace GtkSharp.Generation {
if (!(parm is XmlElement) || parm.Name != "parameter") continue;
XmlElement elem = (XmlElement) parm;
String type = elem.GetAttribute("type");
String ptype = SymbolTable.GetMarshalType(type);
string type = elem.GetAttribute("type");
string ptype = SymbolTable.GetMarshalType(type);
if (ptype == "") {
Console.Write("Funky type: " + type);
return "";
@ -99,8 +101,6 @@ namespace GtkSharp.Generation {
String sname = name + "Signal";
String dname = name + "Delegate";
String cbname = name + "Callback";
String hndlrname = name + "Handler";
String argsname = name + "Args";
handlers[name] = sname;
@ -124,11 +124,6 @@ namespace GtkSharp.Generation {
sw.Write("\tpublic delegate " + p_ret + " ");
sw.WriteLine(dname + "(" + pinv + ", int key);");
sw.WriteLine();
sw.WriteLine("\tpublic delegate void " + hndlrname + "(object o, " + argsname + " args);");
sw.WriteLine();
sw.WriteLine("\tpublic class " + argsname + " : EventArgs {");
sw.WriteLine("\t}");
sw.WriteLine();
sw.WriteLine("\tpublic class " + sname + " : SignalCallback {");
sw.WriteLine();
sw.WriteLine("\t\tprivate static " + dname + " _Delegate;");
@ -140,37 +135,47 @@ namespace GtkSharp.Generation {
sw.WriteLine("\t\t\t\tthrow new Exception(\"Unexpected signal key\");");
sw.WriteLine();
sw.WriteLine("\t\t\t" + sname + " inst = (" + sname + ") _Instances[key];");
sw.WriteLine("\t\t\tSignalArgs args = new SignalArgs();");
if (parms.Count > 1) {
sw.WriteLine("\t\t\targs.Args = new object[" + (parms.Count-1) + "];");
}
for (int idx=1; idx < parms.Count; idx++) {
if (SymbolTable.IsObject((String)parms[idx])) {
sw.Write("\t\t\targs.Args[" + (idx-1) + "] ");
sw.WriteLine("= GLib.Object.GetObject(arg" + idx + ");");
} else {
string ctype = (string) parms[idx];
sw.WriteLine("\t\t\targs.Args[" + (idx-1) + "] = " + SymbolTable.FromNative (ctype, "arg" + idx) + ";");
ClassBase wrapper = SymbolTable.GetClassGen (ctype);
if ((wrapper != null && !(wrapper is InterfaceGen)) || SymbolTable.IsManuallyWrapped (ctype) || SymbolTable.IsBoxed (ctype)) {
sw.WriteLine("\t\t\tif (args.Args[" + (idx-1) + "] == null)");
sw.WriteLine("\t\t\t\targs.Args[{0}] = new {1}(arg{2});", idx-1, SymbolTable.GetCSType (ctype), idx);
if ((s_ret == "void") && (parms.Count == 1)) {
sw.WriteLine("\t\t\tEventHandler h = (EventHandler) inst._handler;");
sw.WriteLine("\t\t\th (inst._obj, new EventArgs ());");
sw.WriteLine("\t\t}");
sw.WriteLine();
} else {
sw.WriteLine("\t\t\tSignalArgs args = (SignalArgs) Activator.CreateInstance (inst._argstype);");
if (parms.Count > 1) {
sw.WriteLine("\t\t\targs.Args = new object[" + (parms.Count-1) + "];");
}
for (int idx=1; idx < parms.Count; idx++) {
if (SymbolTable.IsObject((String)parms[idx])) {
sw.Write("\t\t\targs.Args[" + (idx-1) + "] ");
sw.WriteLine("= GLib.Object.GetObject(arg" + idx + ");");
} else {
string ctype = (string) parms[idx];
sw.WriteLine("\t\t\targs.Args[" + (idx-1) + "] = " + SymbolTable.FromNative (ctype, "arg" + idx) + ";");
ClassBase wrapper = SymbolTable.GetClassGen (ctype);
if ((wrapper != null && !(wrapper is InterfaceGen)) || SymbolTable.IsManuallyWrapped (ctype) || SymbolTable.IsBoxed (ctype)) {
sw.WriteLine("\t\t\tif (args.Args[" + (idx-1) + "] == null)");
sw.WriteLine("\t\t\t\targs.Args[{0}] = new {1}(arg{2});", idx-1, SymbolTable.GetCSType (ctype), idx);
}
}
}
sw.WriteLine("\t\t\tobject[] argv = new object[2];");
sw.WriteLine("\t\t\targv[0] = inst._obj;");
sw.WriteLine("\t\t\targv[1] = args;");
sw.WriteLine("\t\t\tinst._handler.DynamicInvoke(argv);");
if (retval != "void") {
sw.WriteLine("\t\t\treturn (" + s_ret + ") args.RetVal;");
}
sw.WriteLine("\t\t}");
sw.WriteLine();
}
sw.WriteLine("\t\t\tinst._handler (inst._obj, args);");
if (retval != "void") {
sw.WriteLine("\t\t\treturn (" + s_ret + ") args.RetVal;");
}
sw.WriteLine("\t\t}");
sw.WriteLine();
sw.Write("\t\t[DllImport(\"gobject-2.0\")]");
sw.Write("\t\tstatic extern void g_signal_connect_data(");
sw.Write("IntPtr obj, String name, " + dname + " cb, int key, IntPtr p,");
sw.WriteLine(" int flags);");
sw.WriteLine();
sw.Write("\t\tpublic " + sname + "(GLib.Object obj, IntPtr raw, ");
sw.WriteLine("String name, EventHandler eh) : base(obj, eh)");
sw.WriteLine("String name, MulticastDelegate eh, Type argstype) : base(obj, eh, argstype)");
sw.WriteLine("\t\t{");
sw.WriteLine("\t\t\tif (_Delegate == null) {");
sw.WriteLine("\t\t\t\t_Delegate = new " + dname + "(" + cbname + ");");

View File

@ -14,7 +14,7 @@ namespace GtkSharp.Generation {
public StructGen (XmlElement ns, XmlElement elem) : base (ns, elem) {}
public new string MarshalType {
public override string MarshalType {
get
{
return QualifiedName;

View File

@ -28,8 +28,9 @@ namespace GtkSharp {
// protected instance members
protected GLib.Object _obj;
protected EventHandler _handler;
protected MulticastDelegate _handler;
protected int _key;
protected Type _argstype;
/// <summary>
/// SignalCallback Constructor
@ -39,11 +40,12 @@ namespace GtkSharp {
/// Initializes instance data.
/// </remarks>
public SignalCallback (GLib.Object obj, EventHandler eh)
public SignalCallback (GLib.Object obj, MulticastDelegate eh, Type argstype)
{
_key = _NextKey++;
_obj = obj;
_handler = eh;
_argstype = argstype;
_Instances [_key] = this;
}

View File

@ -18,7 +18,7 @@ namespace GtkSamples {
Application.Init ();
Window win = new Window ("Button Tester");
win.DefaultSize = new Size (200, 150);
win.DeleteEvent += new EventHandler (Window_Delete);
win.DeleteEvent += new DeleteEventHandler (Window_Delete);
Button btn = new Button ("Click Me");
btn.Clicked += new EventHandler (btn_click);
win.Add (btn);
@ -32,11 +32,10 @@ namespace GtkSamples {
Console.WriteLine ("Button Clicked");
}
static void Window_Delete (object obj, EventArgs args)
static void Window_Delete (object obj, DeleteEventArgs args)
{
SignalArgs sa = (SignalArgs) args;
Application.Quit ();
sa.RetVal = true;
args.RetVal = true;
}
}

View File

@ -17,13 +17,13 @@ namespace GtkSamples {
{
Application.Init ();
Gtk.Window win = new Gtk.Window ("Gtk# Hello World");
win.DeleteEvent += new EventHandler (Window_Delete);
win.DeleteEvent += new DeleteEventHandler (Window_Delete);
win.ShowAll ();
Application.Run ();
return 0;
}
static void Window_Delete (object obj, EventArgs args)
static void Window_Delete (object obj, DeleteEventArgs args)
{
SignalArgs sa = (SignalArgs) args;
Application.Quit ();

View File

@ -17,7 +17,7 @@ namespace GtkSharp.Samples {
{
Application.Init();
Window win = new Window ("Menu Sample App");
win.DeleteEvent += new EventHandler (delete_cb);
win.DeleteEvent += new DeleteEventHandler (delete_cb);
win.DefaultSize = new Size(200, 150);
VBox box = new VBox (false, 2);
@ -41,7 +41,7 @@ namespace GtkSharp.Samples {
Application.Run ();
}
static void delete_cb (object o, EventArgs args)
static void delete_cb (object o, DeleteEventArgs args)
{
SignalArgs sa = (SignalArgs) args;
Application.Quit ();