Fabian Peter Hammerle 10 жил өмнө
parent
commit
76e2a188fd
4 өөрчлөгдсөн 140 нэмэгдсэн , 1 устгасан
  1. 87 0
      Clock.cpp
  2. 50 0
      Clock.h
  3. 0 1
      MessageList.h
  4. 3 0
      tests/CMakeLists.txt

+ 87 - 0
Clock.cpp

@@ -0,0 +1,87 @@
+#include "Clock.h"
+
+namespace midi {
+
+Clock::Clock()
+    : bpm(60), running(false)
+{
+}
+
+unsigned int Clock::getBpm()
+{
+    bpm_mutex.lock();
+    bpm_type b = bpm;
+    bpm_mutex.unlock();
+    return b;
+}
+
+void Clock::setBpm(bpm_type b)
+{
+    if(b == 0) {
+        throw "bpm may not be 0.";
+    }
+    bpm_mutex.lock();
+    bpm = b;
+    bpm_mutex.unlock();
+}
+
+Clock::duration Clock::getTickInterval()
+{
+    Clock::duration minute = std::chrono::duration_cast<Clock::duration>(
+        std::chrono::minutes(1)
+        );
+    return minute / getBpm();
+}
+
+void Clock::start()
+{
+    if(isRunning()) {
+        throw "already running";
+    }
+    setRunning(true);
+    stopTickThread = false;
+    lastTickTime = time_point(); // epoch
+    tickThread = std::thread(&Clock::run, this);
+}
+
+void Clock::stop()
+{
+    if(!isRunning()) {
+        throw "not running";
+    }
+    tickThread.detach();
+    stopTickThread = true;
+}
+
+bool Clock::isRunning()
+{
+    running_mutex.lock();
+    bool r = running;
+    running_mutex.unlock();
+    return r;
+}
+
+void Clock::tick()
+{
+}
+
+void Clock::run()
+{
+    while(!stopTickThread) {
+        if((now() - lastTickTime) >= getTickInterval()) {
+            lastTickTime = now();
+            tick();
+        }
+        std::this_thread::sleep_for(std::chrono::microseconds(1000));
+    }
+    setRunning(false);
+}
+
+void Clock::setRunning(bool r)
+{
+    running_mutex.lock();
+    running = r;
+    running_mutex.unlock();
+}
+
+};

+ 50 - 0
Clock.h

@@ -0,0 +1,50 @@
+#pragma once
+#include <mutex>
+#include <atomic>
+#include <thread>
+#include <chrono>
+
+#include <iostream>
+
+namespace midi {
+
+class Clock
+{
+    typedef std::chrono::high_resolution_clock clock;
+    typedef clock::time_point time_point;
+    typedef clock::duration duration;
+
+public:
+    typedef unsigned int bpm_type;
+
+private:    
+    bpm_type bpm;
+    std::mutex bpm_mutex;
+    time_point lastTickTime;
+    std::thread tickThread;
+    std::atomic<bool> stopTickThread;
+    bool running;
+    std::mutex running_mutex;
+
+public:
+    Clock();
+    bpm_type getBpm();
+    void setBpm(bpm_type bpm);
+    duration getTickInterval();
+    void start();
+    void stop();
+    bool isRunning();
+    static inline time_point now()
+    {
+        return clock::now();
+    }
+
+protected:
+    virtual void tick();
+
+private: 
+    void run();
+    void setRunning(bool running);
+};
+
+} // namespace

+ 0 - 1
MessageList.h

@@ -1,7 +1,6 @@
 #pragma once
 #include <list>
 #include <memory>
-#include <list>
 #include "Message.h"
 
 namespace midi {

+ 3 - 0
tests/CMakeLists.txt

@@ -15,3 +15,6 @@ target_link_libraries(launchpad midi)
 
 add_executable(launchpad-screen launchpad-screen.cpp)
 target_link_libraries(launchpad-screen midi) 
+
+add_executable(clock clock.cpp)
+target_link_libraries(clock midi)