Skip to content

Commit 24925ad

Browse files
committed
Add skipFrame method to Engine
1 parent e5500ee commit 24925ad

File tree

4 files changed

+26
-1
lines changed

4 files changed

+26
-1
lines changed

include/scratchcpp/iengine.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,13 @@ class LIBSCRATCHCPP_EXPORT IEngine
9090
/*! Returns true if breakFrame() was called. */
9191
virtual bool breakingCurrentFrame() = 0;
9292

93+
/*!
94+
* Call this from a block implementation to skip a frame and run the next frame immediately.\n
95+
* The screen will be refreshed according to the frame rate.
96+
* \note This also works in "run without screen refresh" custom blocks.
97+
*/
98+
virtual void skipFrame() = 0;
99+
93100
/*!
94101
* Registers the given block section.
95102
* \see <a href="blockSections.html">Block sections</a>

src/engine/engine.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ void Engine::run()
227227

228228
while (true) {
229229
auto lastFrameTime = std::chrono::steady_clock::now();
230+
m_skipFrame = false;
231+
230232
// Execute the frame
231233
frame();
232234
if (m_runningScripts.size() <= 0)
@@ -236,10 +238,15 @@ void Engine::run()
236238
auto currentTime = std::chrono::steady_clock::now();
237239
auto elapsedTime = std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - lastFrameTime);
238240
auto sleepTime = frameDuration - elapsedTime;
241+
bool timeOut = sleepTime <= std::chrono::milliseconds::zero();
239242

240-
if (sleepTime > std::chrono::milliseconds::zero())
243+
if (!timeOut && !m_skipFrame)
241244
std::this_thread::sleep_for(sleepTime);
242245

246+
if ((m_skipFrame && timeOut) || !m_skipFrame) {
247+
// TODO: Repaint here
248+
}
249+
243250
lastFrameTime = currentTime;
244251
}
245252
}
@@ -259,6 +266,12 @@ bool libscratchcpp::Engine::breakingCurrentFrame()
259266
return m_breakFrame;
260267
}
261268

269+
void Engine::skipFrame()
270+
{
271+
breakFrame();
272+
m_skipFrame = true;
273+
}
274+
262275
void Engine::registerSection(std::shared_ptr<IBlockSection> section)
263276
{
264277
if (section) {

src/engine/engine.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class Engine : public IEngine
4040
void breakFrame() override;
4141
bool breakingCurrentFrame() override;
4242

43+
void skipFrame() override;
44+
4345
void registerSection(std::shared_ptr<IBlockSection> section) override;
4446
unsigned int functionIndex(BlockFunc f) override;
4547

@@ -88,6 +90,7 @@ class Engine : public IEngine
8890
std::vector<BlockFunc> m_functions;
8991

9092
bool m_breakFrame = false;
93+
bool m_skipFrame = false;
9194
};
9295

9396
} // namespace libscratchcpp

test/mocks/enginemock.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ class EngineMock : public IEngine
2828
MOCK_METHOD(void, breakFrame, (), (override));
2929
MOCK_METHOD(bool, breakingCurrentFrame, (), (override));
3030

31+
MOCK_METHOD(void, skipFrame, (), (override));
32+
3133
MOCK_METHOD(void, registerSection, (std::shared_ptr<IBlockSection>), (override));
3234
MOCK_METHOD(unsigned int, functionIndex, (BlockFunc), (override));
3335

0 commit comments

Comments
 (0)