From bcc04892148c7396e638f45e96fcba42d0034ec7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 17 Oct 2013 16:32:44 -0500 Subject: refactor the timezone and current time provider into a gobject Interface 'IndicatorDatetimeClock' --- src/clock.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 src/clock.c (limited to 'src/clock.c') diff --git a/src/clock.c b/src/clock.c new file mode 100644 index 0000000..1abdd21 --- /dev/null +++ b/src/clock.c @@ -0,0 +1,110 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "clock.h" + +enum +{ + SIGNAL_CHANGED, + SIGNAL_LAST +}; + +static guint signals[SIGNAL_LAST] = { 0 }; + +G_DEFINE_INTERFACE (IndicatorDatetimeClock, + indicator_datetime_clock, + 0); + +static void +indicator_datetime_clock_default_init (IndicatorDatetimeClockInterface * klass) +{ + signals[SIGNAL_CHANGED] = g_signal_new ( + "changed", + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorDatetimeClockInterface, changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); +} + +/*** +**** PUBLIC API +***/ + +/** + * Get a strv of timezones. + * + * Return value: (element-type char*) + * (transfer full): + * array of timezone strings + */ +gchar ** +indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * self) +{ + gchar ** timezones; + IndicatorDatetimeClockInterface * iface; + + g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); + iface = INDICATOR_DATETIME_CLOCK_GET_INTERFACE(self); + + if (iface->get_timezones != NULL) + timezones = iface->get_timezones (self); + else + timezones = NULL; + + return timezones; +} + +/** + * Get the current time. + * + * Return value: (element-type GDateTime*) + * (transfer full): + * the current time. + */ +GDateTime * +indicator_datetime_clock_get_current_time (IndicatorDatetimeClock * self) +{ + GDateTime * now; + IndicatorDatetimeClockInterface * iface; + + g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); + iface = INDICATOR_DATETIME_CLOCK_GET_INTERFACE(self); + + if (iface->get_current_time != NULL) + now = iface->get_current_time (self); + else + now = NULL; + + return now; +} + +/** + * Emits the "changed" signal. + * + * This should only be called by subclasses. + */ +void +indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * self) +{ + g_return_if_fail (INDICATOR_IS_DATETIME_CLOCK (self)); + + g_signal_emit (self, signals[SIGNAL_CHANGED], 0, NULL); +} -- cgit v1.2.3 From 758a4880f645242f1c7753990dc46f880a7e9de8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 17 Oct 2013 17:48:06 -0500 Subject: cleanup: dead code removal, fix comments, smaller implementation of update_internal_localtime() --- src/clock-live.c | 47 ++++++++++++++--------------------------------- src/clock.c | 6 +++--- src/clock.h | 4 ++-- src/main.c | 6 ++++-- src/service.c | 2 +- 5 files changed, 24 insertions(+), 41 deletions(-) (limited to 'src/clock.c') diff --git a/src/clock-live.c b/src/clock-live.c index 6e694ed..564d990 100644 --- a/src/clock-live.c +++ b/src/clock-live.c @@ -35,7 +35,7 @@ struct _IndicatorDatetimeClockLivePriv { GSettings * settings; - /* cached GTimeZone for use by indicator_datetime_service_get_localtime() */ + /* cached GTimeZone for use by get_localtime() */ GTimeZone * internal_timezone; IndicatorDatetimeTimezone * tz_file; @@ -58,39 +58,10 @@ G_DEFINE_TYPE_WITH_CODE ( G_IMPLEMENT_INTERFACE (INDICATOR_TYPE_DATETIME_CLOCK, indicator_datetime_clock_interface_init)); -/*** -**** Convenience func -***/ - -#if 0 -static void -emit_changed (IndicatorDatetimeClockLive * self) -{ - indicator_datetime_clock_emit_changed (INDICATOR_DATETIME_CLOCK (self)); -} -#endif - /*** **** Timezones ***/ -static void -update_internal_timezone (IndicatorDatetimeClockLive * self) -{ - priv_t * p = self->priv; - const char * id; - - /* find the id from tz_file or tz_geoclue if possible; NULL otherwise */ - id = NULL; - if (p->tz_file != NULL ) - id = indicator_datetime_timezone_get_timezone (p->tz_file); - if (!id && p->tz_geoclue) - id = indicator_datetime_timezone_get_timezone (p->tz_geoclue); - - g_clear_pointer (&p->internal_timezone, g_time_zone_unref); - p->internal_timezone = g_time_zone_new (id); -} - static void on_current_timezone_changed (IndicatorDatetimeClockLive * self) { @@ -159,7 +130,7 @@ on_detect_location_changed (IndicatorDatetimeClockLive * self) ***/ static gchar ** -my_get_timezones (IndicatorDatetimeClock * clock G_GNUC_UNUSED) +my_get_timezones (IndicatorDatetimeClock * clock) { IndicatorDatetimeClockLive * self; priv_t * p; @@ -197,8 +168,18 @@ my_get_timezones (IndicatorDatetimeClock * clock G_GNUC_UNUSED) return timezones; } +static void +update_internal_timezone (IndicatorDatetimeClockLive * self) +{ + priv_t * p = self->priv; + gchar ** timezones = my_get_timezones (INDICATOR_DATETIME_CLOCK (self)); + g_clear_pointer (&p->internal_timezone, g_time_zone_unref); + p->internal_timezone = g_time_zone_new (timezones ? timezones[0] : NULL); + g_strfreev (timezones); +} + static GDateTime * -my_get_current_time (IndicatorDatetimeClock * clock) +my_get_localtime (IndicatorDatetimeClock * clock) { IndicatorDatetimeClockLive * self; priv_t * p; @@ -271,8 +252,8 @@ indicator_datetime_clock_live_class_init (IndicatorDatetimeClockLiveClass * klas static void indicator_datetime_clock_interface_init (IndicatorDatetimeClockInterface * iface) { + iface->get_localtime = my_get_localtime; iface->get_timezones = my_get_timezones; - iface->get_current_time = my_get_current_time; } static void diff --git a/src/clock.c b/src/clock.c index 1abdd21..a5cefee 100644 --- a/src/clock.c +++ b/src/clock.c @@ -80,7 +80,7 @@ indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * self) * the current time. */ GDateTime * -indicator_datetime_clock_get_current_time (IndicatorDatetimeClock * self) +indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * self) { GDateTime * now; IndicatorDatetimeClockInterface * iface; @@ -88,8 +88,8 @@ indicator_datetime_clock_get_current_time (IndicatorDatetimeClock * self) g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); iface = INDICATOR_DATETIME_CLOCK_GET_INTERFACE(self); - if (iface->get_current_time != NULL) - now = iface->get_current_time (self); + if (iface->get_localtime != NULL) + now = iface->get_localtime (self); else now = NULL; diff --git a/src/clock.h b/src/clock.h index 8932895..0c10dab 100644 --- a/src/clock.h +++ b/src/clock.h @@ -55,7 +55,7 @@ struct _IndicatorDatetimeClockInterface /* virtual functions */ gchar** (*get_timezones) (IndicatorDatetimeClock * self); - GDateTime* (*get_current_time) (IndicatorDatetimeClock * self); + GDateTime* (*get_localtime) (IndicatorDatetimeClock * self); }; GType indicator_datetime_clock_get_type (void); @@ -66,7 +66,7 @@ GType indicator_datetime_clock_get_type (void); gchar ** indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * clock); -GDateTime * indicator_datetime_clock_get_current_time (IndicatorDatetimeClock * clock); +GDateTime * indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * clock); void indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * clock); diff --git a/src/main.c b/src/main.c index 9305794..dc08419 100644 --- a/src/main.c +++ b/src/main.c @@ -59,17 +59,19 @@ main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) if (!notify_init ("indicator-datetime-service")) g_critical ("libnotify initialization failed"); - /* run */ + /* create the service */ clock = indicator_datetime_clock_live_new (); planner = indicator_datetime_planner_eds_new (); service = indicator_datetime_service_new (clock, planner); + + /* run */ loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_DATETIME_SERVICE_SIGNAL_NAME_LOST, G_CALLBACK(on_name_lost), loop); g_main_loop_run (loop); + g_main_loop_unref (loop); /* cleanup */ - g_main_loop_unref (loop); g_object_unref (service); g_object_unref (planner); g_object_unref (clock); diff --git a/src/service.c b/src/service.c index b777b8c..f2b0b34 100644 --- a/src/service.c +++ b/src/service.c @@ -166,7 +166,7 @@ indicator_clear_timer (guint * tag) static inline GDateTime * indicator_datetime_service_get_localtime (IndicatorDatetimeService * self) { - return indicator_datetime_clock_get_current_time (self->priv->clock); + return indicator_datetime_clock_get_localtime (self->priv->clock); } /*** -- cgit v1.2.3 From 1a898e4eada6f50bd6f3e3b227d1ab0e143ec06d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 17 Oct 2013 18:15:33 -0500 Subject: cache the timezone strv; lazy-rebuilding it when needed --- src/clock-live.c | 54 +++++++++++++++++++++++------------------------------- src/clock.c | 4 ++-- src/clock.h | 8 ++++---- src/service.c | 3 +-- 4 files changed, 30 insertions(+), 39 deletions(-) (limited to 'src/clock.c') diff --git a/src/clock-live.c b/src/clock-live.c index 564d990..a5e42ec 100644 --- a/src/clock-live.c +++ b/src/clock-live.c @@ -35,11 +35,9 @@ struct _IndicatorDatetimeClockLivePriv { GSettings * settings; - /* cached GTimeZone for use by get_localtime() */ - GTimeZone * internal_timezone; - IndicatorDatetimeTimezone * tz_file; IndicatorDatetimeTimezone * tz_geoclue; + gchar ** timezones; }; typedef IndicatorDatetimeClockLivePriv priv_t; @@ -65,6 +63,8 @@ G_DEFINE_TYPE_WITH_CODE ( static void on_current_timezone_changed (IndicatorDatetimeClockLive * self) { + g_clear_pointer (&self->priv->timezones, g_strfreev); + indicator_datetime_clock_emit_changed (INDICATOR_DATETIME_CLOCK (self)); } @@ -129,18 +129,15 @@ on_detect_location_changed (IndicatorDatetimeClockLive * self) **** IndicatorDatetimeClock virtual functions ***/ -static gchar ** -my_get_timezones (IndicatorDatetimeClock * clock) +static void +rebuild_timezone_strv (IndicatorDatetimeClockLive * self) { - IndicatorDatetimeClockLive * self; priv_t * p; GHashTable * hash; - gchar ** timezones; int i; GHashTableIter iter; gpointer key; - self = INDICATOR_DATETIME_CLOCK_LIVE (clock); p = self->priv; hash = g_hash_table_new (g_str_hash, g_str_equal); @@ -159,38 +156,35 @@ my_get_timezones (IndicatorDatetimeClock * clock) g_hash_table_add (hash, (gpointer) tz); } - timezones = g_new0 (gchar*, g_hash_table_size(hash) + 1); + g_strfreev (p->timezones); + p->timezones = g_new0 (gchar*, g_hash_table_size(hash) + 1); i = 0; g_hash_table_iter_init (&iter, hash); while (g_hash_table_iter_next (&iter, &key, NULL)) - timezones[i++] = g_strdup (key); + p->timezones[i++] = g_strdup (key); g_hash_table_unref (hash); - return timezones; } -static void -update_internal_timezone (IndicatorDatetimeClockLive * self) +static const gchar ** +my_get_timezones (IndicatorDatetimeClock * clock) { + IndicatorDatetimeClockLive * self = INDICATOR_DATETIME_CLOCK_LIVE (clock); priv_t * p = self->priv; - gchar ** timezones = my_get_timezones (INDICATOR_DATETIME_CLOCK (self)); - g_clear_pointer (&p->internal_timezone, g_time_zone_unref); - p->internal_timezone = g_time_zone_new (timezones ? timezones[0] : NULL); - g_strfreev (timezones); + + if (p->timezones == NULL) + rebuild_timezone_strv (self); + + return (const gchar **) p->timezones; } static GDateTime * my_get_localtime (IndicatorDatetimeClock * clock) { - IndicatorDatetimeClockLive * self; - priv_t * p; - - self = INDICATOR_DATETIME_CLOCK_LIVE (clock); - p = self->priv; - - if (G_UNLIKELY (p->internal_timezone == NULL)) - update_internal_timezone (self); - - return g_date_time_new_now (p->internal_timezone); + const gchar ** zones = my_get_timezones (clock); + GTimeZone * zone = g_time_zone_new (zones ? zones[0] : NULL); + GDateTime * time = g_date_time_new_now (zone); + g_time_zone_unref (zone); + return time; } /*** @@ -206,8 +200,6 @@ my_dispose (GObject * o) self = INDICATOR_DATETIME_CLOCK_LIVE(o); p = self->priv; - g_clear_pointer (&p->internal_timezone, g_time_zone_unref); - if (p->settings != NULL) { g_signal_handlers_disconnect_by_data (p->settings, self); @@ -222,13 +214,13 @@ my_dispose (GObject * o) static void my_finalize (GObject * o) { -#if 0 IndicatorDatetimeClockLive * self; priv_t * p; self = INDICATOR_DATETIME_CLOCK_LIVE(o); p = self->priv; -#endif + + g_strfreev (p->timezones); G_OBJECT_CLASS (indicator_datetime_clock_live_parent_class)->dispose (o); } diff --git a/src/clock.c b/src/clock.c index a5cefee..adfb0eb 100644 --- a/src/clock.c +++ b/src/clock.c @@ -55,10 +55,10 @@ indicator_datetime_clock_default_init (IndicatorDatetimeClockInterface * klass) * (transfer full): * array of timezone strings */ -gchar ** +const gchar ** indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * self) { - gchar ** timezones; + const gchar ** timezones; IndicatorDatetimeClockInterface * iface; g_return_val_if_fail (INDICATOR_IS_DATETIME_CLOCK(self), NULL); diff --git a/src/clock.h b/src/clock.h index 0c10dab..40cdf1c 100644 --- a/src/clock.h +++ b/src/clock.h @@ -54,7 +54,7 @@ struct _IndicatorDatetimeClockInterface void (*changed) (IndicatorDatetimeClock * self); /* virtual functions */ - gchar** (*get_timezones) (IndicatorDatetimeClock * self); + const gchar** (*get_timezones) (IndicatorDatetimeClock * self); GDateTime* (*get_localtime) (IndicatorDatetimeClock * self); }; @@ -64,11 +64,11 @@ GType indicator_datetime_clock_get_type (void); **** ***/ -gchar ** indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * clock); +const gchar ** indicator_datetime_clock_get_timezones (IndicatorDatetimeClock * clock); -GDateTime * indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * clock); +GDateTime * indicator_datetime_clock_get_localtime (IndicatorDatetimeClock * clock); -void indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * clock); +void indicator_datetime_clock_emit_changed (IndicatorDatetimeClock * clock); G_END_DECLS diff --git a/src/service.c b/src/service.c index f2b0b34..079456c 100644 --- a/src/service.c +++ b/src/service.c @@ -1168,7 +1168,7 @@ create_locations_section (IndicatorDatetimeService * self) GSList * l; GSList * locations = NULL; gchar ** user_locations; - gchar ** detected_timezones; + const gchar ** detected_timezones; priv_t * p = self->priv; GDateTime * now = indicator_datetime_service_get_localtime (self); @@ -1185,7 +1185,6 @@ create_locations_section (IndicatorDatetimeService * self) gchar * name = get_current_zone_name (tz, p->settings); locations = locations_add (locations, tz, name, TRUE); } - g_strfreev (detected_timezones); /* maybe add the user-specified locations */ user_locations = g_settings_get_strv (p->settings, SETTINGS_LOCATIONS_S); -- cgit v1.2.3 From a2f21a1da1b1f467751020b56b04808f5dd00695 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 23 Oct 2013 09:42:49 -0500 Subject: make GObject a prerequisite of the IndicatorDatetimeClock interface. --- src/clock.c | 2 +- src/service.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/clock.c') diff --git a/src/clock.c b/src/clock.c index adfb0eb..2c2fec2 100644 --- a/src/clock.c +++ b/src/clock.c @@ -29,7 +29,7 @@ static guint signals[SIGNAL_LAST] = { 0 }; G_DEFINE_INTERFACE (IndicatorDatetimeClock, indicator_datetime_clock, - 0); + G_TYPE_OBJECT); static void indicator_datetime_clock_default_init (IndicatorDatetimeClockInterface * klass) diff --git a/src/service.c b/src/service.c index cb2ab4f..5fffc11 100644 --- a/src/service.c +++ b/src/service.c @@ -2317,7 +2317,7 @@ indicator_datetime_service_class_init (IndicatorDatetimeServiceClass * klass) properties[PROP_CLOCK] = g_param_spec_object ("clock", "Clock", "The clock", - G_TYPE_OBJECT, + INDICATOR_TYPE_DATETIME_CLOCK, flags); properties[PROP_PLANNER] = g_param_spec_object ("planner", -- cgit v1.2.3