]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
Support async method calls in static D-Bus clients
authorJürg Billeter <j@bitron.ch>
Sat, 22 Nov 2008 08:56:00 +0000 (08:56 +0000)
committerJürg Billeter <juergbi@src.gnome.org>
Sat, 22 Nov 2008 08:56:00 +0000 (08:56 +0000)
2008-11-22  Jürg Billeter  <j@bitron.ch>

* gobject/valaccodebasemodule.vala:
* gobject/valaccodemethodmodule.vala:
* gobject/valadbusclientmodule.vala:
* gobject/valagasyncmodule.vala:

Support async method calls in static D-Bus clients

svn path=/trunk/; revision=2058

ChangeLog
gobject/valaccodebasemodule.vala
gobject/valaccodemethodmodule.vala
gobject/valadbusclientmodule.vala
gobject/valagasyncmodule.vala

index 2893631733a5ef2368008acea672b4320aec02b6..ae74dadd883bb551dead3f81bcdae4a06993e7d7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2008-11-22  Jürg Billeter  <j@bitron.ch>
+
+       * gobject/valaccodebasemodule.vala:
+       * gobject/valaccodemethodmodule.vala:
+       * gobject/valadbusclientmodule.vala:
+       * gobject/valagasyncmodule.vala:
+
+       Support async method calls in static D-Bus clients
+
 2008-11-21  Jürg Billeter  <j@bitron.ch>
 
        * gobject/valagasyncmodule.vala:
