mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Merge branch '3247_status_msg_update_rate'
* 3247_status_msg_update_rate: (status_msg_init): repaint screen forced to remove previous finished dialog. Reduce update rate in the "Directory scanning" dialog. status_msg_t: reimplement delay usage. (mc_time_elapsed): add new function to detect elapsed time intervals. Ticket #3247: refactoring of status_msg engine.
This commit is contained in:
commit
4addae7f12
@ -31,6 +31,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include "global.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
#ifdef ENABLE_SUBSHELL
|
||||
@ -49,6 +50,7 @@
|
||||
/* *INDENT-OFF* */
|
||||
mc_global_t mc_global = {
|
||||
.mc_run_mode = MC_RUN_FULL,
|
||||
.timer = NULL,
|
||||
.midnight_shutdown = FALSE,
|
||||
|
||||
.sysconfig_dir = NULL,
|
||||
|
@ -173,6 +173,8 @@ typedef enum
|
||||
typedef struct
|
||||
{
|
||||
mc_run_mode_t mc_run_mode;
|
||||
/* global timer */
|
||||
struct mc_timer_t *timer;
|
||||
/* Used so that widgets know if they are being destroyed or shut down */
|
||||
gboolean midnight_shutdown;
|
||||
|
||||
|
26
lib/util.c
26
lib/util.c
@ -52,6 +52,7 @@
|
||||
#include "lib/vfs/vfs.h"
|
||||
#include "lib/strutil.h"
|
||||
#include "lib/util.h"
|
||||
#include "lib/timer.h"
|
||||
|
||||
/*** global variables ****************************************************************************/
|
||||
|
||||
@ -1451,3 +1452,28 @@ mc_replace_error (GError ** dest, int code, const char *format, ...)
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Returns if the given duration has elapsed since the given timestamp,
|
||||
* and if it has then updates the timestamp.
|
||||
*
|
||||
* @param timestamp the last timestamp in microseconds, updated if the given time elapsed
|
||||
* @param deleay amount of time in microseconds
|
||||
|
||||
* @return TRUE if clock skew detected, FALSE otherwise
|
||||
*/
|
||||
gboolean
|
||||
mc_time_elapsed (guint64 * timestamp, guint64 delay)
|
||||
{
|
||||
guint64 now;
|
||||
|
||||
now = mc_timer_elapsed (mc_global.timer);
|
||||
|
||||
if (now >= *timestamp && now < *timestamp + delay)
|
||||
return FALSE;
|
||||
|
||||
*timestamp = now;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
@ -249,6 +249,8 @@ char *mc_build_filenamev (const char *first_element, va_list args);
|
||||
void mc_propagate_error (GError ** dest, int code, const char *format, ...);
|
||||
void mc_replace_error (GError ** dest, int code, const char *format, ...);
|
||||
|
||||
gboolean mc_time_elapsed (guint64 * timestamp, guint64 delay);
|
||||
|
||||
/*** inline functions **************************************************/
|
||||
|
||||
static inline gboolean
|
||||
|
@ -9,7 +9,7 @@
|
||||
Radek Doulik, 1994, 1995
|
||||
Jakub Jelinek, 1995
|
||||
Andrej Borsenkow, 1995
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2009, 2010, 2012, 2013
|
||||
Andrew Borodin <aborodin@vmail.ru>, 2009-2014
|
||||
|
||||
This file is part of the Midnight Commander.
|
||||
|
||||
@ -56,8 +56,6 @@ static WDialog *last_query_dlg;
|
||||
|
||||
static int sel_pos = 0;
|
||||
|
||||
static const guint64 status_msg_delay_threshold = G_USEC_PER_SEC / 100; /* 0.01 s */
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
/*** file scope functions ************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
@ -573,8 +571,16 @@ void
|
||||
status_msg_init (status_msg_t * sm, const char *title, double delay, status_msg_cb init_cb,
|
||||
status_msg_update_cb update_cb, status_msg_cb deinit_cb)
|
||||
{
|
||||
guint64 start;
|
||||
|
||||
/* repaint screen to remove previous finished dialog */
|
||||
mc_refresh ();
|
||||
|
||||
start = mc_timer_elapsed (mc_global.timer);
|
||||
|
||||
sm->dlg = dlg_create (TRUE, 0, 0, 7, min (max (40, COLS / 2), COLS), dialog_colors,
|
||||
NULL, NULL, NULL, title, DLG_CENTER);
|
||||
sm->start = start;
|
||||
sm->delay = delay * G_USEC_PER_SEC;
|
||||
sm->block = FALSE;
|
||||
|
||||
@ -585,11 +591,8 @@ status_msg_init (status_msg_t * sm, const char *title, double delay, status_msg_
|
||||
if (sm->init != NULL)
|
||||
sm->init (sm);
|
||||
|
||||
if (sm->delay > status_msg_delay_threshold)
|
||||
sm->timer = mc_timer_new ();
|
||||
else
|
||||
if (mc_time_elapsed (&start, sm->delay))
|
||||
{
|
||||
sm->timer = NULL;
|
||||
/* We will manage the dialog without any help, that's why we have to call init_dlg */
|
||||
dlg_init (sm->dlg);
|
||||
}
|
||||
@ -611,9 +614,6 @@ status_msg_deinit (status_msg_t * sm)
|
||||
if (sm->deinit != NULL)
|
||||
sm->deinit (sm);
|
||||
|
||||
if (sm->timer != NULL)
|
||||
mc_timer_destroy (sm->timer);
|
||||
|
||||
/* close and destroy dialog */
|
||||
dlg_run_done (sm->dlg);
|
||||
dlg_destroy (sm->dlg);
|
||||
@ -637,24 +637,23 @@ status_msg_common_update (status_msg_t * sm)
|
||||
if (sm == NULL)
|
||||
return B_ENTER;
|
||||
|
||||
if (sm->timer != NULL)
|
||||
{
|
||||
if (mc_timer_elapsed (sm->timer) > sm->delay)
|
||||
{
|
||||
mc_timer_destroy (sm->timer); /* we not need the timer anymore */
|
||||
sm->timer = NULL;
|
||||
|
||||
if (sm->dlg != NULL)
|
||||
dlg_init (sm->dlg);
|
||||
}
|
||||
|
||||
return B_ENTER;
|
||||
}
|
||||
|
||||
/* This should not happen, but... */
|
||||
if (sm->dlg == NULL)
|
||||
return B_ENTER;
|
||||
|
||||
if (sm->dlg->state != DLG_ACTIVE)
|
||||
{
|
||||
/* dialog is not shown yet */
|
||||
|
||||
/* do not change sm->start */
|
||||
guint64 start = sm->start;
|
||||
|
||||
if (mc_time_elapsed (&start, sm->delay))
|
||||
dlg_init (sm->dlg);
|
||||
|
||||
return B_ENTER;
|
||||
}
|
||||
|
||||
event.x = -1; /* Don't show the GPM cursor */
|
||||
c = tty_get_event (&event, FALSE, sm->block);
|
||||
if (c == EV_NONE)
|
||||
|
@ -42,8 +42,8 @@ enum
|
||||
struct status_msg_t
|
||||
{
|
||||
WDialog *dlg; /* pointer to status message dialog */
|
||||
guint64 start; /* start time in microseconds */
|
||||
guint64 delay; /* delay before raise the 'dlg' in microseconds */
|
||||
mc_timer_t *timer; /* timer to measure 'delay' */
|
||||
gboolean block; /* how to get event using tty_get_event() */
|
||||
|
||||
status_msg_cb init; /* callback to init derived classes */
|
||||
|
@ -1515,7 +1515,7 @@ single_dirsize_cmd (void)
|
||||
p = vfs_path_from_str (entry->fname);
|
||||
|
||||
memset (&dsm, 0, sizeof (dsm));
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 1.0, dirsize_status_init_cb,
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 0, dirsize_status_init_cb,
|
||||
dirsize_status_update_cb, dirsize_status_deinit_cb);
|
||||
|
||||
if (compute_dir_size (p, &dsm, &dir_count, &count, &total, TRUE) == FILE_CONT)
|
||||
@ -1550,7 +1550,7 @@ dirsizes_cmd (void)
|
||||
dirsize_status_msg_t dsm;
|
||||
|
||||
memset (&dsm, 0, sizeof (dsm));
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 1.0, dirsize_status_init_cb,
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 0, dirsize_status_init_cb,
|
||||
dirsize_status_update_cb, dirsize_status_deinit_cb);
|
||||
|
||||
for (i = 0; i < panel->dir.len; i++)
|
||||
|
@ -521,7 +521,9 @@ do_compute_dir_size (const vfs_path_t * dirname_vpath, dirsize_status_msg_t * ds
|
||||
size_t * dir_count, size_t * ret_marked, uintmax_t * ret_total,
|
||||
gboolean compute_symlinks)
|
||||
{
|
||||
static unsigned short int update_ui_count = 0;
|
||||
static guint64 timestamp = 0;
|
||||
/* update with 25 FPS rate */
|
||||
static const guint64 delay = G_USEC_PER_SEC / 25;
|
||||
|
||||
status_msg_t *sm = STATUS_MSG (dsm);
|
||||
int res;
|
||||
@ -564,36 +566,23 @@ do_compute_dir_size (const vfs_path_t * dirname_vpath, dirsize_status_msg_t * ds
|
||||
if (res == 0)
|
||||
{
|
||||
if (S_ISDIR (s.st_mode))
|
||||
{
|
||||
ret =
|
||||
do_compute_dir_size (tmp_vpath, dsm, dir_count, ret_marked, ret_total,
|
||||
compute_symlinks);
|
||||
if (ret == FILE_CONT && sm->update != NULL)
|
||||
{
|
||||
dsm->dirname_vpath = tmp_vpath;
|
||||
dsm->dir_count = *dir_count;
|
||||
dsm->total_size = *ret_total;
|
||||
ret = (FileProgressStatus) sm->update (sm);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = FILE_CONT;
|
||||
|
||||
(*ret_marked)++;
|
||||
*ret_total += (uintmax_t) s.st_size;
|
||||
}
|
||||
|
||||
update_ui_count++;
|
||||
if ((update_ui_count & 31) == 0)
|
||||
{
|
||||
if (sm->update == NULL)
|
||||
ret = FILE_CONT;
|
||||
else
|
||||
{
|
||||
dsm->dirname_vpath = dirname_vpath;
|
||||
dsm->dir_count = *dir_count;
|
||||
dsm->total_size = *ret_total;
|
||||
ret = (FileProgressStatus) sm->update (sm);
|
||||
}
|
||||
}
|
||||
if (ret == FILE_CONT && sm->update != NULL && mc_time_elapsed (×tamp, delay))
|
||||
{
|
||||
dsm->dirname_vpath = tmp_vpath;
|
||||
dsm->dir_count = *dir_count;
|
||||
dsm->total_size = *ret_total;
|
||||
ret = (FileProgressStatus) sm->update (sm);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1341,7 +1330,7 @@ panel_operate_init_totals (const WPanel * panel, const char *source, file_op_con
|
||||
|
||||
memset (&dsm, 0, sizeof (dsm));
|
||||
dsm.allow_skip = TRUE;
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 1.0, dirsize_status_init_cb,
|
||||
status_msg_init (STATUS_MSG (&dsm), _("Directory scanning"), 0, dirsize_status_init_cb,
|
||||
dirsize_status_update_cb, dirsize_status_deinit_cb);
|
||||
|
||||
ctx->progress_count = 0;
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "lib/tty/tty.h"
|
||||
#include "lib/tty/key.h" /* For init_key() */
|
||||
#include "lib/tty/mouse.h" /* init_mouse() */
|
||||
#include "lib/timer.h"
|
||||
#include "lib/skin.h"
|
||||
#include "lib/filehighlight.h"
|
||||
#include "lib/fileloc.h"
|
||||
@ -238,6 +239,8 @@ main (int argc, char *argv[])
|
||||
char *config_migrate_msg;
|
||||
int exit_code = EXIT_FAILURE;
|
||||
|
||||
mc_global.timer = mc_timer_new ();
|
||||
|
||||
/* We had LC_CTYPE before, LC_ALL includs LC_TYPE as well */
|
||||
#ifdef HAVE_SETLOCALE
|
||||
(void) setlocale (LC_ALL, "");
|
||||
@ -256,6 +259,7 @@ main (int argc, char *argv[])
|
||||
g_free (mc_global.tty.shell);
|
||||
startup_exit_ok:
|
||||
str_uninit_strings ();
|
||||
mc_timer_destroy (mc_global.timer);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
@ -497,6 +501,8 @@ main (int argc, char *argv[])
|
||||
exit_code = EXIT_FAILURE;
|
||||
}
|
||||
|
||||
mc_timer_destroy (mc_global.timer);
|
||||
|
||||
(void) putchar ('\n'); /* Hack to make shell's prompt start at left of screen */
|
||||
|
||||
return exit_code;
|
||||
|
Loading…
Reference in New Issue
Block a user