diff --git a/src/blocks/controlblocks.cpp b/src/blocks/controlblocks.cpp index 9da72683..8d668a03 100644 --- a/src/blocks/controlblocks.cpp +++ b/src/blocks/controlblocks.cpp @@ -9,9 +9,12 @@ #include #include "controlblocks.h" +#include "../engine/internal/clock.h" using namespace libscratchcpp; +IClock *ControlBlocks::clock = nullptr; + std::string ControlBlocks::name() const { return "Control"; @@ -207,14 +210,20 @@ unsigned int ControlBlocks::stopOtherScriptsInSprite(VirtualMachine *vm) unsigned int ControlBlocks::startWait(VirtualMachine *vm) { - auto currentTime = std::chrono::steady_clock::now(); + if (!clock) + clock = Clock::instance().get(); + + auto currentTime = clock->currentSteadyTime(); m_timeMap[vm] = { currentTime, vm->getInput(0, 1)->toDouble() * 1000 }; return 1; } unsigned int ControlBlocks::wait(VirtualMachine *vm) { - auto currentTime = std::chrono::steady_clock::now(); + if (!clock) + clock = Clock::instance().get(); + + auto currentTime = clock->currentSteadyTime(); assert(m_timeMap.count(vm) == 1); if (std::chrono::duration_cast(currentTime - m_timeMap[vm].first).count() >= m_timeMap[vm].second) { m_timeMap.erase(vm); diff --git a/src/blocks/controlblocks.h b/src/blocks/controlblocks.h index 92e63aaf..236ab87b 100644 --- a/src/blocks/controlblocks.h +++ b/src/blocks/controlblocks.h @@ -11,6 +11,7 @@ namespace libscratchcpp class Compiler; class VirtualMachine; +class IClock; /*! \brief The ControlBlocks class contains the implementation of control blocks. */ class ControlBlocks : public IBlockSection @@ -69,6 +70,8 @@ class ControlBlocks : public IBlockSection static unsigned int deleteThisClone(VirtualMachine *vm); static inline std::unordered_map> m_timeMap; + + static IClock *clock; }; } // namespace libscratchcpp diff --git a/test/blocks/control_blocks_test.cpp b/test/blocks/control_blocks_test.cpp index dab49c20..8ba068e0 100644 --- a/test/blocks/control_blocks_test.cpp +++ b/test/blocks/control_blocks_test.cpp @@ -5,11 +5,13 @@ #include #include #include +#include #include "../common.h" #include "blocks/controlblocks.h" #include "blocks/operatorblocks.h" #include "engine/internal/engine.h" +#include "engine/internal/clock.h" using namespace libscratchcpp; @@ -732,6 +734,11 @@ TEST_F(ControlBlocksTest, WaitImpl) vm.setConstValues(constValues); vm.setBytecode(bytecode); + ClockMock clock; + ControlBlocks::clock = &clock; + + std::chrono::steady_clock::time_point startTime(std::chrono::milliseconds(1000)); + EXPECT_CALL(clock, currentSteadyTime()).Times(2).WillRepeatedly(Return(startTime)); EXPECT_CALL(m_engineMock, lockFrame()).Times(1); EXPECT_CALL(m_engineMock, breakFrame()).Times(1); vm.run(); @@ -740,18 +747,20 @@ TEST_F(ControlBlocksTest, WaitImpl) ASSERT_TRUE(ControlBlocks::m_timeMap.find(&vm) != ControlBlocks::m_timeMap.cend()); ASSERT_FALSE(vm.atEnd()); + std::chrono::steady_clock::time_point time1(std::chrono::milliseconds(6450)); + EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time1)); EXPECT_CALL(m_engineMock, lockFrame()).Times(1); EXPECT_CALL(m_engineMock, breakFrame()).Times(1); - ControlBlocks::m_timeMap[&vm].first = std::chrono::steady_clock::now() - std::chrono::milliseconds(5250); vm.run(); ASSERT_EQ(vm.registerCount(), 0); ASSERT_TRUE(ControlBlocks::m_timeMap.find(&vm) != ControlBlocks::m_timeMap.cend()); ASSERT_FALSE(vm.atEnd()); + std::chrono::steady_clock::time_point time2(std::chrono::milliseconds(6500)); + EXPECT_CALL(clock, currentSteadyTime()).WillOnce(Return(time2)); EXPECT_CALL(m_engineMock, lockFrame()).Times(1); EXPECT_CALL(m_engineMock, breakFrame()).Times(1); - ControlBlocks::m_timeMap[&vm].first = std::chrono::steady_clock::now() - std::chrono::milliseconds(5500); vm.run(); ASSERT_EQ(vm.registerCount(), 0); @@ -765,6 +774,8 @@ TEST_F(ControlBlocksTest, WaitImpl) ASSERT_EQ(vm.registerCount(), 0); ASSERT_TRUE(ControlBlocks::m_timeMap.find(&vm) == ControlBlocks::m_timeMap.cend()); ASSERT_TRUE(vm.atEnd()); + + ControlBlocks::clock = Clock::instance().get(); } TEST_F(ControlBlocksTest, WaitUntil)