From c8f83c99dc82c7eb96480c7533e6f94744af356d Mon Sep 17 00:00:00 2001 From: George Kiagiadakis <george.kiagiadakis@collabora.com> Date: Sun, 29 Mar 2020 14:20:22 +0300 Subject: [PATCH] session-item: export streams --- lib/wp/session-item.c | 181 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 148 insertions(+), 33 deletions(-) diff --git a/lib/wp/session-item.c b/lib/wp/session-item.c index f2e2d6d1..402873d8 100644 --- a/lib/wp/session-item.c +++ b/lib/wp/session-item.c @@ -72,6 +72,7 @@ struct _WpSessionItemPrivate guint32 flags; WpImplEndpoint *impl_endpoint; + GHashTable *impl_streams; }; enum { @@ -151,63 +152,173 @@ wp_session_item_default_reset (WpSessionItem * self) g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); } +enum { + EXPORT_STEP_ENDPOINT = WP_TRANSITION_STEP_CUSTOM_START, + EXPORT_STEP_STREAMS, + EXPORT_STEP_LINK, + EXPORT_STEP_FINISH, +}; + +static guint +default_export_get_next_step (WpSessionItem * self, WpTransition * transition, + guint step) +{ + WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); + + switch (step) { + case WP_TRANSITION_STEP_NONE: + if (WP_IS_SI_ENDPOINT (self)) { + priv->flags |= WP_SI_FLAG_EXPORTING; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + return EXPORT_STEP_ENDPOINT; + } + else if (WP_IS_SI_LINK (self)) { + priv->flags |= WP_SI_FLAG_EXPORTING; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + return EXPORT_STEP_LINK; + } + else { + wp_transition_return_error (transition, g_error_new ( + WP_DOMAIN_LIBRARY, WP_LIBRARY_ERROR_INVALID_ARGUMENT, + "Cannot export WpSessionItem of unknown type (%s:%p)", + G_OBJECT_TYPE_NAME (self), self)); + return WP_TRANSITION_STEP_ERROR; + } + + case EXPORT_STEP_ENDPOINT: + return EXPORT_STEP_STREAMS; + + case EXPORT_STEP_STREAMS: + g_return_val_if_fail (WP_IS_SI_ENDPOINT (self), WP_TRANSITION_STEP_ERROR); + g_return_val_if_fail (priv->impl_streams, WP_TRANSITION_STEP_ERROR); + + /* go to next step only when all impl proxies are augmented */ + if (g_hash_table_size (priv->impl_streams) == + wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self))) + return EXPORT_STEP_FINISH; + else + return step; + + case EXPORT_STEP_FINISH: + return WP_TRANSITION_STEP_NONE; + + default: + return WP_TRANSITION_STEP_ERROR; + } +} + static void on_export_proxy_augmented (WpProxy * proxy, GAsyncResult * res, gpointer data) { - g_autoptr (GTask) task = G_TASK (data); - g_autoptr (GError) error = NULL; - WpSessionItem *self = WP_SESSION_ITEM (g_task_get_source_object (task)); + WpTransition *transition = WP_TRANSITION (data); + WpSessionItem *self = wp_transition_get_source_object (transition); WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); - - priv->flags &= ~WP_SI_FLAG_EXPORTING; + g_autoptr (GError) error = NULL; if (!wp_proxy_augment_finish (proxy, res, &error)) { - g_weak_ref_set (&priv->session, NULL); - g_clear_object (&priv->impl_endpoint); - g_task_return_error (task, g_steal_pointer (&error)); + wp_transition_return_error (transition, g_steal_pointer (&error)); return; } - priv->flags |= WP_SI_FLAG_EXPORTED; - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); - g_task_return_boolean (task, TRUE); + if (WP_IS_IMPL_ENDPOINT_STREAM (proxy)) { + g_autoptr (WpSiStream) si_stream = NULL; + + g_object_get (proxy, "item", &si_stream, NULL); + g_return_if_fail (si_stream != NULL); + + g_hash_table_insert (priv->impl_streams, si_stream, g_object_ref (proxy)); + } + + wp_transition_advance (transition); } static void -wp_session_item_default_export (WpSessionItem * self, - WpSession * session, GCancellable * cancellable, - GAsyncReadyCallback callback, gpointer callback_data) +default_export_execute_step (WpSessionItem * self, WpTransition * transition, + guint step) { WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); + g_autoptr (WpSession) session = g_weak_ref_get (&priv->session); g_autoptr (WpCore) core = wp_proxy_get_core (WP_PROXY (session)); - g_autoptr (GTask) task = NULL; - - g_return_if_fail (priv->flags & WP_SI_FLAG_ACTIVE); - g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED))); - task = g_task_new (self, cancellable, callback, callback_data); - g_task_set_source_tag (task, wp_session_item_default_export); - - if (WP_IS_SI_ENDPOINT (self)) { - g_weak_ref_set (&priv->session, session); - priv->flags |= WP_SI_FLAG_EXPORTING; + switch (step) { + case EXPORT_STEP_ENDPOINT: priv->impl_endpoint = wp_impl_endpoint_new (core, WP_SI_ENDPOINT (self)); - g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); - wp_proxy_augment (WP_PROXY (priv->impl_endpoint), WP_PROXY_FEATURES_STANDARD, NULL, (GAsyncReadyCallback) on_export_proxy_augmented, - g_steal_pointer (&task)); + transition); + break; + + case EXPORT_STEP_STREAMS: { + guint i, n_streams; + + priv->impl_streams = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, g_object_unref); + + n_streams = wp_si_endpoint_get_n_streams (WP_SI_ENDPOINT (self)); + for (i = 0; i < n_streams; i++) { + WpSiStream *stream = wp_si_endpoint_get_stream (WP_SI_ENDPOINT (self), i); + WpImplEndpointStream *impl_stream = + wp_impl_endpoint_stream_new (core, stream); + + wp_proxy_augment (WP_PROXY (impl_stream), + WP_PROXY_FEATURES_STANDARD, NULL, + (GAsyncReadyCallback) on_export_proxy_augmented, + transition); + + /* the augment task holds a ref; object will be added to + priv->impl_streams when augmented */ + g_object_unref (impl_stream); + } + break; } - else { - g_task_return_new_error (task, WP_DOMAIN_LIBRARY, - WP_LIBRARY_ERROR_INVALID_ARGUMENT, - "Cannot export WpSessionItem of unknown type (%s:%p)", - G_OBJECT_TYPE_NAME (self), self); + case EXPORT_STEP_LINK: + /* TODO implement me */ + break; + + case EXPORT_STEP_FINISH: + priv->flags &= ~WP_SI_FLAG_EXPORTING; + priv->flags |= WP_SI_FLAG_EXPORTED; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + wp_transition_advance (transition); + break; + + case WP_TRANSITION_STEP_ERROR: + g_clear_pointer (&priv->impl_streams, g_hash_table_unref); + g_clear_object (&priv->impl_endpoint); + g_weak_ref_set (&priv->session, NULL); + + if (priv->flags & WP_SI_FLAG_EXPORTING) { + priv->flags &= ~WP_SI_FLAG_EXPORTING; + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); + } + break; } } +static void +wp_session_item_default_export (WpSessionItem * self, + WpSession * session, GCancellable * cancellable, + GAsyncReadyCallback callback, gpointer callback_data) +{ + WpSessionItemPrivate *priv = wp_session_item_get_instance_private (self); + WpTransition *transition; + + g_return_if_fail (priv->flags & WP_SI_FLAG_ACTIVE); + g_return_if_fail (!(priv->flags & (WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED))); + + g_weak_ref_set (&priv->session, session); + + transition = wp_transition_new (wp_si_transition_get_type (), + self, cancellable, callback, callback_data); + wp_transition_set_source_tag (transition, wp_session_item_default_export); + + WP_SI_TRANSITION (transition)->get_next_step = default_export_get_next_step; + WP_SI_TRANSITION (transition)->execute_step = default_export_execute_step; + wp_transition_advance (transition); +} + static gboolean wp_session_item_default_export_finish (WpSessionItem * self, GAsyncResult * res, GError ** error) @@ -215,7 +326,7 @@ wp_session_item_default_export_finish (WpSessionItem * self, g_return_val_if_fail ( g_async_result_is_tagged (res, wp_session_item_default_export), FALSE); - return g_task_propagate_boolean (G_TASK (res), error); + return wp_transition_finish (res, error); } static void @@ -225,8 +336,12 @@ wp_session_item_default_unexport (WpSessionItem * self) //TODO cancel job if EXPORTING + g_clear_pointer (&priv->impl_streams, g_hash_table_unref); g_clear_object (&priv->impl_endpoint); + g_weak_ref_set (&priv->session, NULL); + priv->flags &= ~(WP_SI_FLAG_EXPORTING | WP_SI_FLAG_EXPORTED); + g_signal_emit (self, signals[SIGNAL_FLAGS_CHANGED], 0, priv->flags); } static void -- GitLab