index 752671bde4c23b31dc299233c00682e41b22039d..047bd35435ea1ae76c3db2bc2e04938a1e8e0cc2 100644 (file)
@@ -1786,8 +1786,8 @@ public class Vala.CCodeBaseModule : CCodeModule {
                if (invoc != null) {
                        var m = invoc.call.symbol_reference as Method;
                        var ma = invoc.call as MemberAccess;
-                       if (m != null && m.coroutine && (ma == null || ma.member_name != "begin"
-                                                        || ma.inner.symbol_reference != ma.symbol_reference)) {
+                       if (m != null && m.coroutine && current_method != null && current_method.coroutine &&
+                           (ma == null || ma.member_name != "begin" || ma.inner.symbol_reference != ma.symbol_reference)) {
                                var cfrag = new CCodeFragment ();
 
                                int state = next_coroutine_state++;
index 633f93efca783f1c0d052833aaa358f02ccd8560..16b728ba7095ef5c59328a55e5dae37d3fbaacdb 100644 (file)
@@ -294,10 +294,12 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
                                        cinit.append (cdecl);
                                }
 
-                               if (m.source_reference != null && m.source_reference.comment != null) {
-                                       source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
+                               if (!m.coroutine) {
+                                       if (m.source_reference != null && m.source_reference.comment != null) {
+                                               source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
+                                       }
+                                       source_type_member_definition.append (function);
                                }
-                               source_type_member_definition.append (function);
                        
                                if (m is CreationMethod) {
                                        if (in_gobject_creation_method) {
@@ -434,75 +436,10 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
                }
 
                if (m.is_abstract || m.is_virtual) {
-                       var vfunc = new CCodeFunction (m.get_cname (), creturn_type.get_cname ());
-                       vfunc.line = function.line;
-
                        cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
                        var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
 
-                       var vblock = new CCodeBlock ();
-
-                       foreach (Expression precondition in m.get_preconditions ()) {
-                               vblock.add_statement (create_precondition_statement (m, creturn_type, precondition));
-                       }
-
-                       CCodeFunctionCall vcast = null;
-                       if (m.parent_symbol is Interface) {
-                               var iface = (Interface) m.parent_symbol;
-
-                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_INTERFACE".printf (iface.get_upper_case_cname (null))));
-                       } else {
-                               var cl = (Class) m.parent_symbol;
-
-                               vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
-                       }
-                       vcast.add_argument (new CCodeIdentifier ("self"));
-               
-                       var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.vfunc_name));
-                       carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
-
-                       generate_cparameters (m, creturn_type, in_gtypeinstance_creation_method, cparam_map, vfunc, null, carg_map, vcall);
-
-                       CCodeStatement cstmt;
-                       if (creturn_type is VoidType) {
-                               cstmt = new CCodeExpressionStatement (vcall);
-                       } else if (m.get_postconditions ().size == 0) {
-                               /* pass method return value */
-                               cstmt = new CCodeReturnStatement (vcall);
-                       } else {
-                               /* store method return value for postconditions */
-                               var cdecl = new CCodeDeclaration (get_creturn_type (m, creturn_type.get_cname ()));
-                               cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("result", vcall));
-                               cstmt = cdecl;
-                       }
-                       cstmt.line = vfunc.line;
-                       vblock.add_statement (cstmt);
-
-                       if (m.get_postconditions ().size > 0) {
-                               foreach (Expression postcondition in m.get_postconditions ()) {
-                                       vblock.add_statement (create_postcondition_statement (postcondition));
-                               }
-
-                               if (!(creturn_type is VoidType)) {
-                                       var cret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result"));
-                                       cret_stmt.line = vfunc.line;
-                                       vblock.add_statement (cret_stmt);
-                               }
-                       }
-
-                       if (visible) {
-                               header_type_member_declaration.append (vfunc.copy ());
-                       } else {
-                               vfunc.modifiers |= CCodeModifiers.STATIC;
-                               source_type_member_declaration.append (vfunc.copy ());
-                       }
-                       
-                       vfunc.block = vblock;
-
-                       if (m.is_abstract && m.source_reference != null && m.source_reference.comment != null) {
-                               source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
-                       }
-                       source_type_member_definition.append (vfunc);
+                       generate_vfunc (m, creturn_type, cparam_map, carg_map);
                }
 
                if (m.entry_point) {
@@ -722,6 +659,77 @@ public class Vala.CCodeMethodModule : CCodeStructModule {
                }
        }
 
+       public void generate_vfunc (Method m, DataType return_type, Map<int,CCodeFormalParameter> cparam_map, Map<int,CCodeExpression> carg_map, string suffix = "", int direction = 3) {
+               bool visible = !m.is_internal_symbol ();
+
+               var vfunc = new CCodeFunction (m.get_cname () + suffix, return_type.get_cname ());
+               vfunc.line = function.line;
+
+               var vblock = new CCodeBlock ();
+
+               foreach (Expression precondition in m.get_preconditions ()) {
+                       vblock.add_statement (create_precondition_statement (m, return_type, precondition));
+               }
+
+               CCodeFunctionCall vcast = null;
+               if (m.parent_symbol is Interface) {
+                       var iface = (Interface) m.parent_symbol;
+
+                       vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_INTERFACE".printf (iface.get_upper_case_cname (null))));
+               } else {
+                       var cl = (Class) m.parent_symbol;
+
+                       vcast = new CCodeFunctionCall (new CCodeIdentifier ("%s_GET_CLASS".printf (cl.get_upper_case_cname (null))));
+               }
+               vcast.add_argument (new CCodeIdentifier ("self"));
+       
+               var vcall = new CCodeFunctionCall (new CCodeMemberAccess.pointer (vcast, m.vfunc_name + suffix));
+               carg_map.set (get_param_pos (m.cinstance_parameter_position), new CCodeIdentifier ("self"));
+
+               generate_cparameters (m, return_type, false, cparam_map, vfunc, null, carg_map, vcall, direction);
+
+               CCodeStatement cstmt;
+               if (return_type is VoidType) {
+                       cstmt = new CCodeExpressionStatement (vcall);
+               } else if (m.get_postconditions ().size == 0) {
+                       /* pass method return value */
+                       cstmt = new CCodeReturnStatement (vcall);
+               } else {
+                       /* store method return value for postconditions */
+                       var cdecl = new CCodeDeclaration (get_creturn_type (m, return_type.get_cname ()));
+                       cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("result", vcall));
+                       cstmt = cdecl;
+               }
+               cstmt.line = vfunc.line;
+               vblock.add_statement (cstmt);
+
+               if (m.get_postconditions ().size > 0) {
+                       foreach (Expression postcondition in m.get_postconditions ()) {
+                               vblock.add_statement (create_postcondition_statement (postcondition));
+                       }
+
+                       if (!(return_type is VoidType)) {
+                               var cret_stmt = new CCodeReturnStatement (new CCodeIdentifier ("result"));
+                               cret_stmt.line = vfunc.line;
+                               vblock.add_statement (cret_stmt);
+                       }
+               }
+
+               if (visible) {
+                       header_type_member_declaration.append (vfunc.copy ());
+               } else {
+                       vfunc.modifiers |= CCodeModifiers.STATIC;
+                       source_type_member_declaration.append (vfunc.copy ());
+               }
+               
+               vfunc.block = vblock;
+
+               if (m.is_abstract && m.source_reference != null && m.source_reference.comment != null) {
+                       source_type_member_definition.append (new CCodeComment (m.source_reference.comment));
+               }
+               source_type_member_definition.append (vfunc);
+       }
+
        private CCodeStatement create_method_type_check_statement (Method m, DataType return_type, TypeSymbol t, bool non_null, string var_name) {
                return create_type_check_statement (m, return_type, t, non_null, var_name);
        }
index eb23e86236d79dbdee5870d35f278ec215a8cef5..3e8b2fc2d023fb538e1cf7e605a811ff13bb087f 100644 (file)
@@ -943,6 +943,12 @@ public class Vala.DBusClientModule : DBusModule {
                foreach (Method m in iface.get_methods ()) {
                        var vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.vfunc_name);
                        iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_dbus_proxy_method (iface, m)))));
