Skip to content

Commit 21df2fe

Browse files
committed
Add StackTimer
1 parent 77f687e commit 21df2fe

File tree

8 files changed

+177
-0
lines changed

8 files changed

+177
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ target_sources(scratchcpp
5959
include/scratchcpp/sprite.h
6060
include/scratchcpp/textbubble.h
6161
include/scratchcpp/itimer.h
62+
include/scratchcpp/istacktimer.h
6263
include/scratchcpp/keyevent.h
6364
include/scratchcpp/rect.h
6465
include/scratchcpp/igraphicseffect.h

include/scratchcpp/istacktimer.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include "global.h"
6+
7+
namespace libscratchcpp
8+
{
9+
10+
/*!
11+
* \brief The IStackTimer interface represents a timer that can be used by blocks.
12+
*
13+
* You can get a stack timer using ExecutionContext#stackTimer().
14+
*/
15+
class LIBSCRATCHCPP_EXPORT IStackTimer
16+
{
17+
public:
18+
virtual ~IStackTimer() { }
19+
20+
/*! Starts the timer. */
21+
virtual void start(double seconds) = 0;
22+
23+
/*! Stops the timer. */
24+
virtual void stop() = 0;
25+
26+
/*! Returns true if the timer has been stopped using stop() or wasn't used at all. */
27+
virtual bool stopped() const = 0;
28+
29+
/*! Returns true if the timer has elapsed. */
30+
virtual bool elapsed() const = 0;
31+
};
32+
33+
} // namespace libscratchcpp

src/engine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ target_sources(scratchcpp
1616
internal/iclock.h
1717
internal/timer.cpp
1818
internal/timer.h
19+
internal/stacktimer.cpp
20+
internal/stacktimer.h
1921
internal/randomgenerator.h
2022
internal/randomgenerator.cpp
2123
internal/irandomgenerator.h

src/engine/internal/stacktimer.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <cassert>
4+
#include <iostream>
5+
6+
#include "stacktimer.h"
7+
#include "clock.h"
8+
9+
using namespace libscratchcpp;
10+
11+
StackTimer::StackTimer()
12+
{
13+
m_clock = Clock::instance().get();
14+
}
15+
16+
StackTimer::StackTimer(IClock *clock) :
17+
m_clock(clock)
18+
{
19+
assert(clock);
20+
}
21+
22+
void StackTimer::start(double seconds)
23+
{
24+
m_startTime = m_clock->currentSteadyTime();
25+
m_timeLimit = seconds * 1000;
26+
m_stopped = false;
27+
}
28+
29+
void StackTimer::stop()
30+
{
31+
m_stopped = true;
32+
}
33+
34+
bool StackTimer::stopped() const
35+
{
36+
return m_stopped;
37+
}
38+
39+
bool StackTimer::elapsed() const
40+
{
41+
if (m_stopped)
42+
return false;
43+
44+
return std::chrono::duration_cast<std::chrono::milliseconds>(m_clock->currentSteadyTime() - m_startTime).count() >= m_timeLimit;
45+
}

src/engine/internal/stacktimer.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <scratchcpp/istacktimer.h>
6+
#include <chrono>
7+
8+
namespace libscratchcpp
9+
{
10+
11+
class IClock;
12+
13+
class StackTimer : public IStackTimer
14+
{
15+
public:
16+
StackTimer();
17+
StackTimer(IClock *clock);
18+
StackTimer(const StackTimer &) = delete;
19+
20+
void start(double seconds) override;
21+
void stop() override;
22+
23+
bool stopped() const override;
24+
bool elapsed() const override;
25+
26+
private:
27+
std::chrono::steady_clock::time_point m_startTime;
28+
bool m_stopped = true;
29+
long m_timeLimit = 0;
30+
IClock *m_clock = nullptr;
31+
};
32+
33+
} // namespace libscratchcpp

test/mocks/stacktimermock.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#pragma once
2+
3+
#include <scratchcpp/istacktimer.h>
4+
#include <gmock/gmock.h>
5+
6+
using namespace libscratchcpp;
7+
8+
class StackTimerMock : public IStackTimer
9+
{
10+
public:
11+
MOCK_METHOD(void, start, (double), (override));
12+
MOCK_METHOD(void, stop, (), (override));
13+
14+
MOCK_METHOD(bool, stopped, (), (const, override));
15+
MOCK_METHOD(bool, elapsed, (), (const, override));
16+
};

test/timer/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
add_executable(
22
timer_test
33
timer_test.cpp
4+
stacktimer_test.cpp
45
)
56

67
target_link_libraries(

test/timer/stacktimer_test.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include <engine/internal/stacktimer.h>
2+
3+
#include <clockmock.h>
4+
5+
using namespace libscratchcpp;
6+
7+
using ::testing::Return;
8+
9+
TEST(StackTimerTest, StartStopElapsed)
10+
{
11+
ClockMock clock;
12+
StackTimer timer(&clock);
13+
14+
ASSERT_TRUE(timer.stopped());
15+
16+
EXPECT_CALL(clock, currentSteadyTime).Times(0);
17+
ASSERT_FALSE(timer.elapsed());
18+
19+
std::chrono::steady_clock::time_point time2(std::chrono::milliseconds(73));
20+
EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time2));
21+
timer.start(0.5);
22+
23+
EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time2));
24+
ASSERT_FALSE(timer.elapsed());
25+
ASSERT_FALSE(timer.stopped());
26+
27+
std::chrono::steady_clock::time_point time3(std::chrono::milliseconds(520));
28+
EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time3));
29+
ASSERT_FALSE(timer.elapsed());
30+
ASSERT_FALSE(timer.stopped());
31+
32+
std::chrono::steady_clock::time_point time4(std::chrono::milliseconds(573));
33+
EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time4));
34+
ASSERT_TRUE(timer.elapsed());
35+
ASSERT_FALSE(timer.stopped());
36+
37+
std::chrono::steady_clock::time_point time5(std::chrono::milliseconds(580));
38+
EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time5));
39+
ASSERT_TRUE(timer.elapsed());
40+
ASSERT_FALSE(timer.stopped());
41+
42+
timer.stop();
43+
EXPECT_CALL(clock, currentSteadyTime).Times(0);
44+
ASSERT_FALSE(timer.elapsed());
45+
ASSERT_TRUE(timer.stopped());
46+
}

0 commit comments

Comments
 (0)