diff options
author | Charles Kerr <charles.kerr@canonical.com> | 2015-04-03 13:11:39 -0500 |
---|---|---|
committer | Charles Kerr <charles.kerr@canonical.com> | 2015-04-03 13:11:39 -0500 |
commit | 8c7daeeb87abd0be1b96169da18baf018c4859c9 (patch) | |
tree | dbcceb67a1cda0ef293394948f358f2b06063dd4 /src | |
parent | 6e4367c088eb9026f29295c650f8639e09423212 (diff) | |
download | ayatana-indicator-datetime-8c7daeeb87abd0be1b96169da18baf018c4859c9.tar.gz ayatana-indicator-datetime-8c7daeeb87abd0be1b96169da18baf018c4859c9.tar.bz2 ayatana-indicator-datetime-8c7daeeb87abd0be1b96169da18baf018c4859c9.zip |
add the new Alarm class as an argument to the alarm queue class
Diffstat (limited to 'src')
-rw-r--r-- | src/alarm-queue-simple.cpp | 226 | ||||
-rw-r--r-- | src/date-time.cpp | 10 | ||||
-rw-r--r-- | src/main.cpp | 8 | ||||
-rw-r--r-- | src/planner-snooze.cpp | 16 |
4 files changed, 157 insertions, 103 deletions
diff --git a/src/alarm-queue-simple.cpp b/src/alarm-queue-simple.cpp index f45e61a..db0fd21 100644 --- a/src/alarm-queue-simple.cpp +++ b/src/alarm-queue-simple.cpp @@ -20,134 +20,174 @@ #include <datetime/alarm-queue-simple.h> #include <cmath> +#include <set> namespace unity { namespace indicator { namespace datetime { /*** -**** Public API +**** ***/ -SimpleAlarmQueue::SimpleAlarmQueue(const std::shared_ptr<Clock>& clock, - const std::shared_ptr<Planner>& planner, - const std::shared_ptr<WakeupTimer>& timer): - m_clock(clock), - m_planner(planner), - m_timer(timer), - m_datetime(clock->localtime()) +class SimpleAlarmQueue::Impl { - m_planner->appointments().changed().connect([this](const std::vector<Appointment>&){ - g_debug("AlarmQueue %p calling requeue() due to appointments changed", this); - requeue(); - }); - - m_clock->minute_changed.connect([=]{ - const auto now = m_clock->localtime(); - constexpr auto skew_threshold_usec = int64_t{90} * G_USEC_PER_SEC; - const bool clock_jumped = std::abs(now - m_datetime) > skew_threshold_usec; - m_datetime = now; - if (clock_jumped) { - g_debug("AlarmQueue %p calling requeue() due to clock skew", this); +public: + + Impl(const std::shared_ptr<Clock>& clock, + const std::shared_ptr<Planner>& planner, + const std::shared_ptr<WakeupTimer>& timer): + m_clock{clock}, + m_planner{planner}, + m_timer{timer}, + m_datetime{clock->localtime()} + { + m_planner->appointments().changed().connect([this](const std::vector<Appointment>&){ + g_debug("AlarmQueue %p calling requeue() due to appointments changed", this); requeue(); - } - }); + }); + + m_clock->minute_changed.connect([=]{ + const auto now = m_clock->localtime(); + constexpr auto skew_threshold_usec = int64_t{90} * G_USEC_PER_SEC; + const bool clock_jumped = std::abs(now - m_datetime) > skew_threshold_usec; + m_datetime = now; + if (clock_jumped) { + g_debug("AlarmQueue %p calling requeue() due to clock skew", this); + requeue(); + } + }); + + m_timer->timeout().connect([this](){ + g_debug("AlarmQueue %p calling requeue() due to timeout", this); + requeue(); + }); - m_timer->timeout().connect([this](){ - g_debug("AlarmQueue %p calling requeue() due to timeout", this); requeue(); - }); - - requeue(); -} + } -SimpleAlarmQueue::~SimpleAlarmQueue() -{ -} + ~Impl() + { + } -core::Signal<const Appointment&>& SimpleAlarmQueue::alarm_reached() -{ - return m_alarm_reached; -} + core::Signal<const Appointment&, const Alarm&>& alarm_reached() + { + return m_alarm_reached; + } -/*** -**** -***/ +private: -void SimpleAlarmQueue::requeue() -{ - // kick any current alarms - for (auto current : find_current_alarms()) + void requeue() { - const std::pair<std::string,DateTime> trig {current.uid, current.begin}; - m_triggered.insert(trig); - m_alarm_reached(current); + // kick any current alarms + for (const auto& appointment : m_planner->appointments().get()) + { + Alarm alarm; + if (appointment_get_current_alarm(appointment, alarm)) + { + m_triggered.insert(std::make_pair(appointment.uid, alarm.time)); + m_alarm_reached(appointment, alarm); + } + } + + // idle until the next alarm + Alarm next; + if (find_next_alarm(next)) + { + g_debug ("setting timer to wake up for next appointment '%s' at %s", + next.text.c_str(), + next.time.format("%F %T").c_str()); + + m_timer->set_wakeup_time(next.time); + } } - // idle until the next alarm - Appointment next; - if (find_next_alarm(next)) + // find the next alarm that will kick now or in the future + bool find_next_alarm(Alarm& setme) const { - g_debug ("setting timer to wake up for next appointment '%s' at %s", - next.summary.c_str(), - next.begin.format("%F %T").c_str()); + bool found = false; + Alarm best; + const auto now = m_clock->localtime(); + const auto beginning_of_minute = now.start_of_minute(); - m_timer->set_wakeup_time(next.begin); - } -} + const auto appointments = m_planner->appointments().get(); + g_debug ("planner has %zu appointments in it", (size_t)appointments.size()); -// find the next alarm that will kick now or in the future -bool SimpleAlarmQueue::find_next_alarm(Appointment& setme) const -{ - bool found = false; - Appointment tmp; - const auto now = m_clock->localtime(); - const auto beginning_of_minute = now.start_of_minute(); + for(const auto& appointment : appointments) + { + for(const auto& alarm : appointment.alarms) + { + const std::pair<std::string,DateTime> trig{appointment.uid, alarm.time}; + if (m_triggered.count(trig)) + continue; - const auto appointments = m_planner->appointments().get(); - g_debug ("planner has %zu appointments in it", (size_t)appointments.size()); + if (alarm.time < beginning_of_minute) // has this one already passed? + continue; - for(const auto& walk : appointments) - { - const std::pair<std::string,DateTime> trig {walk.uid, walk.begin}; - if (m_triggered.count(trig)) - continue; + if (found && (best.time < alarm.time)) // do we already have a better match? + continue; - if (walk.begin < beginning_of_minute) // has this one already passed? - continue; + best = alarm; + found = true; + } + } - if (found && (tmp.begin < walk.begin)) // do we already have a better match? - continue; + if (found) + setme = best; - tmp = walk; - found = true; + return found; } - if (found) - setme = tmp; - return found; -} + bool appointment_get_current_alarm(const Appointment& appointment, Alarm& setme) const + { + const auto now = m_clock->localtime(); -// find the alarm(s) that should kick right now -std::vector<Appointment> SimpleAlarmQueue::find_current_alarms() const -{ - std::vector<Appointment> appointments; + for (const auto& alarm : appointment.alarms) + { + const auto trig = std::make_pair(appointment.uid, alarm.time); + if (m_triggered.count(trig)) // did we already use this one? + continue; + + if (DateTime::is_same_minute(now, alarm.time)) + { + setme = alarm; + return true; + } + } - const auto now = m_clock->localtime(); + return false; + } - for(const auto& walk : m_planner->appointments().get()) - { - const std::pair<std::string,DateTime> trig {walk.uid, walk.begin}; - if (m_triggered.count(trig)) // did we already use this one? - continue; - if (!DateTime::is_same_minute(now, walk.begin)) - continue; - appointments.push_back(walk); - } + std::set<std::pair<std::string,DateTime>> m_triggered; + const std::shared_ptr<Clock> m_clock; + const std::shared_ptr<Planner> m_planner; + const std::shared_ptr<WakeupTimer> m_timer; + core::Signal<const Appointment&, const Alarm&> m_alarm_reached; + DateTime m_datetime; +}; + +/*** +**** Public API +***/ + - return appointments; +SimpleAlarmQueue::SimpleAlarmQueue(const std::shared_ptr<Clock>& clock, + const std::shared_ptr<Planner>& planner, + const std::shared_ptr<WakeupTimer>& timer): + impl{new Impl{clock, planner, timer}} +{ +} + +SimpleAlarmQueue::~SimpleAlarmQueue() +{ +} + +core::Signal<const Appointment&, const Alarm&>& +SimpleAlarmQueue::alarm_reached() +{ + return impl->alarm_reached(); } /*** diff --git a/src/date-time.cpp b/src/date-time.cpp index 689688c..ecfc971 100644 --- a/src/date-time.cpp +++ b/src/date-time.cpp @@ -55,6 +55,16 @@ DateTime& DateTime::operator=(const DateTime& that) return *this; } +DateTime& DateTime::operator+=(const std::chrono::minutes& minutes) +{ + return (*this = add_full(0, 0, 0, 0, minutes.count(), 0)); +} + +DateTime& DateTime::operator+=(const std::chrono::seconds& seconds) +{ + return (*this = add_full(0, 0, 0, 0, 0, seconds.count())); +} + DateTime::DateTime(time_t t) { auto gtz = g_time_zone_new_local(); diff --git a/src/main.cpp b/src/main.cpp index 38e5caa..907d49f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -138,11 +138,11 @@ main(int /*argc*/, char** /*argv*/) auto notification_engine = std::make_shared<uin::Engine>("indicator-datetime-service"); std::unique_ptr<Snap> snap (new Snap(notification_engine, state->settings)); auto alarm_queue = create_simple_alarm_queue(state->clock, snooze_planner, engine, timezone_); - auto on_snooze = [snooze_planner](const Appointment& appointment, const Alarm&) {snooze_planner->add(appointment);}; + auto on_snooze = [snooze_planner](const Appointment& appointment, const Alarm& alarm) { + snooze_planner->add(appointment, alarm); + }; auto on_ok = [](const Appointment&, const Alarm&){}; - auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment) { -#warning placeholder; next step is to have AlarmQueue pass an appointment and alarm - Alarm alarm; + auto on_alarm_reached = [&engine, &snap, &on_snooze, &on_ok](const Appointment& appointment, const Alarm& alarm) { (*snap)(appointment, alarm, on_snooze, on_ok); engine->disable_ubuntu_alarm(appointment); }; diff --git a/src/planner-snooze.cpp b/src/planner-snooze.cpp index 29d5f06..e4062d2 100644 --- a/src/planner-snooze.cpp +++ b/src/planner-snooze.cpp @@ -51,14 +51,18 @@ public: return m_appointments; } - void add(const Appointment& appt_in) + void add(const Appointment& appt_in, const Alarm& alarm) { + // make a copy of the appointment with only this alarm Appointment appt = appt_in; + appt.alarms.clear(); + appt.alarms.push_back(alarm); // reschedule the alarm to go off N minutes from now - const auto alarm_duration_secs = appt.end - appt.begin; - appt.begin = m_clock->localtime().add_full(0,0,0,0,m_settings->snooze_duration.get(),0); - appt.end = appt.begin.add_full(0,0,0,0,0,alarm_duration_secs); + const auto offset = std::chrono::minutes(m_settings->snooze_duration.get()); + appt.begin += offset; + appt.end += offset; + appt.alarms[0].time += offset; // give it a new ID gchar* uid = e_uid_new(); @@ -95,9 +99,9 @@ SnoozePlanner::~SnoozePlanner() } void -SnoozePlanner::add(const Appointment& appointment) +SnoozePlanner::add(const Appointment& appointment, const Alarm& alarm) { - impl->add(appointment); + impl->add(appointment, alarm); } core::Property<std::vector<Appointment>>& |