+                       if (m.coroutine) {
+                               vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.vfunc_name + "_async");
+                               iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_async_dbus_proxy_method (iface, m)))));
+                               vfunc_entry = new CCodeMemberAccess.pointer (new CCodeIdentifier ("iface"), m.vfunc_name + "_finish");
+                               iface_block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (vfunc_entry, new CCodeIdentifier (generate_finish_dbus_proxy_method (iface, m)))));
+                       }
                }
 
                proxy_iface_init.modifiers = CCodeModifiers.STATIC;
@@ -951,42 +957,9 @@ public class Vala.DBusClientModule : DBusModule {
                source_type_member_definition.append (proxy_iface_init);
        }
 
-       string generate_dbus_proxy_method (Interface iface, Method m) {
-               string proxy_name = "%sdbus_proxy_%s".printf (iface.get_lower_case_cprefix (), m.name);
-
-               string dbus_iface_name = iface.get_attribute ("DBus").get_string ("name");
-
+       void generate_marshalling (Method m, string dbus_iface_name, CCodeFragment prefragment, CCodeFragment postfragment) {
                CCodeDeclaration cdecl;
 
-               var function = new CCodeFunction (proxy_name, m.return_type.get_cname ());
-               function.modifiers = CCodeModifiers.STATIC;
-
-               var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
-
-               var instance_param = new CCodeFormalParameter ("self", iface.get_cname () + "*");
-               cparam_map.set (get_param_pos (m.cinstance_parameter_position), instance_param);
-
-               generate_cparameters (m, m.return_type, false, cparam_map, function);
-
-               var block = new CCodeBlock ();
-               var prefragment = new CCodeFragment ();
-               var postfragment = new CCodeFragment ();
-
-               cdecl = new CCodeDeclaration ("DBusGConnection");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection"));
-               block.add_statement (cdecl);
-
-               cdecl = new CCodeDeclaration ("DBusMessage");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
-               cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
-               block.add_statement (cdecl);
-
-               cdecl = new CCodeDeclaration ("DBusMessageIter");
-               cdecl.add_declarator (new CCodeVariableDeclarator ("_iter"));
-               block.add_statement (cdecl);
-
-               block.add_statement (prefragment);
-
                var destination = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_bus_name"));
                destination.add_argument (new CCodeCastExpression (new CCodeIdentifier ("self"), "DBusGProxy*"));
                var path = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_proxy_get_path"));
@@ -1019,7 +992,7 @@ public class Vala.DBusClientModule : DBusModule {
                        } else {
                                cdecl = new CCodeDeclaration (param.parameter_type.get_cname ());
                                cdecl.add_declarator (new CCodeVariableDeclarator ("_" + param.name));
-                               block.add_statement (cdecl);
+                               postfragment.append (cdecl);
 
                                var target = new CCodeIdentifier ("_" + param.name);
                                var expr = read_expression (postfragment, param.parameter_type, new CCodeIdentifier ("_iter"), target);
@@ -1033,7 +1006,7 @@ public class Vala.DBusClientModule : DBusModule {
                                if (param.parameter_type is ArrayType) {
                                        cdecl = new CCodeDeclaration ("int");
                                        cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("_%s_length1".printf (param.name), new CCodeConstant ("0")));
-                                       block.add_statement (cdecl);
+                                       postfragment.append (cdecl);
 
                                        // TODO check that parameter is not NULL (out parameters are optional)
                                        postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("%s_length1".printf (param.name))), new CCodeIdentifier ("_%s_length1".printf (param.name)))));
