diff --git a/Bluetooth/Device.cpp b/Bluetooth/Device.cpp index 5a6f00b..4720ec7 100644 --- a/Bluetooth/Device.cpp +++ b/Bluetooth/Device.cpp @@ -21,7 +21,7 @@ Device::~Device() void Device::Start() { - m_timer.Start(10000, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); + m_timer.StartContinuous(10000, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); } void Device::Stop() diff --git a/UniFi/Device.cpp b/UniFi/Device.cpp index a14eb27..6f63e39 100644 --- a/UniFi/Device.cpp +++ b/UniFi/Device.cpp @@ -27,7 +27,7 @@ Device::~Device() void Device::Start() { - m_timer.Start(5000, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); + m_timer.StartContinuous(5000, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); } void Device::Stop() diff --git a/Util/Helpers.h b/Util/Helpers.h new file mode 100644 index 0000000..a062611 --- /dev/null +++ b/Util/Helpers.h @@ -0,0 +1,36 @@ +#ifndef UTIL_HELPERS_H +#define UTIL_HELPERS_H + +#include + + +namespace PresenceDetection { +namespace Util { +namespace Helpers { + +template +struct index {}; + +template +struct gen_seq : gen_seq {}; + +template +struct gen_seq<0, Is...> : index {}; + +template +void execute(std::function const & function, std::tuple& tuple, index) +{ + function(std::get(tuple)...); +} + +template +void execute(std::function const & function, std::tuple& tuple) +{ + execute(function, tuple, gen_seq{}); +} + +} // namespace Helpers +} // namespace Util +} // namespace PresenceDetection + +#endif // UTIL_HELPERS_H diff --git a/Util/Timer.cpp b/Util/Timer.cpp index 06e81e1..2865eb8 100644 --- a/Util/Timer.cpp +++ b/Util/Timer.cpp @@ -17,11 +17,31 @@ Timer::~Timer() Wait(); } +Timer::Timer(Timer&& other) : + m_run(static_cast(other.m_run)), + m_identifier(other.m_identifier), + m_thread(std::move(other.m_thread)) +{ +} + +Timer& Timer::operator=(Timer&& other) +{ + m_run = static_cast(other.m_run); + m_identifier = std::move(other.m_identifier); + m_thread = std::move(other.m_thread); + return *this; +} + bool Timer::operator==(const Timer& other) const { return m_identifier == other.Identifier(); } +bool Timer::operator==(const std::string& identifier) const +{ + return m_identifier == identifier; +} + std::string Timer::Identifier() const { return m_identifier; diff --git a/Util/Timer.h b/Util/Timer.h index fdd8620..9bb491f 100644 --- a/Util/Timer.h +++ b/Util/Timer.h @@ -1,11 +1,10 @@ #ifndef UTIL_TIMER_H #define UTIL_TIMER_H -#include - #include #include #include +#include "Helpers.h" namespace PresenceDetection { @@ -17,32 +16,75 @@ public: Timer(); ~Timer(); + Timer(const Timer&) = delete; + Timer& operator= (const Timer&) = delete; + + Timer(Timer&& other); + Timer& operator= (Timer&& other); + bool operator==(const Timer& other) const; + bool operator==(const std::string& identifier) const; public: std::string Identifier() const; template - void Start(int interval, std::function const & function, Arguments && ...arguments) + void StartSingle(int interval, std::function const & function, Arguments && ...arguments) { - if (m_run.load(std::memory_order_acquire)) - Stop(); + Start(TimerType::Single, interval, function, std::forward(arguments)...); + } - m_run.store(true, std::memory_order_release); - m_thread = std::thread([this, interval, function, &arguments...]() - { - while (m_run.load(std::memory_order_acquire)) - { - function(std::forward(arguments)...); - std::this_thread::sleep_for(std::chrono::milliseconds(interval)); - } - }); + template + void StartContinuous(int interval, std::function const & function, Arguments && ...arguments) + { + Start(TimerType::Continuous, interval, function, std::forward(arguments)...); } void Stop(); bool IsRunning() const noexcept; void Wait(); +private: + class TimerType + { + public: + enum type + { + Unknown, + Single, + Continuous + }; + }; + +private: + template + void Start(TimerType::type type, int interval, std::function const & function, Arguments && ...arguments) + { + if (type == TimerType::Unknown) + return; + + if (m_run.load(std::memory_order_acquire)) + Stop(); + + m_thread = std::thread([this, interval, function, &arguments...]() + { + auto argumentsCopy = std::make_tuple(std::forward(arguments)...); + m_run.store(true, std::memory_order_release); + + while (m_run.load(std::memory_order_acquire)) + { + std::this_thread::sleep_for(std::chrono::milliseconds(interval)); + Helpers::execute(function, argumentsCopy); + if (TimerType::Single) + m_run.store(false, std::memory_order_release); + } + }); + + while (!IsRunning()) + { + } + } + private: std::atomic m_run; std::string m_identifier;