summaryrefslogtreecommitdiff
path: root/gobject/valadbusclientmodule.vala
diff options
context:
space:
mode:
authorJürg Billeter <j@bitron.ch>2008-11-22 08:56:00 +0000
committerJürg Billeter <juergbi@src.gnome.org>2008-11-22 08:56:00 +0000
commit1962f757db548006f0f94dadb754b37e22b43ce2 (patch)
treee6857f144d2efac0c216b34b3d41e8ef3ea33b09 /gobject/valadbusclientmodule.vala
parent8fb40fa3dd0a236cd439f94749cf910d4f4533ad (diff)
downloadvala-1962f757db548006f0f94dadb754b37e22b43ce2.tar.gz
Support async method calls in static D-Bus clients
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
Diffstat (limited to 'gobject/valadbusclientmodule.vala')
-rw-r--r--gobject/valadbusclientmodule.vala290
1 files changed, 252 insertions, 38 deletions
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<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;
+ }
}