#include <iostream>
#include <functional>
#include <chrono>
#include <thread>
#include <mutex>
#include <condition_variable>
class Debouncer {
public:
Debouncer(std::chrono::milliseconds debounceTime)
: debounceTime(debounceTime), lastCallTime(std::chrono::steady_clock::now()), active(false) {}
void call(std::function<void()> func) {
std::unique_lock<std::mutex> lock(mutex);
lastCallTime = std::chrono::steady_clock::now();
if (!active) {
active = true;
std::thread([this, func]() {
std::this_thread::sleep_for(debounceTime);
std::unique_lock<std::mutex> lock(mutex);
auto now = std::chrono::steady_clock::now();
if (now - lastCallTime >= debounceTime) {
func();
active = false;
} else {
// Wait for the remaining time and then call the function
std::this_thread::sleep_for(debounceTime - (now - lastCallTime));
func();
active = false;
}
}).detach();
}
}
private:
std::chrono::milliseconds debounceTime;
std::chrono::steady_clock::time_point lastCallTime;
bool active;
std::mutex mutex;
};
// Example usage:
void exampleFunction() {
static int counter = 0;
std::cout << "Function called " << ++counter << std::endl;
}
int main() {
Debouncer debouncer(std::chrono::milliseconds(100));
// Simulating rapid calls
for (int i = 0; i < 32; ++i) {
debouncer.call(exampleFunction);
std::this_thread::sleep_for(std::chrono::milliseconds(30));
}
// Give some time for debouncer to process
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
return 0;
}