Skip to content

Commit dc18ede

Browse files
committed
Add Timer class
1 parent 27fa0e8 commit dc18ede

File tree

9 files changed

+157
-0
lines changed

9 files changed

+157
-0
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ target_sources(scratchcpp
4646
include/scratchcpp/target.h
4747
include/scratchcpp/stage.h
4848
include/scratchcpp/sprite.h
49+
include/scratchcpp/itimer.h
4950
)
5051

5152
add_library(zip SHARED

include/scratchcpp/itimer.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
namespace libscratchcpp
6+
{
7+
8+
/*!
9+
* \brief The ITimer interface represents a timer of a Scratch project.
10+
*
11+
* You can get a project timer using Engine#timer().
12+
*/
13+
class ITimer
14+
{
15+
public:
16+
virtual ~ITimer() { }
17+
18+
/*! Returns the time since last reset in seconds. */
19+
virtual double value() const = 0;
20+
21+
/*! Resets the timer. */
22+
virtual void reset() = 0;
23+
};
24+
25+
} // namespace libscratchcpp

src/engine/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ target_sources(scratchcpp
1414
internal/clock.cpp
1515
internal/clock.h
1616
internal/iclock.h
17+
internal/timer.cpp
18+
internal/timer.h
1719
internal/blocksectioncontainer.cpp
1820
internal/blocksectioncontainer.h
1921
internal/global.h

src/engine/internal/timer.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include <cassert>
4+
5+
#include "timer.h"
6+
#include "clock.h"
7+
8+
using namespace libscratchcpp;
9+
10+
Timer::Timer()
11+
{
12+
m_clock = Clock::instance().get();
13+
resetTimer();
14+
}
15+
16+
Timer::Timer(IClock *clock) :
17+
m_clock(clock)
18+
{
19+
assert(clock);
20+
resetTimer();
21+
}
22+
23+
double Timer::value() const
24+
{
25+
return std::chrono::duration_cast<std::chrono::milliseconds>(m_clock->currentTime() - m_startTime).count() / 1000.0;
26+
}
27+
28+
void Timer::reset()
29+
{
30+
resetTimer();
31+
}
32+
33+
// Required to avoid calling the virtual method from the constructors
34+
void Timer::resetTimer()
35+
{
36+
m_startTime = m_clock->currentTime();
37+
}

src/engine/internal/timer.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <scratchcpp/itimer.h>
6+
#include <chrono>
7+
8+
namespace libscratchcpp
9+
{
10+
11+
class IClock;
12+
13+
class Timer : public ITimer
14+
{
15+
public:
16+
Timer();
17+
Timer(IClock *clock);
18+
Timer(const Timer &) = delete;
19+
20+
double value() const override;
21+
void reset() override;
22+
23+
private:
24+
void resetTimer();
25+
26+
std::chrono::steady_clock::time_point m_startTime;
27+
IClock *m_clock = nullptr;
28+
};
29+
30+
} // namespace libscratchcpp

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ add_subdirectory(script)
2929
add_subdirectory(extensions)
3030
add_subdirectory(engine)
3131
add_subdirectory(clock)
32+
add_subdirectory(timer)

test/mocks/timermock.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#pragma once
2+
3+
#include <scratchcpp/itimer.h>
4+
#include <gmock/gmock.h>
5+
6+
using namespace libscratchcpp;
7+
8+
class TimerMock : public ITimer
9+
{
10+
public:
11+
MOCK_METHOD(double, value, (), (const, override));
12+
13+
MOCK_METHOD(void, reset, (), (override));
14+
};

test/timer/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
add_executable(
2+
timer_test
3+
timer_test.cpp
4+
)
5+
6+
target_link_libraries(
7+
timer_test
8+
GTest::gtest_main
9+
GTest::gmock_main
10+
scratchcpp
11+
scratchcpp_mocks
12+
)
13+
14+
gtest_discover_tests(timer_test)

test/timer/timer_test.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <engine/internal/timer.h>
2+
#include <clockmock.h>
3+
4+
#include "../common.h"
5+
6+
using namespace libscratchcpp;
7+
8+
using ::testing::Return;
9+
10+
TEST(TimerTest, ValueAndReset)
11+
{
12+
ClockMock clock;
13+
14+
std::chrono::steady_clock::time_point startTime(std::chrono::milliseconds(50));
15+
EXPECT_CALL(clock, currentTime()).WillOnce(Return(startTime));
16+
Timer timer(&clock);
17+
18+
std::chrono::steady_clock::time_point time1(std::chrono::milliseconds(73));
19+
EXPECT_CALL(clock, currentTime()).WillOnce(Return(time1));
20+
ASSERT_EQ(timer.value(), 0.023);
21+
22+
std::chrono::steady_clock::time_point time2(std::chrono::milliseconds(15432));
23+
EXPECT_CALL(clock, currentTime()).WillOnce(Return(time2));
24+
ASSERT_EQ(timer.value(), 15.382);
25+
26+
std::chrono::steady_clock::time_point time3(std::chrono::milliseconds(16025));
27+
EXPECT_CALL(clock, currentTime()).WillOnce(Return(time3));
28+
timer.reset();
29+
30+
std::chrono::steady_clock::time_point time4(std::chrono::milliseconds(24632));
31+
EXPECT_CALL(clock, currentTime()).WillOnce(Return(time4));
32+
ASSERT_EQ(timer.value(), 8.607);
33+
}

0 commit comments

Comments
 (0)