Skip to content

Commit 80a651e

Browse files
committed
Implement motion_pointindirection block
1 parent 16fed38 commit 80a651e

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

src/blocks/motionblocks.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ void MotionBlocks::registerBlocks(IEngine *engine)
2121
engine->addCompileFunction(this, "motion_movesteps", &compileMoveSteps);
2222
engine->addCompileFunction(this, "motion_turnright", &compileTurnRight);
2323
engine->addCompileFunction(this, "motion_turnleft", &compileTurnLeft);
24+
engine->addCompileFunction(this, "motion_pointindirection", &compilePointInDirection);
2425

2526
// Inputs
2627
engine->addInput(this, "STEPS", STEPS);
2728
engine->addInput(this, "DEGREES", DEGREES);
29+
engine->addInput(this, "DIRECTION", DIRECTION);
2830
}
2931

3032
void MotionBlocks::compileMoveSteps(Compiler *compiler)
@@ -45,6 +47,12 @@ void MotionBlocks::compileTurnLeft(Compiler *compiler)
4547
compiler->addFunctionCall(&turnLeft);
4648
}
4749

50+
void MotionBlocks::compilePointInDirection(Compiler *compiler)
51+
{
52+
compiler->addInput(DIRECTION);
53+
compiler->addFunctionCall(&pointInDirection);
54+
}
55+
4856
unsigned int MotionBlocks::moveSteps(VirtualMachine *vm)
4957
{
5058
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
@@ -78,3 +86,13 @@ unsigned int MotionBlocks::turnLeft(VirtualMachine *vm)
7886

7987
return 1;
8088
}
89+
90+
unsigned int MotionBlocks::pointInDirection(VirtualMachine *vm)
91+
{
92+
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
93+
94+
if (sprite)
95+
sprite->setDirection(vm->getInput(0, 1)->toDouble());
96+
97+
return 1;
98+
}

src/blocks/motionblocks.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ class MotionBlocks : public IBlockSection
1414
enum Inputs
1515
{
1616
STEPS,
17-
DEGREES
17+
DEGREES,
18+
DIRECTION
1819
};
1920

2021
std::string name() const override;
@@ -24,10 +25,12 @@ class MotionBlocks : public IBlockSection
2425
static void compileMoveSteps(Compiler *compiler);
2526
static void compileTurnRight(Compiler *compiler);
2627
static void compileTurnLeft(Compiler *compiler);
28+
static void compilePointInDirection(Compiler *compiler);
2729

2830
static unsigned int moveSteps(VirtualMachine *vm);
2931
static unsigned int turnRight(VirtualMachine *vm);
3032
static unsigned int turnLeft(VirtualMachine *vm);
33+
static unsigned int pointInDirection(VirtualMachine *vm);
3134
};
3235

3336
} // namespace libscratchcpp

test/blocks/motion_blocks_test.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,12 @@ TEST_F(MotionBlocksTest, RegisterBlocks)
5454
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_movesteps", &MotionBlocks::compileMoveSteps));
5555
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_turnright", &MotionBlocks::compileTurnRight));
5656
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_turnleft", &MotionBlocks::compileTurnLeft));
57+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_pointindirection", &MotionBlocks::compilePointInDirection));
5758

5859
// Inputs
5960
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "STEPS", MotionBlocks::STEPS));
6061
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "DEGREES", MotionBlocks::DEGREES));
62+
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "DIRECTION", MotionBlocks::DIRECTION));
6163

6264
m_section->registerBlocks(&m_engineMock);
6365
}
@@ -181,3 +183,42 @@ TEST_F(MotionBlocksTest, TurnLeftImpl)
181183
ASSERT_EQ(vm.registerCount(), 0);
182184
ASSERT_EQ(std::round(sprite.direction() * 100) / 100, 112.32);
183185
}
186+
187+
TEST_F(MotionBlocksTest, PointInDirection)
188+
{
189+
Compiler compiler(&m_engineMock);
190+
191+
// point in direction (-60.5)
192+
auto block = std::make_shared<Block>("a", "motion_pointindirection");
193+
addValueInput(block, "DIRECTION", MotionBlocks::DIRECTION, -60.5);
194+
195+
EXPECT_CALL(m_engineMock, functionIndex(&MotionBlocks::pointInDirection)).WillOnce(Return(0));
196+
197+
compiler.init();
198+
compiler.setBlock(block);
199+
MotionBlocks::compilePointInDirection(&compiler);
200+
compiler.end();
201+
202+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT }));
203+
ASSERT_EQ(compiler.constValues().size(), 1);
204+
ASSERT_EQ(compiler.constValues()[0].toDouble(), -60.5);
205+
}
206+
207+
TEST_F(MotionBlocksTest, PointInDirectionImpl)
208+
{
209+
static unsigned int bytecode[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT };
210+
static BlockFunc functions[] = { &MotionBlocks::pointInDirection };
211+
static Value constValues[] = { -60.5 };
212+
213+
Sprite sprite;
214+
sprite.setDirection(50.02);
215+
216+
VirtualMachine vm(&sprite, nullptr, nullptr);
217+
vm.setBytecode(bytecode);
218+
vm.setFunctions(functions);
219+
vm.setConstValues(constValues);
220+
vm.run();
221+
222+
ASSERT_EQ(vm.registerCount(), 0);
223+
ASSERT_EQ(sprite.direction(), -60.5);
224+
}

0 commit comments

Comments
 (0)