From: Jürg Billeter Date: Sat, 22 Nov 2008 08:56:00 +0000 (+0000) Subject: Support async method calls in static D-Bus clients X-Git-Tag: VALA_0_5_2~53 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1962f757db548006f0f94dadb754b37e22b43ce2;p=thirdparty%2Fvala.git Support async method calls in static D-Bus clients 2008-11-22 Jürg Billeter * 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 --- diff --git a/ChangeLog b/ChangeLog index 289363173..ae74dadd8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-11-22 Jürg Billeter + + * 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 * gobject/valagasyncmodule.vala: diff --git a/gobject/valaccodebasemodule.vala b/gobject/valaccodebasemodule.vala index 752671bde..047bd3543 100644 --- a/gobject/valaccodebasemodule.vala +++ b/gobject/valaccodebasemodule.vala @@ -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++; diff --git a/gobject/valaccodemethodmodule.vala b/gobject/valaccodemethodmodule.vala index 633f93efc..16b728ba7 100644 --- a/gobject/valaccodemethodmodule.vala +++ b/gobject/valaccodemethodmodule.vala @@ -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 (direct_hash, direct_equal); var carg_map = new HashMap (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 cparam_map, Map 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); } diff --git a/gobject/valadbusclientmodule.vala b/gobject/valadbusclientmodule.vala index eb23e8623..3e8b2fc2d 100644 --- a/gobject/valadbusclientmodule.vala +++ b/gobject/valadbusclientmodule.vala @@ -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 (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 (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 (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 (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; + } } diff --git a/gobject/valagasyncmodule.vala b/gobject/valagasyncmodule.vala index 8f1169df3..dc9722860 100644 --- a/gobject/valagasyncmodule.vala +++ b/gobject/valagasyncmodule.vala @@ -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 (direct_hash, direct_equal); + var carg_map = new HashMap (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 (direct_hash, direct_equal); + carg_map = new HashMap (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) {