foxygit / Torlinkc Log in
commits tags

/include/torlinkc/ui/coalescing_notifier.hpp · 1.36 KB

raw
#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