@@ -1044,7 +1017,7 @@ public class Vala.DBusClientModule : DBusModule {
                if (!(m.return_type is VoidType)) {
                        cdecl = new CCodeDeclaration (m.return_type.get_cname ());
                        cdecl.add_declarator (new CCodeVariableDeclarator ("_result"));
-                       block.add_statement (cdecl);
+                       postfragment.append (cdecl);
 
                        var target = new CCodeIdentifier ("_result");
                        var expr = read_expression (postfragment, m.return_type, new CCodeIdentifier ("_iter"), target);
@@ -1053,12 +1026,48 @@ public class Vala.DBusClientModule : DBusModule {
                        if (m.return_type is ArrayType) {
                                cdecl = new CCodeDeclaration ("int");
                                cdecl.add_declarator (new CCodeVariableDeclarator.with_initializer ("_result_length1", new CCodeConstant ("0")));
-                               block.add_statement (cdecl);
+                               postfragment.append (cdecl);
 
                                // TODO check that parameter is not NULL (out parameters are optional)
                                postfragment.append (new CCodeExpressionStatement (new CCodeAssignment (new CCodeUnaryExpression (CCodeUnaryOperator.POINTER_INDIRECTION, new CCodeIdentifier ("result_length1")), new CCodeIdentifier ("_result_length1"))));
                        }
                }
+       }
+
+       string generate_dbus_proxy_method (Interface iface, Method m) {
+               string proxy_name = "%sdbus_proxy_%s".printf (iface.get_lower_case_cprefix (), m.name);
+
+               string dbus_iface_name = iface.get_attribute ("DBus").get_string ("name");
+
+               CCodeDeclaration cdecl;
+
+               var function = new CCodeFunction (proxy_name, m.return_type.get_cname ());
+               function.modifiers = CCodeModifiers.STATIC;
+
+               var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+               generate_cparameters (m, m.return_type, false, cparam_map, function);
+
+               var block = new CCodeBlock ();
+               var prefragment = new CCodeFragment ();
+               var postfragment = new CCodeFragment ();
+
+               cdecl = new CCodeDeclaration ("DBusGConnection");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessage");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessageIter");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("_iter"));
+               block.add_statement (cdecl);
+
+               block.add_statement (prefragment);
+
+               generate_marshalling (m, dbus_iface_name, prefragment, postfragment);
 
                var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
                gconnection.add_argument (new CCodeIdentifier ("self"));
@@ -1101,4 +1110,209 @@ public class Vala.DBusClientModule : DBusModule {
 
                return proxy_name;
        }
