diff --git a/generator/ManagedCallString.cs b/generator/ManagedCallString.cs index de0ad1b21..3e54fe349 100644 --- a/generator/ManagedCallString.cs +++ b/generator/ManagedCallString.cs @@ -28,6 +28,7 @@ namespace GtkSharp.Generation { public class ManagedCallString { IDictionary parms = new Dictionary (); + IList dispose_params = new List (); string error_param = null; string user_data_param = null; string destroy_param = null; @@ -57,6 +58,10 @@ namespace GtkSharp.Generation { special = true; this.parms.Add (p, special); + + if (p.IsOwnable) { + dispose_params.Add (p); + } } } @@ -70,10 +75,18 @@ namespace GtkSharp.Generation { } } + public bool HasDisposeParam { + get { return dispose_params.Count > 0; } + } + public string Unconditional (string indent) { string ret = ""; if (error_param != null) ret = indent + error_param + " = IntPtr.Zero;\n"; + + foreach (Parameter p in dispose_params) { + ret += indent + p.CSType + " my" + p.Name + " = null;\n"; + } return ret; } @@ -103,6 +116,10 @@ namespace GtkSharp.Generation { } } + foreach (Parameter p in dispose_params) { + ret += indent + "my" + p.Name + " = " + p.FromNative (p.Name) + ";\n"; + } + return ret; } @@ -119,7 +136,12 @@ namespace GtkSharp.Generation { if (p.Generatable is CallbackGen) { result [i] += p.Name + "_invoker.Handler"; } else { - result [i] += (parms [p]) ? "my" + p.Name : p.FromNative (p.Name); + if (parms [p] || dispose_params.Contains(p)) { + // Parameter was declared and marshalled earlier + result [i] += "my" + p.Name; + } else { + result [i] += p.FromNative (p.Name); + } } i++; } @@ -150,6 +172,22 @@ namespace GtkSharp.Generation { return ret; } + + public string DisposeParams (string indent) + { + string ret = ""; + + foreach (Parameter p in dispose_params) { + string name = "my" + p.Name; + string disp_name = "disposable_" + p.Name; + + ret += indent + "var " + disp_name + " = " + name + " as IDisposable;\n"; + ret += indent + "if (" + disp_name + " != null)\n"; + ret += indent + "\t" + disp_name + ".Dispose ();\n"; + } + + return ret; + } } } diff --git a/generator/Parameter.cs b/generator/Parameter.cs index 981cadee7..02c0ad5c4 100644 --- a/generator/Parameter.cs +++ b/generator/Parameter.cs @@ -186,6 +186,12 @@ namespace GtkSharp.Generation { } } + public bool IsOwnable { + get { + return this.Generatable is OwnableGen; + } + } + public bool Owned { get { return elem.GetAttribute ("owned") == "true"; diff --git a/generator/VirtualMethod.cs b/generator/VirtualMethod.cs index 878f81a69..901ad02bd 100644 --- a/generator/VirtualMethod.cs +++ b/generator/VirtualMethod.cs @@ -98,14 +98,17 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\t\t{0} __obj = GLib.Object.GetObject (inst, false) as {0};", type); } - sw.Write (call.Setup ("\t\t\t\t")); - sw.Write ("\t\t\t\t"); + string indent = "\t\t\t\t"; if (!retval.IsVoid) - sw.Write (retval.CSType + " __result = "); + sw.WriteLine (indent + retval.CSType + " __result;"); + sw.Write (call.Setup (indent)); + sw.Write (indent); + if (!retval.IsVoid) + sw.Write ("__result = "); if (!this.IsStatic) sw.Write ("__obj."); sw.WriteLine (this.CallString + ";"); - sw.Write (call.Finish ("\t\t\t\t")); + sw.Write (call.Finish (indent)); if (!retval.IsVoid) sw.WriteLine ("\t\t\t\treturn " + retval.ToNative ("__result") + ";"); @@ -116,6 +119,11 @@ namespace GtkSharp.Generation { sw.WriteLine ("\t\t\t\t// NOTREACHED: above call does not return."); sw.WriteLine ("\t\t\t\tthrow e;"); } + + if (call.HasDisposeParam) { + sw.WriteLine ("\t\t\t} finally {"); + sw.Write (call.DisposeParams (indent)); + } sw.WriteLine ("\t\t\t}"); sw.WriteLine ("\t\t}"); sw.WriteLine ();