|
|
@@ -0,0 +1,74 @@
|
|
|
+#include "MetronomeImpl.h"
|
|
|
+#include "Trigger.h"
|
|
|
+
|
|
|
+
|
|
|
+namespace Timer {
|
|
|
+
|
|
|
+MetronomeImpl::MetronomeImpl(Metronome::Quantity::type quantity, int amount) :
|
|
|
+ m_work(m_ioService),
|
|
|
+ m_timer(m_ioService),
|
|
|
+ m_quantity(quantity),
|
|
|
+ m_amount(amount)
|
|
|
+{
|
|
|
+ m_thread = std::thread([&] { m_ioService.run(); });
|
|
|
+
|
|
|
+#ifdef __linux__
|
|
|
+ pthread_setname_np(m_thread.native_handle(), "Metronome");
|
|
|
+#endif
|
|
|
+
|
|
|
+ SetTimer();
|
|
|
+}
|
|
|
+
|
|
|
+MetronomeImpl::~MetronomeImpl()
|
|
|
+{
|
|
|
+ m_ioService.stop();
|
|
|
+ m_thread.join();
|
|
|
+}
|
|
|
+
|
|
|
+size_t MetronomeImpl::Connect(std::function<void()> function)
|
|
|
+{
|
|
|
+ return m_signal.connect(function);
|
|
|
+}
|
|
|
+
|
|
|
+void MetronomeImpl::SetTimer()
|
|
|
+{
|
|
|
+ m_timer.expires_at(GetTimePoint());
|
|
|
+ CheckDeadline(asio::error_code());
|
|
|
+}
|
|
|
+
|
|
|
+asio::system_timer::time_point MetronomeImpl::GetTimePoint()
|
|
|
+{
|
|
|
+ switch (m_quantity)
|
|
|
+ {
|
|
|
+ case Metronome::Quantity::Hours:
|
|
|
+ return Trigger::HoursMultitude(m_amount);
|
|
|
+ case Metronome::Quantity::Minutes:
|
|
|
+ return Trigger::MinutesMultitude(m_amount);
|
|
|
+ case Metronome::Quantity::Seconds:
|
|
|
+ return Trigger::SecondsMultitude(m_amount);
|
|
|
+ default:
|
|
|
+ return asio::system_timer::time_point();
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void MetronomeImpl::Trigger()
|
|
|
+{
|
|
|
+ m_signal.emit();
|
|
|
+ SetTimer();
|
|
|
+}
|
|
|
+
|
|
|
+void MetronomeImpl::CheckDeadline(const asio::error_code& ec)
|
|
|
+{
|
|
|
+ if (ec != asio::error::operation_aborted)
|
|
|
+ {
|
|
|
+ if (m_timer.expires_at() <= std::chrono::system_clock::now())
|
|
|
+ {
|
|
|
+ Trigger();
|
|
|
+ SetTimer();
|
|
|
+ }
|
|
|
+
|
|
|
+ m_timer.async_wait(std::bind(&MetronomeImpl::CheckDeadline, this, std::placeholders::_1));
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+} // namespace Timer
|