~mitya57/indicator-datetime/lp1502480

« back to all changes in this revision

Viewing changes to src/clock-live.cpp

  • Committer: Charles Kerr
  • Date: 2013-12-18 03:59:43 UTC
  • mto: This revision was merged to the branch mainline in revision 298.
  • Revision ID: charles.kerr@canonical.com-20131218035943-1l7a6popkxt2teez
add clock + tests

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3, as published
 
6
 * by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful, but
 
9
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 
10
 * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
 
11
 * PURPOSE.  See the GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along
 
14
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authors:
 
17
 *   Charles Kerr <charles.kerr@canonical.com>
 
18
 */
 
19
 
 
20
#include <datetime/clock.h>
 
21
 
 
22
namespace unity {
 
23
namespace indicator {
 
24
namespace datetime {
 
25
 
 
26
class LiveClock::Impl
 
27
{
 
28
public:
 
29
 
 
30
    Impl(LiveClock& owner, const std::shared_ptr<Timezones>& tzd):
 
31
        owner_(owner),
 
32
        timezones_(tzd)
 
33
    {
 
34
        if (timezones_)
 
35
        {
 
36
            timezones_->timezone.changed().connect ([this](const std::string& z) {setTimezone(z);});
 
37
            setTimezone(timezones_->timezone.get());
 
38
        }
 
39
 
 
40
        owner_.skewTestIntervalSec.changed().connect([this](unsigned int intervalSec) {setInterval(intervalSec);});
 
41
        setInterval(owner_.skewTestIntervalSec.get());
 
42
    }
 
43
 
 
44
    ~Impl()
 
45
    {
 
46
        clearTimer();
 
47
 
 
48
        g_clear_pointer (&timezone_, g_time_zone_unref);
 
49
    }
 
50
 
 
51
    GDateTime* localtime() const
 
52
    {
 
53
        g_assert (timezone_ != nullptr);
 
54
 
 
55
        return g_date_time_new_now (timezone_);
 
56
    }
 
57
 
 
58
private:
 
59
 
 
60
    void setTimezone (const std::string& str)
 
61
    {
 
62
        g_clear_pointer (&timezone_, g_time_zone_unref);
 
63
        timezone_= g_time_zone_new (str.c_str());
 
64
        owner_.skewDetected();
 
65
    }
 
66
 
 
67
private:
 
68
 
 
69
    void clearTimer()
 
70
    {
 
71
        if (skew_timeout_id_)
 
72
        {
 
73
            g_source_remove(skew_timeout_id_);
 
74
            skew_timeout_id_ = 0;
 
75
        }
 
76
 
 
77
        g_clear_pointer(&prev_datetime_, g_date_time_unref);
 
78
    }
 
79
 
 
80
    void setInterval(unsigned int seconds)
 
81
    {
 
82
        clearTimer();
 
83
 
 
84
        if (seconds > 0)
 
85
        {
 
86
            prev_datetime_ = owner_.localtime();
 
87
            skew_timeout_id_ = g_timeout_add_seconds(seconds, onTimerPulse, this);
 
88
        }
 
89
    }
 
90
 
 
91
    static gboolean onTimerPulse(gpointer gself)
 
92
    {
 
93
        auto self = static_cast<Impl*>(gself);
 
94
 
 
95
        // check to see if too much time passed since the last check */
 
96
        GDateTime * now = self->owner_.localtime();
 
97
        const GTimeSpan diff = g_date_time_difference(now, self->prev_datetime_);
 
98
        const GTimeSpan fuzz = 5;
 
99
        const GTimeSpan max = (self->owner_.skewTestIntervalSec.get() + fuzz) * G_USEC_PER_SEC;
 
100
        if (abs(diff) > max)
 
101
            self->owner_.skewDetected();
 
102
 
 
103
        // update prev_datetime
 
104
        g_clear_pointer(&self->prev_datetime_, g_date_time_unref);
 
105
        self->prev_datetime_ = now;
 
106
 
 
107
        return G_SOURCE_CONTINUE;
 
108
    }
 
109
 
 
110
protected:
 
111
 
 
112
    LiveClock& owner_;
 
113
    GTimeZone * timezone_ = nullptr;
 
114
    std::shared_ptr<Timezones> timezones_;
 
115
 
 
116
    GDateTime * prev_datetime_ = nullptr;
 
117
    unsigned int skew_timeout_id_ = 0;
 
118
    unsigned int sleep_subscription_id_ = 0;
 
119
};
 
120
 
 
121
LiveClock::LiveClock(const std::shared_ptr<Timezones>& tzd):
 
122
  p (new Impl (*this, tzd))
 
123
{
 
124
}
 
125
 
 
126
LiveClock::~LiveClock() =default;
 
127
 
 
128
GDateTime *
 
129
LiveClock::localtime() const
 
130
{
 
131
    return p->localtime();
 
132
}
 
133
 
 
134
} // namespace datetime
 
135
} // namespace indicator
 
136
} // namespace unity
 
137