[vala] D-Bus: Support register_object with generic type in GDBus servers



commit 6cd39b77b686b20274a6c9197d451dc8804418fd
Author: Jürg Billeter <j bitron ch>
Date:   Mon Oct 25 20:45:07 2010 +0200

    D-Bus: Support register_object with generic type in GDBus servers

 codegen/valaccodebasemodule.vala   |    2 +-
 codegen/valagdbusservermodule.vala |   98 ++++++++++++++++++++++++++++++++++--
 2 files changed, 94 insertions(+), 6 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index e921ac3..6fd4b7e 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -2260,7 +2260,7 @@ public class Vala.CCodeBaseModule : CodeGenerator {
 		}
 	}
 
-	private CCodeExpression get_type_id_expression (DataType type, bool is_chainup = false) {
+	public CCodeExpression get_type_id_expression (DataType type, bool is_chainup = false) {
 		if (type is GenericType) {
 			string var_name = "%s_type".printf (type.type_parameter.name.down ());
 			if (is_in_generic_type (type) && !is_chainup && !in_creation_method) {
diff --git a/codegen/valagdbusservermodule.vala b/codegen/valagdbusservermodule.vala
index 51a6869..11631a9 100644
--- a/codegen/valagdbusservermodule.vala
+++ b/codegen/valagdbusservermodule.vala
@@ -1020,6 +1020,67 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		return new CCodeIdentifier ("_" + sym.get_lower_case_cprefix () + "dbus_interface_vtable");
 	}
 
+	string generate_register_object_function () {
+		string register_object_func = "_vala_g_dbus_connection_register_object";
+
+		if (!add_wrapper (register_object_func)) {
+			return register_object_func;
+		}
+
+		var function = new CCodeFunction (register_object_func, "guint");
+		function.modifiers = CCodeModifiers.STATIC;
+
+		function.add_parameter (new CCodeFormalParameter ("type", "GType"));
+		function.add_parameter (new CCodeFormalParameter ("object", "void*"));
+		function.add_parameter (new CCodeFormalParameter ("connection", "GDBusConnection*"));
+		function.add_parameter (new CCodeFormalParameter ("path", "const gchar*"));
+		function.add_parameter (new CCodeFormalParameter ("error", "GError**"));
+
+		push_function (function);
+
+		var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
+		quark.add_argument (new CCodeConstant ("\"vala-dbus-register-object\""));
+
+		var get_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_get_qdata"));
+		get_qdata.add_argument (new CCodeIdentifier ("type"));
+		get_qdata.add_argument (quark);
+
+		ccode.add_declaration ("void", new CCodeVariableDeclarator ("*func"));
+		ccode.add_expression (new CCodeAssignment (new CCodeIdentifier ("func"), get_qdata));
+
+		ccode.open_if (new CCodeUnaryExpression (CCodeUnaryOperator.LOGICAL_NEGATION, new CCodeIdentifier ("func")));
+		// no D-Bus interface
+		// return error
+
+		var set_error = new CCodeFunctionCall (new CCodeIdentifier ("g_set_error_literal"));
+		set_error.add_argument (new CCodeIdentifier ("error"));
+		set_error.add_argument (new CCodeIdentifier ("G_IO_ERROR"));
+		set_error.add_argument (new CCodeIdentifier ("G_IO_ERROR_FAILED"));
+		set_error.add_argument (new CCodeConstant ("\"The specified type does not support D-Bus registration\""));
+		ccode.add_expression (set_error);
+
+		ccode.add_return (new CCodeConstant ("0"));
+
+		ccode.close ();
+
+		var register_object = new CCodeCastExpression (new CCodeIdentifier ("func"), "guint (*) (void *, GDBusConnection *, const gchar *, GError **)");
+
+		var ccall = new CCodeFunctionCall (register_object);
+		ccall.add_argument (new CCodeIdentifier ("object"));
+		ccall.add_argument (new CCodeIdentifier ("connection"));
+		ccall.add_argument (new CCodeIdentifier ("path"));
+		ccall.add_argument (new CCodeIdentifier ("error"));
+
+		ccode.add_return (ccall);
+
+		pop_function ();
+
+		cfile.add_function_declaration (function);
+		cfile.add_function (function);
+
+		return register_object_func;
+	}
+
 	public override void visit_method_call (MethodCall expr) {
 		var mtype = expr.call.value_type as MethodType;
 		if (mtype == null || mtype.method_symbol.get_cname () != "g_dbus_connection_register_object") {
@@ -1028,11 +1089,22 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		}
 
 		var ma = (MemberAccess) expr.call;
-		var type_arg = (ObjectType) ma.get_type_arguments ().get (0);
+		var type_arg = ma.get_type_arguments ().get (0);
 
-		if (get_dbus_name (type_arg.type_symbol) == null) {
-			Report.error (expr.source_reference, "DBusConnection.register_object requires type argument with [DBus (name = ...)] attribute");
-			return;
+		CCodeFunctionCall cregister;
+
+		var object_type = type_arg as ObjectType;
+		if (object_type != null) {
+			if (get_dbus_name (object_type.type_symbol) == null) {
+				Report.error (expr.source_reference, "DBusConnection.register_object requires type argument with [DBus (name = ...)] attribute");
+				return;
+			}
+
+			cregister = new CCodeFunctionCall (new CCodeIdentifier ("%sregister_object".printf (object_type.type_symbol.get_lower_case_cprefix ())));
+		} else {
+			// use runtime type information for generic methods
+			cregister = new CCodeFunctionCall (new CCodeIdentifier (generate_register_object_function ()));
+			cregister.add_argument (get_type_id_expression (type_arg));
 		}
 
 		var args = expr.get_argument_list ();
@@ -1042,7 +1114,6 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 		// method can fail
 		current_method_inner_error = true;
 
-		var cregister = new CCodeFunctionCall (new CCodeIdentifier ("%sregister_object".printf (type_arg.type_symbol.get_lower_case_cprefix ())));
 		cregister.add_argument (get_cvalue (obj_arg));
 		cregister.add_argument (get_cvalue (ma.inner));
 		cregister.add_argument (get_cvalue (path_arg));
@@ -1202,4 +1273,21 @@ public class Vala.GDBusServerModule : GDBusClientModule {
 
 		cfile.add_function (cfunc);
 	}
+
+	public override void register_dbus_info (ObjectTypeSymbol sym) {
+		string dbus_iface_name = get_dbus_name (sym);
+		if (dbus_iface_name == null) {
+			return;
+		}
+
+		var quark = new CCodeFunctionCall (new CCodeIdentifier ("g_quark_from_static_string"));
+		quark.add_argument (new CCodeConstant ("\"vala-dbus-register-object\""));
+
+		var set_qdata = new CCodeFunctionCall (new CCodeIdentifier ("g_type_set_qdata"));
+		set_qdata.add_argument (new CCodeIdentifier (sym.get_upper_case_cname ("TYPE_")));
+		set_qdata.add_argument (quark);
+		set_qdata.add_argument (new CCodeCastExpression (new CCodeIdentifier (sym.get_lower_case_cprefix () + "register_object"), "void*"));
+
+		ccode.add_expression (set_qdata);
+	}
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]