diff --git a/src/client/widgets/sky/sky.c b/src/client/widgets/sky/sky.c index a7abaa6bae40db9fb6a5d3add9ce69985253d05d..2a858a1659e6b45b34ea1069aac743c33621a8a0 100644 --- a/src/client/widgets/sky/sky.c +++ b/src/client/widgets/sky/sky.c @@ -37,14 +37,61 @@ #define SKY_SUN_SIZE 7.0 #define SKY_MOON_SIZE 7.0 +#define SKY_REFRESH_HZ_CAP 30. +#define SKY_REFRESH_AVG_LEN 10. +#define SKY_REFRESH_DUTY_CYCLE 0.8 + #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) G_DEFINE_TYPE_WITH_PRIVATE(Sky, sky, GTK_TYPE_DRAWING_AREA) + static void sky_plot(GtkWidget *w); +static void sky_try_plot(GtkWidget *w) +{ + gdouble elapsed; + + const double n = 1.0 / SKY_REFRESH_AVG_LEN; + const double n1 = SKY_REFRESH_AVG_LEN - 1.0; + + Sky *p; + + + p = SKY(w); + + g_timer_stop(p->cfg->timer); + + elapsed = g_timer_elapsed(p->cfg->timer, NULL); + + if (elapsed > p->cfg->refresh) { + + /* reuse the timer to measure drawing time */ + g_timer_start(p->cfg->timer); + sky_plot(w); + g_timer_stop(p->cfg->timer); + + elapsed = g_timer_elapsed(p->cfg->timer, NULL); + + elapsed /= SKY_REFRESH_DUTY_CYCLE; + + /* adapt refresh rate */ + p->cfg->refresh = (p->cfg->refresh * n1 + elapsed) * n; + + if (p->cfg->refresh < (1.0 / SKY_REFRESH_HZ_CAP)) + p->cfg->refresh = (1.0 / SKY_REFRESH_HZ_CAP); + + + + g_timer_start(p->cfg->timer); + } else { + g_timer_continue(p->cfg->timer); + } +} + + /** * @brief handle connected */ @@ -96,10 +143,15 @@ static void sky_handle_pr_moveto_azel(gpointer instance, p = SKY(data); + + if (p->cfg->tgt.az == az) + if (p->cfg->tgt.el == el) + return; + p->cfg->tgt.az = az; p->cfg->tgt.el = el; - sky_plot(GTK_WIDGET(p)); + sky_try_plot(GTK_WIDGET(p)); } @@ -118,7 +170,7 @@ static void sky_handle_pr_getpos_azel(gpointer instance, struct getpos *pos, p->cfg->pos.az = (gdouble) pos->az_arcsec / 3600.0; p->cfg->pos.el = (gdouble) pos->el_arcsec / 3600.0; - sky_plot(GTK_WIDGET(p)); + sky_try_plot(GTK_WIDGET(p)); } @@ -155,7 +207,7 @@ static void sky_handle_pr_capabilities(gpointer instance, p->cfg->local_hor = g_memdup(c->hor, c->n_hor * sizeof(struct local_horizon)); - sky_plot(GTK_WIDGET(p)); + sky_try_plot(GTK_WIDGET(p)); } @@ -229,7 +281,7 @@ static gboolean sky_update_coord_hor(gpointer data) } - sky_plot(GTK_WIDGET(p)); + sky_try_plot(GTK_WIDGET(p)); return G_SOURCE_CONTINUE; } @@ -1884,7 +1936,7 @@ static void sky_button_reset_time(GtkWidget *widget, GdkEventButton *event) /* reset time offset */ p->cfg->time_off = 0.0; sky_update_coord_hor((gpointer) p); - sky_plot(widget); + sky_try_plot(widget); } @@ -1957,7 +2009,7 @@ static void sky_selection(GtkWidget *widget, GdkEventButton *event) break; } - sky_plot(widget); + sky_try_plot(widget); } /** @@ -2072,7 +2124,7 @@ static gboolean sky_motion_notify_event_cb(GtkWidget *widget, /* redraw with new time */ sky_update_coord_hor((gpointer) p); - sky_plot(widget); + sky_try_plot(widget); } @@ -2091,7 +2143,7 @@ static gboolean sky_motion_notify_event_cb(GtkWidget *widget, if (px * px + py * py > p->cfg->r * p->cfg->r) { p->cfg->mptr.inside = FALSE; - sky_plot(GTK_WIDGET(p)); + sky_try_plot(GTK_WIDGET(p)); goto cleanup; } @@ -2158,7 +2210,7 @@ static gboolean sky_configure_event_cb(GtkWidget *w, width, height); sky_update_coord_hor((gpointer) p); - sky_plot(w); + sky_try_plot(w); exit: return TRUE; @@ -2183,6 +2235,8 @@ static gboolean sky_destroy(GtkWidget *w, void *data) g_signal_handler_disconnect(sig_get_instance(), p->cfg->id_trk); g_signal_handler_disconnect(sig_get_instance(), p->cfg->id_con); + g_timer_destroy(p->cfg->timer); + return TRUE; } @@ -2226,6 +2280,10 @@ static void sky_init(Sky *p) p->cfg->tgt.el = -90.0; /* do not draw target position on init */ + + p->cfg->timer = g_timer_new(); + p->cfg->refresh = 1.0 / SKY_REFRESH_HZ_CAP; + sky_load_config(p); /* add sun/moon objects, their coordinates are updated automatically */ diff --git a/src/client/widgets/sky/sky_cfg.h b/src/client/widgets/sky/sky_cfg.h index 118309390e8b9e45d43e215ab2df9bc98757a690..91a01d9b012322fb82607a3ac7a367b8d5bd4f4d 100644 --- a/src/client/widgets/sky/sky_cfg.h +++ b/src/client/widgets/sky/sky_cfg.h @@ -45,6 +45,9 @@ struct _SkyConfig { GList *obj; /* list of sky objects */ + GTimer *timer; + gdouble refresh; + struct { /* reset button */ gdouble x0, x1; gdouble y0, y1;