+
+       string generate_async_dbus_proxy_method (Interface iface, Method m) {
+               string proxy_name = "%sdbus_proxy_%s_async".printf (iface.get_lower_case_cprefix (), m.name);
+
+               string dbus_iface_name = iface.get_attribute ("DBus").get_string ("name");
+
+               CCodeDeclaration cdecl;
+
+
+               // generate data struct
+
+               string dataname = "%sDBusProxy%sData".printf (iface.get_cname (), Symbol.lower_case_to_camel_case (m.name));
+               var datastruct = new CCodeStruct ("_" + dataname);
+
+               datastruct.add_field ("GAsyncReadyCallback", "callback");
+               datastruct.add_field ("gpointer", "user_data");
+               datastruct.add_field ("DBusPendingCall*", "pending");
+
+               source_type_definition.append (datastruct);
+               source_type_declaration.append (new CCodeTypeDefinition ("struct _" + dataname, new CCodeVariableDeclarator (dataname)));
+
+
+               // generate async function
+
+               var function = new CCodeFunction (proxy_name, "void");
+               function.modifiers = CCodeModifiers.STATIC;
+
+               var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+               cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback"));
+               cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer"));
+
+               generate_cparameters (m, m.return_type, false, cparam_map, function, null, null, null, 1);
+
+               var block = new CCodeBlock ();
+               var prefragment = new CCodeFragment ();
+               var postfragment = new CCodeFragment ();
+
+               cdecl = new CCodeDeclaration ("DBusGConnection");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_connection"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessage");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_message"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusPendingCall");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_pending"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessageIter");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("_iter"));
+               block.add_statement (cdecl);
+
+               block.add_statement (prefragment);
+
+               generate_marshalling (m, dbus_iface_name, prefragment, postfragment);
+
+               var gconnection = new CCodeFunctionCall (new CCodeIdentifier ("g_object_get"));
+               gconnection.add_argument (new CCodeIdentifier ("self"));
+               gconnection.add_argument (new CCodeConstant ("\"connection\""));
+               gconnection.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_connection")));
+               gconnection.add_argument (new CCodeConstant ("NULL"));
+               block.add_statement (new CCodeExpressionStatement (gconnection));
+
+               var connection = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_get_connection"));
+               connection.add_argument (new CCodeIdentifier ("_connection"));
+
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_connection_send_with_reply"));
+               ccall.add_argument (connection);
+               ccall.add_argument (new CCodeIdentifier ("_message"));
+               ccall.add_argument (new CCodeUnaryExpression (CCodeUnaryOperator.ADDRESS_OF, new CCodeIdentifier ("_pending")));
+               ccall.add_argument (new CCodeConstant ("-1"));
+               block.add_statement (new CCodeExpressionStatement (ccall));
+
+               var conn_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_g_connection_unref"));
+               conn_unref.add_argument (new CCodeIdentifier ("_connection"));
+               block.add_statement (new CCodeExpressionStatement (conn_unref));
+
+               var message_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref"));
+               message_unref.add_argument (new CCodeIdentifier ("_message"));
+               block.add_statement (new CCodeExpressionStatement (message_unref));
+
+               var dataalloc = new CCodeFunctionCall (new CCodeIdentifier ("g_slice_new0"));
+               dataalloc.add_argument (new CCodeIdentifier (dataname));
+
+               var datadecl = new CCodeDeclaration (dataname + "*");
+               datadecl.add_declarator (new CCodeVariableDeclarator ("data"));
+               block.add_statement (datadecl);
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), dataalloc)));
+
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"), new CCodeIdentifier ("callback"))));
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"), new CCodeIdentifier ("user_data"))));
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "pending"), new CCodeIdentifier ("_pending"))));
+
+               var pending = new CCodeFunctionCall (new CCodeIdentifier ("dbus_pending_call_set_notify"));
+               pending.add_argument (new CCodeIdentifier ("_pending"));
+               pending.add_argument (new CCodeIdentifier ("%sdbus_proxy_%s_ready".printf (iface.get_lower_case_cprefix (), m.name)));
+               pending.add_argument (new CCodeIdentifier ("data"));
+               pending.add_argument (new CCodeConstant ("NULL"));
+               block.add_statement (new CCodeExpressionStatement (pending));
+
+               source_type_member_declaration.append (function.copy ());
+               function.block = block;
+               source_type_member_definition.append (function);
+
+
+               // generate ready function
+
+               function = new CCodeFunction ("%sdbus_proxy_%s_ready".printf (iface.get_lower_case_cprefix (), m.name), "void");
+               function.modifiers = CCodeModifiers.STATIC;
+
+               function.add_parameter (new CCodeFormalParameter ("pending", "DBusPendingCall*"));
+               function.add_parameter (new CCodeFormalParameter ("user_data", "void*"));
+
+               block = new CCodeBlock ();
+
+               datadecl = new CCodeDeclaration (dataname + "*");
+               datadecl.add_declarator (new CCodeVariableDeclarator ("data"));
+               block.add_statement (datadecl);
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), new CCodeIdentifier ("user_data"))));
+
+               // complete async call by invoking callback
+               var object_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_object_newv"));
+               object_creation.add_argument (new CCodeConstant ("G_TYPE_OBJECT"));
+               object_creation.add_argument (new CCodeConstant ("0"));
+               object_creation.add_argument (new CCodeConstant ("NULL"));
+
+               var async_result_creation = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_new"));
+               async_result_creation.add_argument (object_creation);
+               async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "callback"));
+               async_result_creation.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "user_data"));
+               async_result_creation.add_argument (new CCodeIdentifier ("data"));
+
+               var completecall = new CCodeFunctionCall (new CCodeIdentifier ("g_simple_async_result_complete"));
+               completecall.add_argument (async_result_creation);
+               block.add_statement (new CCodeExpressionStatement (completecall));
+
+               source_type_member_declaration.append (function.copy ());
+               function.block = block;
+               source_type_member_definition.append (function);
+
+
+               return proxy_name;
+       }
+
+       string generate_finish_dbus_proxy_method (Interface iface, Method m) {
+               string proxy_name = "%sdbus_proxy_%s_finish".printf (iface.get_lower_case_cprefix (), m.name);
+
+               string dbus_iface_name = iface.get_attribute ("DBus").get_string ("name");
+
+               CCodeDeclaration cdecl;
+
+               var function = new CCodeFunction (proxy_name, m.return_type.get_cname ());
+               function.modifiers = CCodeModifiers.STATIC;
+
+               var cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+
+               cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*"));
+
+               generate_cparameters (m, m.return_type, false, cparam_map, function, null, null, null, 2);
+
+               var block = new CCodeBlock ();
+               var prefragment = new CCodeFragment ();
+               var postfragment = new CCodeFragment ();
+
+               string dataname = "%sDBusProxy%sData".printf (iface.get_cname (), Symbol.lower_case_to_camel_case (m.name));
+               cdecl = new CCodeDeclaration (dataname + "*");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("data"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessage");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("*_reply"));
+               block.add_statement (cdecl);
+
+               cdecl = new CCodeDeclaration ("DBusMessageIter");
+               cdecl.add_declarator (new CCodeVariableDeclarator ("_iter"));
+               block.add_statement (cdecl);
+
+               var get_user_data = new CCodeFunctionCall (new CCodeIdentifier ("g_async_result_get_user_data"));
+               get_user_data.add_argument (new CCodeIdentifier ("res"));
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("data"), get_user_data)));
+
+               var ccall = new CCodeFunctionCall (new CCodeIdentifier ("dbus_pending_call_steal_reply"));
+               ccall.add_argument (new CCodeMemberAccess.pointer (new CCodeIdentifier ("data"), "pending"));
+               block.add_statement (new CCodeExpressionStatement (new CCodeAssignment (new CCodeIdentifier ("_reply"), ccall)));
+
+               generate_marshalling (m, dbus_iface_name, prefragment, postfragment);
+
+               block.add_statement (postfragment);
+
+               var reply_unref = new CCodeFunctionCall (new CCodeIdentifier ("dbus_message_unref"));
+               reply_unref.add_argument (new CCodeIdentifier ("_reply"));
+               block.add_statement (new CCodeExpressionStatement (reply_unref));
+
+               if (!(m.return_type is VoidType)) {
+                       block.add_statement (new CCodeReturnStatement (new CCodeIdentifier ("_result")));
+               }
+
+               source_type_member_declaration.append (function.copy ());
+               function.block = block;
+               source_type_member_definition.append (function);
+
+               return proxy_name;
+       }
 }
