Skip to content

Commit

Permalink
feat: add TimerLimitedRepeating::Start overload to support TriggerImm…
Browse files Browse the repository at this point in the history
…ediately (#760)
  • Loading branch information
daantimmer authored Oct 29, 2024
1 parent 45f2cb4 commit 631ec6c
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 6 deletions.
26 changes: 23 additions & 3 deletions infra/timer/TimerLimitedRepeating.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
#include "infra/timer/TimerLimitedRepeating.hpp"
#include "infra/timer/Timer.hpp"
#include "infra/util/Function.hpp"
#include <cstdint>

namespace infra
{
TimerLimitedRepeating::TimerLimitedRepeating(int aHowMany, Duration duration, const infra::Function<void()>& aAction, uint32_t timerServiceId)
TimerLimitedRepeating::TimerLimitedRepeating(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, uint32_t timerServiceId)
: detail::TimerRepeating(timerServiceId)
{
Start(aHowMany, duration, aAction);
Start(aHowMany, duration, action);
}

void TimerLimitedRepeating::Start(int aHowMany, Duration duration, const infra::Function<void()>& aAction)
TimerLimitedRepeating::TimerLimitedRepeating(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, TriggerImmediately, uint32_t timerServiceId)
: detail::TimerRepeating(timerServiceId)
{
Start(aHowMany, duration, action, triggerImmediately);
}

void TimerLimitedRepeating::Start(uint32_t aHowMany, Duration duration, const infra::Function<void()>& aAction)
{
howMany = aHowMany;
if (howMany > 0)
Expand All @@ -17,6 +26,17 @@ namespace infra
Cancel();
}

void TimerLimitedRepeating::Start(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, TriggerImmediately)
{
const auto atLeastOnce = aHowMany > 0;
const auto howManyRemaining = atLeastOnce ? aHowMany - 1 : 0;

Start(howManyRemaining, duration, action);

if (atLeastOnce)
action();
}

void TimerLimitedRepeating::ComputeNextTriggerTime()
{
--howMany;
Expand Down
10 changes: 7 additions & 3 deletions infra/timer/TimerLimitedRepeating.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#define INFRA_TIMER_LIMITED_REPEATING_HPP

#include "infra/timer/Timer.hpp"
#include "infra/util/Function.hpp"
#include <cstdint>

namespace infra
{
Expand All @@ -10,15 +12,17 @@ namespace infra
{
public:
using detail::TimerRepeating::TimerRepeating;
TimerLimitedRepeating(int aHowMany, Duration duration, const infra::Function<void()>& action, uint32_t timerServiceId = systemTimerServiceId);
TimerLimitedRepeating(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, uint32_t timerServiceId = systemTimerServiceId);
TimerLimitedRepeating(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, TriggerImmediately, uint32_t timerServiceId = systemTimerServiceId);

void Start(int aHowMany, Duration duration, const infra::Function<void()>& action);
void Start(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action);
void Start(uint32_t aHowMany, Duration duration, const infra::Function<void()>& action, TriggerImmediately);

protected:
void ComputeNextTriggerTime() override;

private:
int howMany{ 0 };
uint32_t howMany{ 0 };
};
}

Expand Down
51 changes: 51 additions & 0 deletions infra/timer/test/TestTimerLimitedRepeating.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
#include "infra/timer/Timer.hpp"
#include "infra/timer/TimerLimitedRepeating.hpp"
#include "infra/timer/test_helper/ClockFixture.hpp"
#include "infra/util/test_helper/MockCallback.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <chrono>

class TimerLimitedRepeatingTest
: public testing::Test
Expand Down Expand Up @@ -92,3 +94,52 @@ TEST_F(TimerLimitedRepeatingTest, Restart0AfterFirstCallback)

ForwardTime(std::chrono::seconds(5));
}

TEST_F(TimerLimitedRepeatingTest, TimerTriggersImmediately)
{
infra::MockCallback<void()> callback;
EXPECT_CALL(callback, callback()).With(After(std::chrono::seconds(0)));
EXPECT_CALL(callback, callback()).With(After(std::chrono::seconds(1)));

infra::TimerLimitedRepeating timer(
2,
std::chrono::seconds(1), [&callback]()
{
callback.callback();
},
infra::triggerImmediately);

ForwardTime(std::chrono::seconds(1));
}

TEST_F(TimerLimitedRepeatingTest, TimerTriggersImmediatelyNever)
{
infra::MockCallback<void()> callback;
EXPECT_CALL(callback, callback()).Times(0);

infra::TimerLimitedRepeating timer(
0,
std::chrono::seconds(1), [&callback]()
{
callback.callback();
},
infra::triggerImmediately);

ForwardTime(std::chrono::seconds(1));
}

TEST_F(TimerLimitedRepeatingTest, TimerTriggersImmediatelyOnce)
{
infra::MockCallback<void()> callback;
EXPECT_CALL(callback, callback()).Times(1);

infra::TimerLimitedRepeating timer(
1,
std::chrono::seconds(1), [&callback]()
{
callback.callback();
},
infra::triggerImmediately);

ForwardTime(std::chrono::seconds(1));
}

0 comments on commit 631ec6c

Please sign in to comment.