Skip to content

Commit edebfee

Browse files
committed
clapper-app: Create pipeline preview file async
1 parent b8a4a90 commit edebfee

File tree

4 files changed

+124
-43
lines changed

4 files changed

+124
-43
lines changed

src/bin/clapper-app/clapper-app-application.c

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ struct _ClapperAppApplication
4141
GtkApplication parent;
4242

4343
GSettings *settings;
44+
GCancellable *cancellable;
4445

4546
gboolean need_init_state;
4647
};
@@ -61,6 +62,12 @@ struct ClapperPluginData
6162
struct ClapperPluginFeatureData features[10];
6263
};
6364

65+
typedef struct
66+
{
67+
ClapperAppApplication *app;
68+
guint id;
69+
} ClapperAppWindowData;
70+
6471
typedef struct
6572
{
6673
const gchar *action;
@@ -396,7 +403,7 @@ show_info (GSimpleAction *action, GVariant *param, gpointer user_data)
396403
}
397404

398405
static void
399-
_show_pipeline_cb (GtkFileLauncher *launcher,
406+
_launch_pipeline_cb (GtkFileLauncher *launcher,
400407
GAsyncResult *res, gpointer user_data G_GNUC_UNUSED)
401408
{
402409
GError *error = NULL;
@@ -411,14 +418,52 @@ _show_pipeline_cb (GtkFileLauncher *launcher,
411418
}
412419

413420
static void
414-
show_pipeline (GSimpleAction *action, GVariant *param, gpointer user_data)
421+
_show_pipeline_cb (GObject *source G_GNUC_UNUSED,
422+
GAsyncResult *res, ClapperAppWindowData *win_data)
415423
{
416-
GtkApplication *gtk_app = GTK_APPLICATION (user_data);
424+
GTask *task = G_TASK (res);
417425
GtkWindow *window;
418-
GtkFileLauncher *launcher;
419426
GFile *svg_file;
420427
GError *error = NULL;
421428

429+
svg_file = (GFile *) g_task_propagate_pointer (task, &error);
430+
431+
if (error) {
432+
if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED) {
433+
GST_ERROR ("Could not create pipeline graph file, reason: %s",
434+
GST_STR_NULL (error->message));
435+
}
436+
g_error_free (error);
437+
g_free (win_data);
438+
439+
return;
440+
}
441+
442+
if ((window = gtk_application_get_window_by_id (
443+
GTK_APPLICATION (win_data->app), win_data->id))) {
444+
GtkFileLauncher *launcher = gtk_file_launcher_new (svg_file);
445+
446+
#if GTK_CHECK_VERSION(4,12,0)
447+
gtk_file_launcher_set_always_ask (launcher, TRUE);
448+
#endif
449+
450+
gtk_file_launcher_launch (launcher, window, NULL,
451+
(GAsyncReadyCallback) _launch_pipeline_cb, NULL);
452+
g_object_unref (launcher);
453+
}
454+
455+
g_object_unref (svg_file);
456+
g_free (win_data);
457+
}
458+
459+
static void
460+
show_pipeline (GSimpleAction *action, GVariant *param, gpointer user_data)
461+
{
462+
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (user_data);
463+
GtkApplication *gtk_app = GTK_APPLICATION (self);
464+
GtkWindow *window;
465+
ClapperAppWindowData *win_data;
466+
422467
window = gtk_application_get_active_window (gtk_app);
423468

424469
while (window && !CLAPPER_APP_IS_WINDOW (window))
@@ -427,25 +472,19 @@ show_pipeline (GSimpleAction *action, GVariant *param, gpointer user_data)
427472
if (G_UNLIKELY (window == NULL))
428473
return;
429474

430-
if (!(svg_file = clapper_app_utils_create_pipeline_svg_file (
431-
clapper_app_window_get_player (CLAPPER_APP_WINDOW (window)), &error))) {
432-
GST_ERROR ("Could not create pipeline graph file, reason: %s",
433-
GST_STR_NULL (error->message));
434-
g_error_free (error);
435-
436-
return;
475+
if (self->cancellable) {
476+
g_cancellable_cancel (self->cancellable);
477+
g_object_unref (self->cancellable);
437478
}
479+
self->cancellable = g_cancellable_new ();
438480

439-
launcher = gtk_file_launcher_new (svg_file);
440-
g_object_unref (svg_file);
441-
442-
#if GTK_CHECK_VERSION(4,12,0)
443-
gtk_file_launcher_set_always_ask (launcher, TRUE);
444-
#endif
481+
win_data = g_new (ClapperAppWindowData, 1);
482+
win_data->app = self;
483+
win_data->id = gtk_application_window_get_id (GTK_APPLICATION_WINDOW (window));
445484

446-
gtk_file_launcher_launch (launcher, window, NULL,
447-
(GAsyncReadyCallback) _show_pipeline_cb, NULL);
448-
g_object_unref (launcher);
485+
clapper_app_utils_create_pipeline_svg_file_async (
486+
clapper_app_window_get_player (CLAPPER_APP_WINDOW (window)),
487+
self->cancellable, (GAsyncReadyCallback) _show_pipeline_cb, win_data);
449488
}
450489

451490
static void
@@ -809,13 +848,30 @@ clapper_app_application_constructed (GObject *object)
809848
G_OBJECT_CLASS (parent_class)->constructed (object);
810849
}
811850

851+
static void
852+
clapper_app_application_dispose (GObject *object)
853+
{
854+
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (object);
855+
856+
if (self->cancellable) {
857+
g_cancellable_cancel (self->cancellable);
858+
g_clear_object (&self->cancellable);
859+
}
860+
861+
G_OBJECT_CLASS (parent_class)->dispose (object);
862+
}
863+
812864
static void
813865
clapper_app_application_finalize (GObject *object)
814866
{
815867
ClapperAppApplication *self = CLAPPER_APP_APPLICATION_CAST (object);
816868

817869
GST_TRACE ("Finalize");
818870

871+
if (self->cancellable) {
872+
g_cancellable_cancel (self->cancellable);
873+
g_object_unref (self->cancellable);
874+
}
819875
g_object_unref (self->settings);
820876

821877
G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -832,6 +888,7 @@ clapper_app_application_class_init (ClapperAppApplicationClass *klass)
832888
"Clapper App Application");
833889

834890
gobject_class->constructed = clapper_app_application_constructed;
891+
gobject_class->dispose = clapper_app_application_dispose;
835892
gobject_class->finalize = clapper_app_application_finalize;
836893

837894
gtk_application_class->window_removed = clapper_app_application_window_removed;

src/bin/clapper-app/clapper-app-application.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <glib.h>
2121
#include <glib-object.h>
22+
#include <gio/gio.h>
2223
#include <gtk/gtk.h>
2324

2425
G_BEGIN_DECLS

src/bin/clapper-app/clapper-app-utils.c

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -548,42 +548,42 @@ _get_tmp_dir (const gchar *subdir)
548548

549549
#ifdef HAVE_GRAPHVIZ
550550
static GFile *
551-
_create_tmp_subdir (const gchar *subdir)
551+
_create_tmp_subdir (const gchar *subdir, GCancellable *cancellable, GError **error)
552552
{
553553
GFile *tmp_dir;
554-
GError *error = NULL;
554+
GError *my_error = NULL;
555555

556556
tmp_dir = _get_tmp_dir (subdir);
557557

558-
if (!g_file_make_directory_with_parents (tmp_dir, NULL, &error)) {
559-
if (error->domain != G_IO_ERROR || error->code != G_IO_ERROR_EXISTS) {
560-
GST_ERROR ("Could not create temp dir, reason: %s",
561-
GST_STR_NULL (error->message));
558+
if (!g_file_make_directory_with_parents (tmp_dir, cancellable, &my_error)) {
559+
if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_EXISTS) {
560+
*error = g_error_copy (my_error);
562561
g_clear_object (&tmp_dir); // return NULL
563562
}
564-
g_error_free (error);
563+
g_error_free (my_error);
565564
}
566565

567566
return tmp_dir;
568567
}
569568
#endif
570569

571-
GFile *
572-
clapper_app_utils_create_pipeline_svg_file (ClapperPlayer *player, GError **error)
570+
static void
571+
_create_pipeline_svg_file_in_thread (GTask *task, GObject *source G_GNUC_UNUSED,
572+
ClapperPlayer *player, GCancellable *cancellable)
573573
{
574574
GFile *tmp_file = NULL;
575+
GError *error = NULL;
575576

576577
#ifdef HAVE_GRAPHVIZ
577578
GFile *tmp_subdir;
578579
Agraph_t *graph;
579580
GVC_t *gvc;
580-
gchar *path, *template, *dot_data, *img_data = NULL;
581+
gchar *path, *template = NULL, *dot_data = NULL, *img_data = NULL;
581582
gint fd;
582583
guint size = 0;
583584

584-
tmp_subdir = _create_tmp_subdir ("pipelines");
585-
if (G_UNLIKELY (tmp_subdir == NULL))
586-
return NULL;
585+
if (!(tmp_subdir = _create_tmp_subdir ("pipelines", cancellable, &error)))
586+
goto finish;
587587

588588
path = g_file_get_path (tmp_subdir);
589589
g_object_unref (tmp_subdir);
@@ -594,14 +594,16 @@ clapper_app_utils_create_pipeline_svg_file (ClapperPlayer *player, GError **erro
594594
fd = g_mkstemp (template); // Modifies template to actual filename
595595

596596
if (G_UNLIKELY (fd == -1)) {
597-
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
597+
g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
598598
"Could not open temp file for writing");
599-
g_free (template);
600-
601-
return NULL;
599+
goto finish;
602600
}
603601

604602
dot_data = clapper_player_make_pipeline_graph (player, GST_DEBUG_GRAPH_SHOW_ALL);
603+
604+
if (g_cancellable_is_cancelled (cancellable))
605+
goto close_and_finish;
606+
605607
graph = agmemread (dot_data);
606608

607609
gvc = gvContext ();
@@ -610,27 +612,48 @@ clapper_app_utils_create_pipeline_svg_file (ClapperPlayer *player, GError **erro
610612

611613
agclose (graph);
612614
gvFreeContext (gvc);
613-
g_free (dot_data);
615+
616+
if (g_cancellable_is_cancelled (cancellable))
617+
goto close_and_finish;
614618

615619
if (write (fd, img_data, size) != -1) {
616620
tmp_file = g_file_new_for_path (template);
617621
} else {
618-
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
622+
g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
619623
"Could not write data to temp file");
620624
}
621625

626+
close_and_finish:
622627
/* Always close the file IO */
623628
if (G_UNLIKELY (close (fd) == -1))
624629
GST_ERROR ("Could not close temp file!");
625630

626-
g_free (img_data);
631+
finish:
627632
g_free (template);
633+
g_free (dot_data);
634+
g_free (img_data);
628635
#else
629-
g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
636+
g_set_error (&error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
630637
"Cannot create graph file when compiled without Graphviz");
631638
#endif
632639

633-
return tmp_file;
640+
if (tmp_file)
641+
g_task_return_pointer (task, tmp_file, (GDestroyNotify) g_object_unref);
642+
else
643+
g_task_return_error (task, error);
644+
}
645+
646+
void
647+
clapper_app_utils_create_pipeline_svg_file_async (ClapperPlayer *player,
648+
GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data)
649+
{
650+
GTask *task;
651+
652+
task = g_task_new (NULL, cancellable, callback, user_data);
653+
g_task_set_task_data (task, gst_object_ref (player), (GDestroyNotify) gst_object_unref);
654+
g_task_run_in_thread (task, (GTaskThreadFunc) _create_pipeline_svg_file_in_thread);
655+
656+
g_object_unref (task);
634657
}
635658

636659
static gboolean

src/bin/clapper-app/clapper-app-utils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ G_GNUC_INTERNAL
8585
GstElement * clapper_app_utils_make_element (const gchar *string);
8686

8787
G_GNUC_INTERNAL
88-
GFile * clapper_app_utils_create_pipeline_svg_file (ClapperPlayer *player, GError **error);
88+
void clapper_app_utils_create_pipeline_svg_file_async (ClapperPlayer *player, GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
8989

9090
G_GNUC_INTERNAL
9191
void clapper_app_utils_delete_tmp_dir (void);

0 commit comments

Comments
 (0)