index 8f1169df3aaf625320880a991bbb1c8f44fcab04..dc97228606668128434cdbd4eb2e3f323b399206 100644 (file)
@@ -175,6 +175,27 @@ public class Vala.GAsyncModule : GSignalModule {
 
                        source_type_member_definition.append (readyfunc);
                }
+
+               if (m.is_abstract || m.is_virtual) {
+                       cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+                       var carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
+                       cparam_map.set (get_param_pos (-1), new CCodeFormalParameter ("callback", "GAsyncReadyCallback"));
+                       cparam_map.set (get_param_pos (-0.9), new CCodeFormalParameter ("user_data", "gpointer"));
+                       carg_map.set (get_param_pos (-1), new CCodeIdentifier ("callback"));
+                       carg_map.set (get_param_pos (-0.9), new CCodeIdentifier ("user_data"));
+
+                       generate_vfunc (m, new VoidType (), cparam_map, carg_map, "_async", 1);
+
+
+                       cparam_map = new HashMap<int,CCodeFormalParameter> (direct_hash, direct_equal);
+                       carg_map = new HashMap<int,CCodeExpression> (direct_hash, direct_equal);
+
+                       cparam_map.set (get_param_pos (0.1), new CCodeFormalParameter ("res", "GAsyncResult*"));
+                       carg_map.set (get_param_pos (0.1), new CCodeIdentifier ("res"));
+
+                       generate_vfunc (m, m.return_type, cparam_map, carg_map, "_finish", 2);
+               }
        }
 
        public override void visit_yield_statement (YieldStatement stmt) {