Mercurial > ~mikael > mcabber > hg
comparison mcabber/mcabber/main.c @ 2281:1bb9002801e5
Limit the number of roster computations/redraws per second
This reduces CPU time and greatly improve performance with very large
rosters (e.g. >1000 items).
author | Mikael Berthe <mikael@lilotux.net> |
---|---|
date | Sun, 25 Sep 2016 15:07:24 +0200 |
parents | f5402d705f67 |
children | ece02eb9c81d |
comparison
equal
deleted
inserted
replaced
2280:f1eebfdd6db7 | 2281:1bb9002801e5 |
---|---|
26 #include <sys/types.h> | 26 #include <sys/types.h> |
27 #include <sys/wait.h> | 27 #include <sys/wait.h> |
28 #include <glib.h> | 28 #include <glib.h> |
29 #include <config.h> | 29 #include <config.h> |
30 #include <poll.h> | 30 #include <poll.h> |
31 #include <time.h> | |
31 #include <errno.h> | 32 #include <errno.h> |
32 | 33 |
33 #include "caps.h" | 34 #include "caps.h" |
34 #include "screen.h" | 35 #include "screen.h" |
35 #include "settings.h" | 36 #include "settings.h" |
64 #ifdef USE_SIGWINCH | 65 #ifdef USE_SIGWINCH |
65 void sigwinch_resize(void); | 66 void sigwinch_resize(void); |
66 static bool sigwinch; | 67 static bool sigwinch; |
67 #endif | 68 #endif |
68 | 69 |
70 extern int build_buddylist; | |
71 | |
69 static bool terminate_ui; | 72 static bool terminate_ui; |
70 GMainContext *main_context; | 73 GMainContext *main_context; |
74 static guint refresh_timeout_id; | |
71 | 75 |
72 static struct termios *backup_termios; | 76 static struct termios *backup_termios; |
73 | 77 |
74 char *mcabber_version(void) | 78 char *mcabber_version(void) |
75 { | 79 { |
375 static gboolean mcabber_source_dispatch(GSource *source, GSourceFunc callback, | 379 static gboolean mcabber_source_dispatch(GSource *source, GSourceFunc callback, |
376 gpointer udata) { | 380 gpointer udata) { |
377 return keyboard_activity(); | 381 return keyboard_activity(); |
378 } | 382 } |
379 | 383 |
384 static gboolean refresh_timeout_cb(gpointer data) { | |
385 // Only called once, to trigger a refresh if needed | |
386 // so reset ID and return false. | |
387 refresh_timeout_id = 0; | |
388 return FALSE; | |
389 } | |
390 | |
380 static GSourceFuncs mcabber_source_funcs = { | 391 static GSourceFuncs mcabber_source_funcs = { |
381 mcabber_source_prepare, | 392 mcabber_source_prepare, |
382 mcabber_source_check, | 393 mcabber_source_check, |
383 mcabber_source_dispatch, | 394 mcabber_source_dispatch, |
384 NULL, | 395 NULL, |
481 settings_set(SETTINGS_TYPE_OPTION, "password", pwd); | 492 settings_set(SETTINGS_TYPE_OPTION, "password", pwd); |
482 g_free(pwd); | 493 g_free(pwd); |
483 } | 494 } |
484 } | 495 } |
485 | 496 |
497 /* Initialize buddylist update timestamp */ | |
498 struct timespec last_ui_update; | |
499 clock_gettime(CLOCK_MONOTONIC, &last_ui_update); | |
500 | |
486 /* Initialize PGP system | 501 /* Initialize PGP system |
487 We do it before ncurses initialization because we may need to request | 502 We do it before ncurses initialization because we may need to request |
488 a passphrase. */ | 503 a passphrase. */ |
489 if (settings_opt_get_int("pgp")) | 504 if (settings_opt_get_int("pgp")) |
490 main_init_pgp(); | 505 main_init_pgp(); |
553 g_source_attach(mc_source, main_context); | 568 g_source_attach(mc_source, main_context); |
554 | 569 |
555 scr_LogPrint(LPRINT_DEBUG, "Entering into main loop..."); | 570 scr_LogPrint(LPRINT_DEBUG, "Entering into main loop..."); |
556 | 571 |
557 while(!terminate_ui) { | 572 while(!terminate_ui) { |
573 int64_t timediff; | |
574 struct timespec now; | |
575 | |
558 if (g_main_context_iteration(main_context, TRUE) == FALSE) | 576 if (g_main_context_iteration(main_context, TRUE) == FALSE) |
559 keyboard_activity(); | 577 keyboard_activity(); |
560 #ifdef USE_SIGWINCH | 578 #ifdef USE_SIGWINCH |
561 if (sigwinch) { | 579 if (sigwinch) { |
562 sigwinch_resize(); | 580 sigwinch_resize(); |
563 sigwinch = FALSE; | 581 sigwinch = FALSE; |
564 } | 582 } |
565 #endif | 583 #endif |
566 if (update_roster) | 584 |
567 scr_draw_roster(); | 585 // Compute time in ms since last buddylist/screen update |
568 scr_do_update(); | 586 clock_gettime(CLOCK_MONOTONIC, &now); |
587 timediff = (((now.tv_sec - last_ui_update.tv_sec) * 1.0e9) + | |
588 (now.tv_nsec - last_ui_update.tv_nsec)) / 1.0e6; | |
589 | |
590 if (timediff <= 200) { | |
591 // Trigger a timeout in 1s to make sure no refresh will be missed | |
592 if (!refresh_timeout_id) { | |
593 refresh_timeout_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT, | |
594 1, refresh_timeout_cb, NULL, NULL); | |
595 } | |
596 } else if ((build_buddylist || update_roster)) { | |
597 // More than 200ms | |
598 if (build_buddylist || update_roster) { | |
599 if (build_buddylist) { | |
600 buddylist_build(); | |
601 update_roster = TRUE; | |
602 } | |
603 if (update_roster) { | |
604 scr_draw_roster(); | |
605 scr_do_update(); | |
606 last_ui_update = now; | |
607 } | |
608 } else { | |
609 // No roster change; minimum screen update | |
610 update_panels(); | |
611 doupdate(); | |
612 } | |
613 } | |
569 } | 614 } |
570 | 615 |
571 g_source_destroy(mc_source); | 616 g_source_destroy(mc_source); |
572 g_source_unref(mc_source); | 617 g_source_unref(mc_source); |
573 } | 618 } |