Skip to content

Commit

Permalink
fixing review comments
Browse files Browse the repository at this point in the history
  • Loading branch information
phyBrackets committed Oct 23, 2023
1 parent 5542197 commit eac6199
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 0 deletions.
40 changes: 40 additions & 0 deletions src/kdbindings/signal.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,46 @@ class Signal
return m_connections.insert({ slot });
}

// Connect a callback function with Throttling
Private::GenerationalIndex connectWithThrottling(std::function<void(Args...)> const &slot, int interval)
{
std::chrono::milliseconds throttleDelay(interval);
auto lastCallTime = std::chrono::high_resolution_clock::now() - throttleDelay; // Initialize so it can be triggered immediately the first time.

auto throttleCallBack = [slot = std::move(slot), throttleDelay, lastCallTime](Args... args) mutable {
auto now = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastCallTime);

if (elapsed.count() >= throttleDelay.count()) {
slot(args...);
lastCallTime = now;
}
};

return m_connections.insert({ throttleCallBack });
}

// Connect a callback function with Debouncing
Private::GenerationalIndex connectWithDebouncing(std::function<void(Args...)> const &slot, int interval)
{
std::chrono::milliseconds debounceDelay(interval);
auto lastEventTime = std::chrono::high_resolution_clock::now();
auto lastCallTime = lastEventTime - debounceDelay; // Initialize so it can be triggered immediately the first time.

auto debounceCallBack = [slot = std::move(slot), debounceDelay, lastEventTime, lastCallTime](Args... args) mutable {
auto now = std::chrono::high_resolution_clock::now();
lastEventTime = now;

auto timeSinceLastCall = std::chrono::duration_cast<std::chrono::milliseconds>(now - lastCallTime);
if (timeSinceLastCall.count() >= debounceDelay.count()) {
slot(args...);
lastCallTime = now;
}
};

return m_connections.insert({ debounceCallBack });
}

// Disconnects a previously connected function
void disconnect(const Private::GenerationalIndex &id) override
{
Expand Down
42 changes: 42 additions & 0 deletions tests/signal/tst_signal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,48 @@ TEST_CASE("Signal connections")
REQUIRE(lambdaCalled == true);
}

SUBCASE("Test connectWithThrottling")
{
Signal<int> signal;

int count = 0;
auto handle = signal.connectWithThrottling([&count](int value) {
count++;
},
100);

signal.emit(2);
REQUIRE(count == 1); // First emission should trigger the slot immediately

std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Within the throttling interval
signal.emit(2);
REQUIRE(count == 1); // Second emission shouldn't trigger the slot due to throttling

std::this_thread::sleep_for(std::chrono::milliseconds(100)); // After the throttling interval
signal.emit(2);
REQUIRE(count == 2); // Third emission should trigger the slot
}
SUBCASE("Test connectWithDebouncing")
{
Signal<int> signal;
int count = 0;
auto handle = signal.connectWithDebouncing([&count](int value) {
count++;
},
100);

signal.emit(1);
REQUIRE(count == 1); // Debouncing interval hasn't passed

std::this_thread::sleep_for(std::chrono::milliseconds(50)); // Still within the debouncing interval
signal.emit(2);
REQUIRE(count == 1); // Debouncing interval still hasn't passed

std::this_thread::sleep_for(std::chrono::milliseconds(50)); // After the debouncing interval
signal.emit(2);
REQUIRE(count == 2);
}

SUBCASE("A signal with arguments can be connected to a lambda and invoked with const l-value args")
{
Signal<std::string, int> signal;
Expand Down

0 comments on commit eac6199

Please sign in to comment.