From 1d105a960b07548291e8838ae9c7ac0d296b461b Mon Sep 17 00:00:00 2001 From: Mike Kestner Date: Fri, 26 Jan 2007 20:46:09 +0000 Subject: [PATCH] 2007-01-09 Mike Kestner * generator/CallbackGen.cs : add PersistUntilCalled method generation to the wrapper class. Holds a GCHandle for the wrapper which is Freed when the delegate is invoked. * generator/MethodBody.cs : add "async" case for delegate scope. Use this scope to identify a callback parameter that needs to persist until the native side calls back. Only valid for single-invoke callbacks. * gtk/Gtk.metadata : mark Print.RunPageSetupDialogAsync done_cb param with the new async scope. svn path=/trunk/gtk-sharp/; revision=71767 --- ChangeLog | 12 ++++++++++++ generator/CallbackGen.cs | 21 ++++++++++++++------- generator/MethodBody.cs | 4 ++++ gtk/Gtk.metadata | 1 + 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index a29efc50f..0b7949d6f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-01-09 Mike Kestner + + * generator/CallbackGen.cs : add PersistUntilCalled method generation + to the wrapper class. Holds a GCHandle for the wrapper which is Freed + when the delegate is invoked. + * generator/MethodBody.cs : add "async" case for delegate scope. Use + this scope to identify a callback parameter that needs to persist + until the native side calls back. Only valid for single-invoke + callbacks. + * gtk/Gtk.metadata : mark Print.RunPageSetupDialogAsync done_cb param + with the new async scope. + 2007-01-09 Mike Kestner * sample/GtkDemo/DemoPixbuf.cs : use Marshal.Copy properly diff --git a/generator/CallbackGen.cs b/generator/CallbackGen.cs index b2669dec1..efd18344c 100644 --- a/generator/CallbackGen.cs +++ b/generator/CallbackGen.cs @@ -98,6 +98,7 @@ namespace GtkSharp.Generation { sw.WriteLine ("namespace " + NS + "Sharp {"); sw.WriteLine (); sw.WriteLine ("\tusing System;"); + sw.WriteLine ("\tusing System.Runtime.InteropServices;"); sw.WriteLine (); sw.WriteLine ("#region Autogenerated code"); sw.WriteLine ("\t[GLib.CDeclCallback]"); @@ -138,15 +139,13 @@ namespace GtkSharp.Generation { idx++; } + cleanup_str += "\t\t\tif (release_on_call)\n\t\t\t\tgch.Free ();\n"; + sw.Write ("\t\t\t"); string invoke = "managed (" + call_str + ")"; if (retval.MarshalType != "void") { - if (cleanup_str == "") - sw.Write ("return "); - else { - sw.Write (retval.MarshalType + " ret = "); - cleanup_str += "\t\t\treturn ret;\n"; - } + sw.Write (retval.MarshalType + " ret = "); + cleanup_str += "\t\t\treturn ret;\n"; SymbolTable table = SymbolTable.Table; ClassBase ret_wrapper = table.GetClassGen (retval.CType); @@ -167,7 +166,15 @@ namespace GtkSharp.Generation { sw.Write (cleanup_str); sw.WriteLine ("\t\t}"); sw.WriteLine (); - + sw.WriteLine ("\t\tbool release_on_call = false;"); + sw.WriteLine ("\t\tGCHandle gch;"); + sw.WriteLine (); + sw.WriteLine ("\t\tpublic void PersistUntilCalled ()"); + sw.WriteLine ("\t\t{"); + sw.WriteLine ("\t\t\trelease_on_call = true;"); + sw.WriteLine ("\t\t\tgch = GCHandle.Alloc (this);"); + sw.WriteLine ("\t\t}"); + sw.WriteLine (); sw.WriteLine ("\t\tinternal " + wrapper + " NativeDelegate;"); sw.WriteLine ("\t\t" + NS + "." + Name + " managed;"); sw.WriteLine (); diff --git a/generator/MethodBody.cs b/generator/MethodBody.cs index bb0ca689e..348861b1b 100644 --- a/generator/MethodBody.cs +++ b/generator/MethodBody.cs @@ -155,6 +155,10 @@ namespace GtkSharp.Generation { sw.WriteLine (indent + "\t\t\t}"); break; + case "async": + sw.WriteLine (indent + "\t\t\t{0} {1}_wrapper = new {0} ({1});", wrapper, name); + sw.WriteLine (indent + "\t\t\t{0}_wrapper.PersistUntilCalled ();", name); + break; case "call": default: if (p.Scope == String.Empty) diff --git a/gtk/Gtk.metadata b/gtk/Gtk.metadata index 899eafbd7..2c3aa1655 100644 --- a/gtk/Gtk.metadata +++ b/gtk/Gtk.metadata @@ -93,6 +93,7 @@ 1 1 1 + async 1 1 1