Advertisement
Guest User

Untitled

a guest
Mar 29th, 2017
55
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.44 KB | None | 0 0
  1. #include <atomic>
  2. #include <chrono>
  3. #include <condition_variable>
  4. #include <functional>
  5. #include <mutex>
  6. #include <thread>
  7. #include <utility>
  8.  
  9.  
  10. #include <vector>
  11. template<typename ... Args>
  12. class Signal
  13. {
  14. public:
  15. void connect(std::function<void(Args...)> slot)
  16. {
  17. if(slot) {
  18. m_slots.emplace_back(std::move(slot));
  19. }
  20. }
  21.  
  22. void operator()(Args&&... args)
  23. {
  24. for(const auto& slot: m_slots) {
  25. slot(args...);
  26. }
  27. }
  28.  
  29. private:
  30. std::vector<std::function<void(Args...)>> m_slots;
  31. };
  32.  
  33.  
  34.  
  35.  
  36. class Timer
  37. {
  38. public:
  39. using Interval = std::chrono::milliseconds;
  40. Signal<> timeout;
  41. Signal<> stopped;
  42.  
  43. Timer() = default;
  44. Timer(const Timer&) = delete;
  45. Timer& operator=(const Timer&) = delete;
  46. ~Timer()
  47. {
  48. if(m_isActive) {
  49. // maybe log
  50. this->stop();
  51. }
  52.  
  53. if(m_thread.joinable()){
  54. m_thread.join();
  55. }
  56. }
  57.  
  58. Interval interval() const
  59. {
  60. return m_interval;
  61. }
  62.  
  63. void setInterval(Interval interval)
  64. {
  65. m_interval = interval;
  66. }
  67.  
  68. bool isSingleShot() const
  69. {
  70. return m_isSingleShot;
  71. }
  72.  
  73. void setSingleShot(bool singleShot)
  74. {
  75. m_isSingleShot = singleShot;
  76. }
  77.  
  78. void start(Interval msec)
  79. {
  80. this->setInterval(msec);
  81. this->start();
  82. }
  83.  
  84. void start()
  85. {
  86. if(m_isActive) {
  87. this->stop();
  88. }
  89.  
  90. m_isActive = true;
  91. m_thread = std::thread([this]()
  92. {
  93. while(m_isActive)
  94. {
  95. std::unique_lock<std::mutex> lk(m_mutex);
  96. m_condition.wait_for(lk, m_interval, [this]{ return !m_isActive;});
  97.  
  98. if(m_isActive) // If timer was not stopped prematurely, emit timeout signal
  99. {
  100. timeout();
  101. m_isActive = !m_isSingleShot;
  102. }
  103. }
  104. });
  105. }
  106.  
  107. void stop()
  108. {
  109. if(m_isActive)
  110. {
  111. m_isActive = false;
  112. m_condition.notify_all();
  113. if(m_thread.joinable()){
  114. m_thread.join();
  115. }
  116. stopped();
  117. }
  118. }
  119.  
  120. bool isActive() const
  121. {
  122. return m_isActive;
  123. }
  124.  
  125. private:
  126. std::atomic_bool m_isActive = {false};
  127. std::atomic_bool m_isSingleShot = {false};
  128. std::condition_variable m_condition;
  129. std::mutex m_mutex;
  130. std::thread m_thread;
  131. Interval m_interval;
  132. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement