From e151150cad6625dbed4338e22d102ed25798fc8f Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 27 Apr 2015 11:06:48 +0200 Subject: [PATCH] Move subscription signal to context Emit the subscription signal event directly from the context, This is easier and it avoids having two subscribe objects. Remove client proxy property from the context, we don't need it anymore. Only expose objects when the client manager has a name-owner. --- src/client/pv-context.c | 140 +++++++++++++++++-------------------- src/client/pv-context.h | 3 - src/client/pv-subscribe.c | 64 +++++++++++++---- src/tests/test-subscribe.c | 8 +-- 4 files changed, 115 insertions(+), 100 deletions(-) diff --git a/src/client/pv-context.c b/src/client/pv-context.c index 90e319ef3..58e0100c2 100644 --- a/src/client/pv-context.c +++ b/src/client/pv-context.c @@ -40,7 +40,7 @@ struct _PvContextPrivate PvClient1 *client; - PvSubscribe *internal_subscribe; + PvSubscriptionFlags subscription_mask; PvSubscribe *subscribe; GList *sources; @@ -69,9 +69,17 @@ enum PROP_PROPERTIES, PROP_STATE, PROP_CONNECTION, - PROP_CLIENT_PROXY + PROP_SUBSCRIPTION_MASK, }; +enum +{ + SIGNAL_SUBSCRIPTION_EVENT, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + static void pv_context_get_property (GObject *_object, guint prop_id, @@ -98,8 +106,8 @@ pv_context_get_property (GObject *_object, g_value_set_object (value, priv->connection); break; - case PROP_CLIENT_PROXY: - g_value_set_object (value, priv->client); + case PROP_SUBSCRIPTION_MASK: + g_value_set_flags (value, priv->subscription_mask); break; default: @@ -129,6 +137,10 @@ pv_context_set_property (GObject *_object, priv->properties = g_value_dup_variant (value); break; + case PROP_SUBSCRIPTION_MASK: + priv->subscription_mask = g_value_get_flags (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (context, prop_id, pspec); break; @@ -213,18 +225,41 @@ pv_context_class_init (PvContextClass * klass) G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); /** - * PvContext:client-path + * PvContext:subscription-mask * - * The client object path of the context. + * The subscription mask */ g_object_class_install_property (gobject_class, - PROP_CLIENT_PROXY, - g_param_spec_object ("client-proxy", - "Client Proxy", - "The client proxy", - G_TYPE_DBUS_PROXY, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS)); + PROP_SUBSCRIPTION_MASK, + g_param_spec_flags ("subscription-mask", + "Subscription Mask", + "The object to receive subscription events of", + PV_TYPE_SUBSCRIPTION_FLAGS, + 0, + G_PARAM_READWRITE | + G_PARAM_STATIC_STRINGS)); + /** + * PvContext:subscription-event + * @subscribe: The #PvContext emitting the signal. + * @event: A #PvSubscriptionEvent + * @flags: #PvSubscriptionFlags indicating the object + * @object: the GDBusProxy object + * + * Notify about a new object that was added/removed/modified. + */ + signals[SIGNAL_SUBSCRIPTION_EVENT] = g_signal_new ("subscription-event", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_generic, + G_TYPE_NONE, + 3, + PV_TYPE_SUBSCRIPTION_EVENT, + PV_TYPE_SUBSCRIPTION_FLAGS, + G_TYPE_DBUS_PROXY); + } static void @@ -234,10 +269,10 @@ pv_context_init (PvContext * context) priv->state = PV_CONTEXT_STATE_UNCONNECTED; priv->server_manager = g_dbus_object_manager_server_new (PV_DBUS_OBJECT_PREFIX); - priv->internal_subscribe = pv_subscribe_new (); - g_object_set (priv->internal_subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); - g_signal_connect (priv->internal_subscribe, "subscription-event", (GCallback) subscription_cb, context); - g_signal_connect (priv->internal_subscribe, "notify::state", (GCallback) subscription_state, context); + priv->subscribe = pv_subscribe_new (); + g_object_set (priv->subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); + g_signal_connect (priv->subscribe, "subscription-event", (GCallback) subscription_cb, context); + g_signal_connect (priv->subscribe, "notify::state", (GCallback) subscription_state, context); } /** @@ -362,6 +397,15 @@ subscription_cb (PvSubscribe *subscribe, case PV_SUBSCRIPTION_FLAGS_SOURCE_OUTPUT: break; } + + if (flags & priv->subscription_mask) + g_signal_emit (context, + signals[SIGNAL_SUBSCRIPTION_EVENT], + 0, + event, + flags, + object); + } static void @@ -373,7 +417,6 @@ subscription_state (GObject *object, PvSubscriptionState state; g_object_get (object, "state", &state, NULL); - g_print ("got subscription state %d\n", state); switch (state) { @@ -399,12 +442,8 @@ on_name_appeared (GDBusConnection *connection, priv->connection = connection; g_dbus_object_manager_server_set_connection (priv->server_manager, connection); - if (priv->subscribe) { - g_object_set (priv->subscribe, "connection", priv->connection, - "service", name, NULL); - } - g_object_set (priv->internal_subscribe, "connection", priv->connection, - "service", name, NULL); + g_object_set (priv->subscribe, "connection", priv->connection, + "service", name, NULL); } static void @@ -418,10 +457,7 @@ on_name_vanished (GDBusConnection *connection, priv->connection = connection; g_dbus_object_manager_server_set_connection (priv->server_manager, connection); - if (priv->subscribe) - g_object_set (priv->subscribe, "connection", connection, NULL); - - g_object_set (priv->internal_subscribe, "connection", connection, NULL); + g_object_set (priv->subscribe, "connection", connection, NULL); if (priv->flags & PV_CONTEXT_FLAGS_NOFAIL) { context_set_state (context, PV_CONTEXT_STATE_CONNECTING); @@ -430,37 +466,6 @@ on_name_vanished (GDBusConnection *connection, } } -/** - * pv_context_set_subscribe: - * @context: a #PvContext - * @subscribe: (transfer full): a #PvSubscribe - * - * Use @subscribe to receive subscription events from @context. - * - * Returns: %TRUE on success. - */ -gboolean -pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe) -{ - PvContextPrivate *priv; - - g_return_val_if_fail (PV_IS_CONTEXT (context), FALSE); - - priv = context->priv; - - if (priv->subscribe) - g_object_unref (priv->subscribe); - priv->subscribe = subscribe; - - if (priv->subscribe && priv->connection) { - g_object_set (priv->subscribe, "connection", priv->connection, - "service", PV_DBUS_SERVICE, NULL); - } - - return TRUE; -} - - /** * pv_context_connect: * @context: a #PvContext @@ -623,23 +628,6 @@ pv_context_get_connection (PvContext *context) return context->priv->connection; } -/** - * pv_context_get_client_proxy: - * @context: a #PvContext - * - * Get the client proxy that @context is registered with - * - * Returns: the client proxy of @context or %NULL when not - * registered. - */ -GDBusProxy * -pv_context_get_client_proxy (PvContext *context) -{ - g_return_val_if_fail (PV_IS_CONTEXT (context), NULL); - - return G_DBUS_PROXY (context->priv->client); -} - GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props) { diff --git a/src/client/pv-context.h b/src/client/pv-context.h index 03f9046f7..2cfb03376 100644 --- a/src/client/pv-context.h +++ b/src/client/pv-context.h @@ -100,8 +100,6 @@ GType pv_context_get_type (void); PvContext * pv_context_new (const gchar *name, GVariant *properties); -gboolean pv_context_set_subscribe (PvContext *context, PvSubscribe *subscribe); - gboolean pv_context_connect (PvContext *context, PvContextFlags flags); gboolean pv_context_disconnect (PvContext *context); @@ -111,7 +109,6 @@ gboolean pv_context_unregister_source (PvContext *context, PvSource PvContextState pv_context_get_state (PvContext *context); GDBusConnection * pv_context_get_connection (PvContext *context); -GDBusProxy * pv_context_get_client_proxy (PvContext *context); GDBusProxy * pv_context_find_source (PvContext *context, const gchar *name, GVariant *props); diff --git a/src/client/pv-subscribe.c b/src/client/pv-subscribe.c index 03eac08d2..81b695503 100644 --- a/src/client/pv-subscribe.c +++ b/src/client/pv-subscribe.c @@ -363,11 +363,57 @@ on_client_manager_signal (GDBusObjectManagerClient *manager, g_print ("proxy signal %s\n", signal_name); } +static void +client_manager_appeared (PvSubscribe *subscribe) +{ + PvSubscribePrivate *priv = subscribe->priv; + GList *objects, *walk; + + objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager)); + for (walk = objects; walk ; walk = g_list_next (walk)) { + on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager), + walk->data, + subscribe); + } + if (--priv->pending_subscribes == 0) + subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY); +} + +static void +client_manager_disappeared (PvSubscribe *subscribe) +{ +} + +static void +on_client_manager_name_owner (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + PvSubscribe *subscribe = user_data; + PvSubscribePrivate *priv = subscribe->priv; + gchar *name_owner; + + g_object_get (priv->client_manager, "name-owner", &name_owner, NULL); + g_print ("client manager %s %s\n", + g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)), + name_owner); + + if (name_owner) { + client_manager_appeared (subscribe); + g_free (name_owner); + } else { + client_manager_disappeared (subscribe); + } +} + + static void connect_client_signals (PvSubscribe *subscribe) { PvSubscribePrivate *priv = subscribe->priv; + g_signal_connect (priv->client_manager, "notify::name-owner", + (GCallback) on_client_manager_name_owner, subscribe); g_signal_connect (priv->client_manager, "interface-added", (GCallback) on_client_manager_interface_added, subscribe); g_signal_connect (priv->client_manager, "interface-removed", @@ -390,27 +436,14 @@ on_client_manager_ready (GObject *source_object, PvSubscribe *subscribe = user_data; PvSubscribePrivate *priv = subscribe->priv; GError *error = NULL; - GList *objects, *walk; priv->client_manager = pv_object_manager_client_new_finish (res, &error); if (priv->client_manager == NULL) goto manager_error; - g_print ("client manager %s %s\n", - g_dbus_object_manager_client_get_name (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager)), - g_dbus_object_manager_client_get_name_owner (G_DBUS_OBJECT_MANAGER_CLIENT (priv->client_manager))); - connect_client_signals (subscribe); - objects = g_dbus_object_manager_get_objects (G_DBUS_OBJECT_MANAGER (priv->client_manager)); - for (walk = objects; walk ; walk = g_list_next (walk)) { - on_client_manager_object_added (G_DBUS_OBJECT_MANAGER (priv->client_manager), - walk->data, - subscribe); - } - if (--priv->pending_subscribes == 0) - subscription_set_state (subscribe, PV_SUBSCRIPTION_STATE_READY); - + on_client_manager_name_owner (G_OBJECT (priv->client_manager), NULL, subscribe); return; /* ERRORS */ @@ -498,7 +531,8 @@ pv_subscribe_set_property (GObject *_object, if (priv->connection) g_object_unref (priv->connection); priv->connection = g_value_dup_object (value); - install_subscription (subscribe); + if (priv->connection) + install_subscription (subscribe); break; } diff --git a/src/tests/test-subscribe.c b/src/tests/test-subscribe.c index a87b813cf..d28f81b8f 100644 --- a/src/tests/test-subscribe.c +++ b/src/tests/test-subscribe.c @@ -69,12 +69,8 @@ on_state_notify (GObject *gobject, break; case PV_CONTEXT_STATE_READY: { - PvSubscribe *subscribe; - - subscribe = pv_subscribe_new (); - g_object_set (subscribe, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); - g_signal_connect (subscribe, "subscription-event", (GCallback) subscription_cb, NULL); - pv_context_set_subscribe (c, subscribe); + g_object_set (c, "subscription-mask", PV_SUBSCRIPTION_FLAGS_ALL, NULL); + g_signal_connect (c, "subscription-event", (GCallback) subscription_cb, NULL); break; }