A simple example of using synkronize
's timepoint generator
is performing a version check every now and then according to user preferences.
This example checks every month, week or day for a new version of some fact of your choice.
The actual version check and handling of preferences is irrelevant; the main focus is on the simplicity of using the timepoint generator, whose resulting timepoints are fed into a threadpool timer.
namespace fd { // fwd decl timepoint generator class schedule_timepiece; } // window of some description class MyTrayWindow : public ATL::CWindowImpl<MyTrayWindow, ATL::CWindow, ATL::CWinTraits<WS_OVERLAPPED>> { private: // this method gets called initially or on changing settings/preferences void SetupVersionCheck(); void ScheduleNextVersionCheck(); private: // version checker of some description fd_version_checker vchecker_; // the timepoint generator std::unique_ptr<fd::schedule_timepiece> vscheduler_; // threadpool timer of some description threadpool_periodic_timer vtimer_; };
#include <fd/interval_schedule_data.h> #include <fd/schedule_timepiece.h> using namespace fd; void MyTrayWindow::SetupVersionCheck() { // grab read-only program settings/preferences const auto prefs = globalRoSettings->SharedData(); if (prefs->vcheckInterval == MySettingsStore::VCheckOff) { vtimer_.cancel(); vscheduler_ = nullptr; return; } // prepare schedule definition interval_schedule_data sd { prefs->vcheckInterval == MySettingsStore::VCheckMonthly ? month_interval : prefs->vcheckInterval == MySettingsStore::VCheckWeekly ? week_interval : day_interval }; // create and initialize timepoint generator from schedule definition vscheduler_ = std::make_unique<schedule_timepiece> ( sd, // first version check should trigger immediately (rewind), // changing settings should trigger now or next (adjacent) vscheduler_ ? timepiece_move::to_adjacent : timepiece_move::rewind ); // extract generated timepoint as unix timestamp std::chrono::seconds next = currently_scheduled_at__s(*vscheduler_); // feed timepoint to threadpool timer vtimer_.restart(next, winapi_milliseconds::zero(), [this]() { // might get called any time, retrieve window handle once and check if (ATL::CWindow wnd = m_hWnd) // message handler method will call MyTrayWindow::ScheduleNextVersionCheck() wnd.PostMessage(CheckVersion); }); } void MyTrayWindow::ScheduleNextVersionCheck() { auto checkResult = vchecker_.check_result(); // not up-to-date -> no need to check anymore if (checkResult->checkState == fd_version_check_state::already_checked && !checkResult->isUpToDate) return; // advance to next timepoint and extract generated timepoint as unix timestamp std::chrono::seconds next = advance__s(*vscheduler_, timepiece_move::to_adjacent); // feed timepoint to threadpool timer vtimer_.restart(next, winapi_milliseconds::zero(), [this]() { // might get called any time, retrieve window handle once and check if (ATL::CWindow wnd = m_hWnd) // message handler method will call MyTrayWindow::ScheduleNextVersionCheck() wnd.PostMessage(CheckVersion); }); }