File indexing completed on 2025-01-05 04:55:03
0001 /* 0002 Copyright (c) 2021 Christian Mollekopf <christian@mkpf.ch> 0003 0004 This library is free software; you can redistribute it and/or modify it 0005 under the terms of the GNU Library General Public License as published by 0006 the Free Software Foundation; either version 2 of the License, or (at your 0007 option) any later version. 0008 0009 This library is distributed in the hope that it will be useful, but WITHOUT 0010 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0011 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 0012 License for more details. 0013 0014 You should have received a copy of the GNU Library General Public License 0015 along with this library; see the file COPYING.LIB. If not, write to the 0016 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA. 0018 */ 0019 #pragma once 0020 0021 #include <QTimer> 0022 #include <functional> 0023 0024 /** 0025 * A signal throttler/debouncer 0026 * 0027 * The callback is initially slightly delayed, to debounce multiple calls in quick succession. 0028 * The delay used for this is small to provide responsiveness. Successive calls are then batched into a single callback after mInterval ms. 0029 */ 0030 class Debouncer { 0031 public: 0032 Debouncer(int interval, std::function<void()> callback, QObject *guard) 0033 :mInterval{interval}, 0034 mCallback{callback} 0035 { 0036 mRefreshTimer.setSingleShot(true); 0037 QObject::connect(&mRefreshTimer, &QTimer::timeout, guard, [this] { 0038 //Avoid calling after the timeout if there was no trigger inbetween 0039 if (!mCalledAlready) { 0040 mCallback(); 0041 } 0042 }); 0043 0044 mDelayTimer.setSingleShot(true); 0045 QObject::connect(&mDelayTimer, &QTimer::timeout, guard, [this] { 0046 mCalledAlready = true; 0047 mCallback(); 0048 }); 0049 } 0050 0051 void trigger() { 0052 mCalledAlready = false; 0053 if (!mRefreshTimer.isActive()) { 0054 mRefreshTimer.start(mInterval); 0055 mDelayTimer.start(30); 0056 } 0057 } 0058 0059 private: 0060 int mInterval; 0061 bool mCalledAlready{false}; 0062 QTimer mRefreshTimer; 0063 QTimer mDelayTimer; 0064 std::function<void()> mCallback; 0065 };