From 295b6184171bdd230e5e61f0ba2ad26d504062a8 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Tue, 25 Aug 2020 17:15:49 +0200 Subject: Implement progress bar for indexing via generic interface --- src/crystfel_gui.c | 47 +++++++++++++++++++++++++++++++++++++++++++---- src/gui_backend_local.c | 19 +++++++++++++++++-- src/gui_backend_slurm.c | 12 ++++++++++++ src/gui_project.h | 7 +++++++ 4 files changed, 79 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/crystfel_gui.c b/src/crystfel_gui.c index fd79e9da..3e8f6b24 100644 --- a/src/crystfel_gui.c +++ b/src/crystfel_gui.c @@ -1006,7 +1006,11 @@ static void infobar_response_sig(GtkInfoBar *infobar, gint resp, if ( resp == GTK_RESPONSE_CANCEL ) { task->backend->cancel_task(task->job_priv); - /* FIXME: Cancel processing */ + + } else if ( resp == GTK_RESPONSE_CLOSE ) { + + gtk_info_bar_set_revealed(infobar, FALSE); + /* FIXME: Remove task from list */ } else { ERROR("Unrecognised infobar response!\n"); @@ -1014,6 +1018,33 @@ static void infobar_response_sig(GtkInfoBar *infobar, gint resp, } +static gboolean update_info_bar(gpointer data) +{ + struct gui_task *task = data; + int running; + float frac_complete; + + if ( task->backend->task_status(task->job_priv, + &running, &frac_complete) ) { + ERROR("Error retrieving task status\n"); + return G_SOURCE_CONTINUE; + } + + gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(task->progress_bar), + frac_complete); + + if ( !running && task->running ) { + /* Task is no longer running */ + gtk_widget_destroy(task->cancel_button); + gtk_info_bar_set_show_close_button(GTK_INFO_BAR(task->info_bar), + TRUE); + return G_SOURCE_REMOVE; + } + + return G_SOURCE_CONTINUE; +} + + void add_running_task(struct crystfelproject *proj, const char *task_desc, struct crystfel_backend *backend, @@ -1025,11 +1056,17 @@ void add_running_task(struct crystfelproject *proj, task = &proj->tasks[proj->n_running_tasks++]; task->job_priv = job_priv; task->backend = backend; + task->running = 1; /* Progress info bar */ - task->info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_CANCEL, - GTK_RESPONSE_CANCEL, - NULL); + task->info_bar = gtk_info_bar_new(); + gtk_info_bar_set_message_type(GTK_INFO_BAR(task->info_bar), + GTK_MESSAGE_INFO); + + task->cancel_button = gtk_info_bar_add_button(GTK_INFO_BAR(task->info_bar), + GTK_STOCK_CANCEL, + GTK_RESPONSE_CANCEL); + gtk_box_pack_end(GTK_BOX(proj->main_vbox), GTK_WIDGET(task->info_bar), FALSE, FALSE, 0.0); @@ -1050,4 +1087,6 @@ void add_running_task(struct crystfelproject *proj, gtk_widget_show_all(task->info_bar); gtk_info_bar_set_revealed(GTK_INFO_BAR(task->info_bar), TRUE); + + g_timeout_add(500, update_info_bar, task); } diff --git a/src/gui_backend_local.c b/src/gui_backend_local.c index 5e65b3c1..41be3c33 100644 --- a/src/gui_backend_local.c +++ b/src/gui_backend_local.c @@ -90,7 +90,9 @@ static gboolean index_readable(GIOChannel *source, GIOCondition cond, } chomp(line); - if ( strstr(line, " images processed, ") != NULL ) { + if ( strncmp(line, "Final: ", 7) == 0 ) { + job->frac_complete = 1.0; + } else if ( strstr(line, " images processed, ") != NULL ) { int n_proc; sscanf(line, "%i ", &n_proc); job->frac_complete = (double)n_proc/job->n_frames; @@ -178,7 +180,8 @@ static void *run_indexing(char **filenames, free(job); return NULL; } - job->n_frames = job->n_frames; + job->n_frames = n_frames; + job->frac_complete = 0.0; strcpy(index_str, "--indexing=dirax"); /* FIXME */ @@ -263,6 +266,17 @@ static void *run_indexing(char **filenames, } +static int get_task_status(void *job_priv, + int *running, + float *frac_complete) +{ + struct local_job *job = job_priv; + *frac_complete = job->frac_complete; + *running = job->indexamajig_running; + return 0; +} + + static void cancel_task(void *job_priv) { struct local_job *job = job_priv; @@ -354,6 +368,7 @@ int make_local_backend(struct crystfel_backend *be) be->make_indexing_parameters_widget = make_indexing_parameters_widget; be->run_indexing = run_indexing; be->cancel_task = cancel_task; + be->task_status = get_task_status; be->indexing_opts_priv = make_default_local_opts(); if ( be->indexing_opts_priv == NULL ) return 1; be->write_indexing_opts = write_indexing_opts; diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index 434c9302..545e0acb 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -51,6 +51,17 @@ struct slurm_job }; +static int get_task_status(void *job_priv, + int *running, + float *frac_complete) +{ + struct slurm_job *job = job_priv; + *frac_complete = job->frac_complete; + *running = 0; + return 1; +} + + static void cancel_task(void *job_priv) { //struct slurm_job *job = job_priv; @@ -223,6 +234,7 @@ int make_slurm_backend(struct crystfel_backend *be) be->write_indexing_opts = write_indexing_opts; be->read_indexing_opt = read_indexing_opt; be->cancel_task = cancel_task; + be->task_status = get_task_status; be->indexing_opts_priv = make_default_slurm_opts(); if ( be->indexing_opts_priv == NULL ) return 1; diff --git a/src/gui_project.h b/src/gui_project.h index d2a78079..6d6ca919 100644 --- a/src/gui_project.h +++ b/src/gui_project.h @@ -106,6 +106,11 @@ struct crystfel_backend { /* Called to ask the backend to cancel the job */ void (*cancel_task)(void *job_priv); + /* Called to get the status of a task */ + int (*task_status)(void *job_priv, + int *running, + float *fraction_complete); + /* Called to ask the backend to write its indexing options */ void (*write_indexing_opts)(void *opts_priv, FILE *fh); @@ -122,7 +127,9 @@ struct crystfel_backend { struct gui_task { GtkWidget *info_bar; + GtkWidget *cancel_button; GtkWidget *progress_bar; + int running; struct crystfel_backend *backend; void *job_priv; }; -- cgit v1.2.3