Skip to content

Commit d9cefc2

Browse files
authored
Merge pull request #201 from scratchcpp/timer
Implement timer
2 parents d264d7e + 5c5eb05 commit d9cefc2

File tree

21 files changed

+321
-1
lines changed

21 files changed

+321
-1
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/iengine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class Sprite;
1919
class Variable;
2020
class List;
2121
class Script;
22+
class ITimer;
2223

2324
/*!
2425
* \brief The IEngine interface provides an API for running Scratch projects.
@@ -106,6 +107,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
106107
/*! Call this from a block implementation to ignore calls to skipFrame() until the current frame ends. */
107108
virtual void lockFrame() = 0;
108109

110+
/*! Returns the timer of the project. */
111+
virtual ITimer *timer() const = 0;
112+
109113
/*!
110114
* Registers the given block section.
111115
* \see <a href="blockSections.html">Block sections</a>

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: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,11 @@ target_sources(scratchcpp
1111
script_p.h
1212
internal/engine.cpp
1313
internal/engine.h
14+
internal/clock.cpp
15+
internal/clock.h
16+
internal/iclock.h
17+
internal/timer.cpp
18+
internal/timer.h
1419
internal/blocksectioncontainer.cpp
1520
internal/blocksectioncontainer.h
1621
internal/global.h

src/engine/internal/clock.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#include "clock.h"
4+
5+
using namespace libscratchcpp;
6+
7+
std::shared_ptr<Clock> Clock::m_instance = std::make_shared<Clock>();
8+
9+
Clock::Clock()
10+
{
11+
}
12+
13+
std::shared_ptr<Clock> Clock::instance()
14+
{
15+
return m_instance;
16+
}
17+
18+
std::chrono::steady_clock::time_point Clock::currentTime() const
19+
{
20+
return std::chrono::steady_clock::now();
21+
}

src/engine/internal/clock.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+
#include <memory>
6+
#include "iclock.h"
7+
8+
namespace libscratchcpp
9+
{
10+
11+
class Clock : public IClock
12+
{
13+
public:
14+
Clock();
15+
Clock(const Clock &) = delete;
16+
17+
static std::shared_ptr<Clock> instance();
18+
19+
std::chrono::steady_clock::time_point currentTime() const override;
20+
21+
private:
22+
static std::shared_ptr<Clock> m_instance;
23+
};
24+
25+
} // namespace libscratchcpp

src/engine/internal/engine.cpp

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@
1818

1919
#include "engine.h"
2020
#include "blocksectioncontainer.h"
21+
#include "timer.h"
2122
#include "../../blocks/standardblocks.h"
2223

2324
using namespace libscratchcpp;
2425

25-
Engine::Engine()
26+
Engine::Engine() :
27+
m_defaultTimer(std::make_unique<Timer>()),
28+
m_timer(m_defaultTimer.get())
2629
{
2730
srand(time(NULL));
2831
}
@@ -165,6 +168,8 @@ void Engine::frame()
165168

166169
void Engine::start()
167170
{
171+
m_timer->reset();
172+
168173
for (auto target : m_targets) {
169174
auto gfBlocks = target->greenFlagBlocks();
170175
for (auto block : gfBlocks)
@@ -377,6 +382,16 @@ void Engine::lockFrame()
377382
m_lockFrame = true;
378383
}
379384

385+
ITimer *Engine::timer() const
386+
{
387+
return m_timer;
388+
}
389+
390+
void Engine::setTimer(ITimer *timer)
391+
{
392+
m_timer = timer;
393+
}
394+
380395
void Engine::registerSection(std::shared_ptr<IBlockSection> section)
381396
{
382397
if (section) {

src/engine/internal/engine.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
#include <scratchcpp/iengine.h>
66
#include <scratchcpp/target.h>
7+
#include <scratchcpp/itimer.h>
78
#include <unordered_map>
89
#include <memory>
910
#include <chrono>
@@ -43,6 +44,9 @@ class Engine : public IEngine
4344
void skipFrame() override;
4445
void lockFrame() override;
4546

47+
ITimer *timer() const override;
48+
void setTimer(ITimer *timer);
49+
4650
void registerSection(std::shared_ptr<IBlockSection> section) override;
4751
std::vector<std::shared_ptr<IBlockSection>> registeredSections() const;
4852
unsigned int functionIndex(BlockFunc f) override;
@@ -101,6 +105,9 @@ class Engine : public IEngine
101105
std::unordered_map<Variable *, Target *> m_variableOwners;
102106
std::unordered_map<List *, Target *> m_listOwners;
103107

108+
std::unique_ptr<ITimer> m_defaultTimer;
109+
ITimer *m_timer = nullptr;
110+
104111
bool m_breakFrame = false;
105112
bool m_skipFrame = false;
106113
bool m_lockFrame = false;

src/engine/internal/iclock.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
#pragma once
4+
5+
#include <chrono>
6+
7+
namespace libscratchcpp
8+
{
9+
10+
class IClock
11+
{
12+
public:
13+
virtual ~IClock() { }
14+
15+
virtual std::chrono::steady_clock::time_point currentTime() const = 0;
16+
};
17+
18+
} // namespace libscratchcpp

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+
}

0 commit comments

Comments
 (0)