ps. I think the wrapper_type things can be replaced with the already
existing "pass_as" attribute.

On Sun, 2008-02-10 at 15:27 +0100, Philip Van Hoof wrote:
> Hi there,
> 
> I'm trying to make GtkSharp's GAPI generate the typical asynchronous
> GObject style C API to something that looks a bit like the Asynchronous
> Pattern often used in .NET.
> 
> My plan is not to achieve an exact version of the Asynchronous pattern,
> but nonetheless something workable.
> 
> Some pointers:
> http://msdn2.microsoft.com/en-us/library/wewwczdw.aspx
> http://msdn2.microsoft.com/en-us/library/aa719595(VS.71).aspx
> 
> Versus, for example, this one:
> http://tinymail.org/API/libtinymail-1.0/libtinymail-tny-folder.html#tny-folder-get-msg-async
> http://tinymail.org/API/libtinymail-1.0/libtinymail-tny-shared.html#TnyGetMsgCallback
> 
> It's actually awesome about GtkSharp's GAPI, but not surprisingly did
> GAPI do a splendid job already. There's however one big problem:
> 
> The GError based error being passed to the callback (which in C is a
> function pointer typedeffed as TnyGetMsgCallback) is not being converted
> to an Exception type.
> 
> My goal is to wrap the "IntPtr err" (which is the GError pointer in C)
> with a factory's Create method that will create me the right managed
> exception:
> 
> public class Tny.ExceptionFactory
> {
>       static Tny.TException Create (IntPtr gerror) {
>               // Pseudo, to get the type I'll indeed need to make
>               // a small piece of glue code in C ...
>               if (gerror->type == TNY_ERROR_THIS)
>                       return new Tny.ThisException (gerror);
>               if (gerror->type == TNY_ERROR_THAT)
>                       return new Tny.ThatException (gerror);
>               ...
>       }
> }
> 
> That way can my application developer use the error being reported in
> the callback using his normal exception handling methods.
> 
> For example:
> 
> - private void GetMsgCallBack (Tny.Folder folder, bool cancel, Tny.Msg msg, 
> IntPtr err)
> + private void GetMsgCallBack (Tny.Folder folder, bool cancel, Tny.Msg msg, 
> Tny.TException err)
> {
> -     if (err != IntPtr.Zero) {
> -             Exception ex = new Tny.TException (err);
> -             Console.WriteLine (ex.Message);
> +     if (err != null)
> +             throw err; // Or do whatever with Exceptions
>       } else {
>               if (msg != null && !cancel)
>                       this.msg_view.Msg = msg;
>       }
> }
> 
> Note that throwing it is not necessarily what the application developer
> will want to do with the exception. In that callback he'll typically
> want to show an error dialog to the user with the err.Message displayed.
> 
> To achieve this, after doing some analysis on Gapi's generator, this is
> my conclusion:
> 
> Parameter needs a new property Wrapper that looks a lot like its Scope 
> parameter (gets it from the XML file)
> Signature::ToString() needs to recognise parameters that are to be wrapped 
> (change the type)
> CallbackGen::Generate(GenerationInfo) needs to be verified that 
> sig.ToString() does the right thing
> CallbackGen::GenWrapper(GenerationInfo) at line 227 needs to wrap the 
> parameter with p.Wrapper
> 
> 
> ## This
> 
> <callback name="FolderCallback" cname="TnyFolderCallback">
>   <return-type type="void" />
>   <parameters>
>     <parameter type="TnyFolder*" name="self" />
>     <parameter type="gboolean" name="cancelled" />
>     <parameter type="GError*" name="err" />
>     <parameter type="gpointer" name="user_data" />
>   </parameters>
> </callback>
> 
> 
> ## Would become
> 
> <callback name="FolderCallback" cname="TnyFolderCallback">
>   <return-type type="void" />
>   <parameters>
>     <parameter type="TnyFolder*" name="self" />
>     <parameter type="gboolean" name="cancelled" />
>     <parameter type="GError*" name="err" wrapper_type="Tny.TException" 
> wrapper="Tny.ExceptionFactory.Create ({0})" />
>     <parameter type="gpointer" name="user_data" />
>   </parameters>
> </callback>
> 
> 
> ## This
> 
> namespace Tny {
> 
>       using System;
> 
>       public delegate void FolderCallback(Tny.Folder self, bool cancelled, 
> IntPtr err);
> 
> }
> 
> 
> ## Would become (err's type comes from the XML above)
> 
> namespace Tny {
> 
>       using System;
> 
>       public delegate void FolderCallback(Tny.Folder self, bool cancelled, 
> Tny.TException err);
> 
> }
> 
> ## This
> 
> internal class FolderCallbackWrapper {
>       public void NativeCallback (IntPtr self, bool cancelled, IntPtr err, 
> IntPtr user_data)
>       {
>               try {
>                       Tny.Folder _arg0 = Tny.FolderAdapter.GetObject (self, 
> false);
>                       bool _arg1 = cancelled;
>                       IntPtr _arg2 = err;
>                       managed ( _arg0,  _arg1,  _arg2);
>                       if (release_on_call)
>                               gch.Free ();
>               } catch (Exception e) {
>                       GLib.ExceptionManager.RaiseUnhandledException (e, 
> false);
>               }
>       }
>       ...
> }
> 
> 
> ## Would become (arg2 wrap comes from the XML above)
> 
> internal class FolderCallbackWrapper {
>       public void NativeCallback (IntPtr self, bool cancelled, IntPtr err, 
> IntPtr user_data)
>       {
>               try {
>                       Tny.Folder _arg0 = Tny.FolderAdapter.GetObject (self, 
> false);
>                       bool _arg1 = cancelled;
>                       IntPtr _arg2 = err;
>                       managed ( _arg0,  _arg1,  Tny.ExceptionFactory.Create 
> (_arg2));
>                       if (release_on_call)
>                               gch.Free ();
>               } catch (Exception e) {
>                       GLib.ExceptionManager.RaiseUnhandledException (e, 
> false);
>               }
>       }
>       ...
> }
> 
> 
-- 
Philip Van Hoof, freelance software developer
home: me at pvanhoof dot be 
gnome: pvanhoof at gnome dot org 
http://pvanhoof.be/blog
http://codeminded.be




_______________________________________________
Gtk-sharp-list maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/gtk-sharp-list

Reply via email to