Branch data Line data Source code
1 : : /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
2 : : *
3 : : * Copyright © 2018 Endless Mobile, Inc.
4 : : *
5 : : * This library is free software; you can redistribute it and/or
6 : : * modify it under the terms of the GNU Lesser General Public
7 : : * License as published by the Free Software Foundation; either
8 : : * version 2.1 of the License, or (at your option) any later version.
9 : : *
10 : : * This library is distributed in the hope that it will be useful,
11 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 : : * Lesser General Public License for more details.
14 : : *
15 : : * You should have received a copy of the GNU Lesser General Public
16 : : * License along with this library; if not, write to the Free Software
17 : : * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 : : *
19 : : * Authors:
20 : : * - Philip Withnall <withnall@endlessm.com>
21 : : */
22 : :
23 : : #include "config.h"
24 : :
25 : : #include <glib.h>
26 : : #include <glib-object.h>
27 : : #include <glib/gi18n-lib.h>
28 : : #include <gio/gio.h>
29 : : #include <libmogwai-schedule/clock.h>
30 : :
31 : :
32 : : /**
33 : : * SECTION:clock
34 : : * @short_description: Interface to wall clock timing and alarm functionality
35 : : * @stability: Unstable
36 : : * @include: libmogwai-schedule/clock.h
37 : : *
38 : : * #MwsClock is an interface to wall clock timing and alarm functionality, and
39 : : * is provided as an abstraction over the standard system clock functions. By
40 : : * abstracting timing, unit tests can test timing-specific behaviour without
41 : : * having to use multi-hour sleeps or being subject to race conditions.
42 : : *
43 : : * The typical runtime implementation of this interface is #MwsClockSystem,
44 : : * which uses the system clock.
45 : : *
46 : : * A typical test implementation of this interface is #MwsClockDummy, which
47 : : * allows its time and timezone to be controlled by the calling test harness.
48 : : *
49 : : * Since: 0.1.0
50 : : */
51 : :
52 : : /**
53 : : * MwsClock:
54 : : *
55 : : * Interface providing wall clock timing and alarm functionality.
56 : : *
57 : : * Since: 0.1.0
58 : : */
59 : :
60 [ + + + - : 597 : G_DEFINE_INTERFACE (MwsClock, mws_clock, G_TYPE_OBJECT)
+ + ]
61 : :
62 : : static void
63 : 2 : mws_clock_default_init (MwsClockInterface *iface)
64 : : {
65 : : /**
66 : : * MwsClock::offset-changed:
67 : : * @self: a #MwsClock
68 : : *
69 : : * Emitted when the clock offset (timezone, or underlying RTC time) changes,
70 : : * such that any stored offsets from wall clock time need to be recalculated.
71 : : *
72 : : * Since: 0.1.0
73 : : */
74 : 2 : g_signal_new ("offset-changed", G_TYPE_FROM_INTERFACE (iface),
75 : : G_SIGNAL_RUN_LAST,
76 : : 0, NULL, NULL, NULL,
77 : : G_TYPE_NONE, 0);
78 : 2 : }
79 : :
80 : : /**
81 : : * mws_clock_get_now_local:
82 : : * @self: a #MwsClock
83 : : *
84 : : * Get the current time, in the time zone currently in use by the clock (which
85 : : * will typically be the local time zone).
86 : : *
87 : : * Returns: (transfer full): current clock time
88 : : * Since: 0.1.0
89 : : */
90 : : GDateTime *
91 : 168 : mws_clock_get_now_local (MwsClock *self)
92 : : {
93 [ - + ]: 168 : g_return_val_if_fail (MWS_IS_CLOCK (self), NULL);
94 : :
95 : 168 : MwsClockInterface *iface = MWS_CLOCK_GET_IFACE (self);
96 [ - + ]: 168 : g_assert (iface->get_now_local != NULL);
97 : 168 : return iface->get_now_local (self);
98 : : }
99 : :
100 : : /**
101 : : * mws_clock_add_alarm:
102 : : * @self: a #MwsClock
103 : : * @alarm_time: when to trigger the alarm
104 : : * @alarm_func: (nullable): function to invoke when @alarm_time is reached
105 : : * @user_data: (nullable): data to pass to @alarm_func
106 : : * @destroy_func: (nullable): destroy function for @user_data
107 : : *
108 : : * Add an alarm to the clock, which will invoke @alarm_func at the first
109 : : * opportunity after the clock reaches @alarm_time.
110 : : *
111 : : * @user_data will be passed to @alarm_func, and @destroy_func will be used to
112 : : * destroy @user_data afterwards (if both of them are non-%NULL).
113 : : *
114 : : * If @alarm_time is in the past, @alarm_func is guaranteed to be invoked at
115 : : * the first opportunity after the call to mws_clock_add_alarm() returns.
116 : : *
117 : : * Returns: ID of the alarm, valid until the alarm is invoked or removed using
118 : : * mws_clock_remove_alarm()
119 : : * Since: 0.1.0
120 : : */
121 : : guint
122 : 80 : mws_clock_add_alarm (MwsClock *self,
123 : : GDateTime *alarm_time,
124 : : GSourceFunc alarm_func,
125 : : gpointer user_data,
126 : : GDestroyNotify destroy_func)
127 : : {
128 [ - + ]: 80 : g_return_val_if_fail (MWS_IS_CLOCK (self), 0);
129 [ - + ]: 80 : g_return_val_if_fail (alarm_time != NULL, 0);
130 : :
131 : 80 : MwsClockInterface *iface = MWS_CLOCK_GET_IFACE (self);
132 [ - + ]: 80 : g_assert (iface->add_alarm != NULL);
133 : 80 : guint id = iface->add_alarm (self, alarm_time, alarm_func, user_data, destroy_func);
134 [ - + ]: 80 : g_assert (id != 0);
135 : 80 : return id;
136 : : }
137 : :
138 : : /**
139 : : * mws_clock_remove_alarm:
140 : : * @self: a #MwsClock
141 : : * @id: ID of the alarm to remove, as returned by mws_clock_add_alarm()
142 : : *
143 : : * Remove a pending alarm from the clock, using the ID returned by
144 : : * mws_clock_add_alarm() when it was added. @id must be valid and must not be
145 : : * removed more than once.
146 : : *
147 : : * Since: 0.1.0
148 : : */
149 : : void
150 : 0 : mws_clock_remove_alarm (MwsClock *self,
151 : : guint id)
152 : : {
153 [ # # ]: 0 : g_return_if_fail (MWS_IS_CLOCK (self));
154 [ # # ]: 0 : g_return_if_fail (id != 0);
155 : :
156 : 0 : MwsClockInterface *iface = MWS_CLOCK_GET_IFACE (self);
157 [ # # ]: 0 : g_assert (iface->remove_alarm != NULL);
158 : 0 : iface->remove_alarm (self, id);
159 : : }
|