#pragma once
#include <chrono>
#include <condition_variable>
#include <functional>
#include <mutex>
#include <thread>
namespace torlinkc::ui {
// Trailing-edge coalescer: the first markDirty() call arms a `window`
// deadline; further calls before the deadline are absorbed (no extra work);
// when the deadline passes, `onFlush` runs exactly once. flushNow() cuts the
// wait short (used when the last of N producers finishes, so a result
// doesn't sit out a window it no longer needs to). Runs its own background
// thread, torn down on destruction.
//
// Ported from the coalescing behavior shared by useConcurrentSearch.ts's
// 150ms result-flush timer and store.ts's 200ms queue-update hooks -- one
// primitive standing in for what were two near-identical debounces in the
// original.
class CoalescingNotifier {
public:
CoalescingNotifier(std::chrono::milliseconds window, std::function<void()> onFlush);
~CoalescingNotifier();
CoalescingNotifier(const CoalescingNotifier&) = delete;
CoalescingNotifier& operator=(const CoalescingNotifier&) = delete;
void markDirty();
void flushNow();
private:
void run();
std::chrono::milliseconds window_;
std::function<void()> onFlush_;
std::mutex mutex_;
std::condition_variable cv_;
bool dirty_ = false;
bool flushRequested_ = false;
bool stop_ = false;
std::thread thread_;
};
} // namespace torlinkc::ui