#ifndef DEBOUNCE_H #define DEBOUNCE_H #include #include #include "Signal.hh" class Debounce { public: static std::shared_ptr getShared() { static std::weak_ptr sharedInstance; std::shared_ptr shared = sharedInstance.lock(); if (!shared) { shared = std::make_shared(); sharedInstance = shared; } return shared; } Debounce() { mRunning = true; mThread = std::thread([this] () { loop(); }); } ~Debounce() { mRunning = false; mWaitSignal.notify(); mThread.join(); } void add(void *key, std::function cb) { std::unique_lock lock(mMutex); mCallbacks.emplace(key, cb); } void remove(void *key) { std::unique_lock lock(mMutex); mCallbacks.erase(key); } void trigger() { std::unique_lock lock(mMutex); mWaitSignal.notify(); } private: bool mRunning; std::mutex mMutex; Signal mWaitSignal; std::thread mThread; std::unordered_map> mCallbacks; void loop() { while (mRunning) { mWaitSignal.wait(); if (!mRunning) { break; } auto status = mWaitSignal.waitFor(std::chrono::milliseconds(50)); if (status == std::cv_status::timeout && mRunning) { notify(); } } } void notify() { std::unique_lock lock(mMutex); for (auto it = mCallbacks.begin(); it != mCallbacks.end(); it++) { auto cb = it->second; cb(); } mWaitSignal.reset(); } }; #endif