Skip to content

Commit 64fe2da

Browse files
committed
Implement motion_setrotationstyle block
1 parent 5c12d10 commit 64fe2da

File tree

3 files changed

+136
-0
lines changed

3 files changed

+136
-0
lines changed

src/blocks/motionblocks.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <scratchcpp/compiler.h>
55
#include <scratchcpp/sprite.h>
66
#include <scratchcpp/input.h>
7+
#include <scratchcpp/field.h>
78

89
#include "motionblocks.h"
910
#include "../engine/internal/randomgenerator.h"
@@ -37,6 +38,7 @@ void MotionBlocks::registerBlocks(IEngine *engine)
3738
engine->addCompileFunction(this, "motion_setx", &compileSetX);
3839
engine->addCompileFunction(this, "motion_changeyby", &compileChangeYBy);
3940
engine->addCompileFunction(this, "motion_sety", &compileSetY);
41+
engine->addCompileFunction(this, "motion_setrotationstyle", &compileSetRotationStyle);
4042

4143
// Inputs
4244
engine->addInput(this, "STEPS", STEPS);
@@ -49,6 +51,9 @@ void MotionBlocks::registerBlocks(IEngine *engine)
4951
engine->addInput(this, "SECS", SECS);
5052
engine->addInput(this, "DX", DX);
5153
engine->addInput(this, "DY", DY);
54+
55+
// Fields
56+
engine->addField(this, "STYLE", STYLE);
5257
}
5358

5459
void MotionBlocks::compileMoveSteps(Compiler *compiler)
@@ -188,6 +193,28 @@ void MotionBlocks::compileSetY(Compiler *compiler)
188193
compiler->addFunctionCall(&setY);
189194
}
190195

196+
void MotionBlocks::compileSetRotationStyle(Compiler *compiler)
197+
{
198+
int option = compiler->field(STYLE)->specialValueId();
199+
200+
switch (option) {
201+
case LeftRight:
202+
compiler->addFunctionCall(&setLeftRightRotationStyle);
203+
break;
204+
205+
case DoNotRotate:
206+
compiler->addFunctionCall(&setDoNotRotateRotationStyle);
207+
break;
208+
209+
case AllAround:
210+
compiler->addFunctionCall(&setAllAroundRotationStyle);
211+
break;
212+
213+
default:
214+
break;
215+
}
216+
}
217+
191218
unsigned int MotionBlocks::moveSteps(VirtualMachine *vm)
192219
{
193220
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
@@ -589,3 +616,33 @@ unsigned int MotionBlocks::setY(VirtualMachine *vm)
589616

590617
return 1;
591618
}
619+
620+
unsigned int MotionBlocks::setLeftRightRotationStyle(VirtualMachine *vm)
621+
{
622+
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
623+
624+
if (sprite)
625+
sprite->setRotationStyle(Sprite::RotationStyle::LeftRight);
626+
627+
return 0;
628+
}
629+
630+
unsigned int MotionBlocks::setDoNotRotateRotationStyle(VirtualMachine *vm)
631+
{
632+
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
633+
634+
if (sprite)
635+
sprite->setRotationStyle(Sprite::RotationStyle::DoNotRotate);
636+
637+
return 0;
638+
}
639+
640+
unsigned int MotionBlocks::setAllAroundRotationStyle(VirtualMachine *vm)
641+
{
642+
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
643+
644+
if (sprite)
645+
sprite->setRotationStyle(Sprite::RotationStyle::AllAround);
646+
647+
return 0;
648+
}

src/blocks/motionblocks.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,14 @@ class MotionBlocks : public IBlockSection
3434

3535
enum Fields
3636
{
37+
STYLE
3738
};
3839

3940
enum FieldValues
4041
{
42+
LeftRight,
43+
AllAround,
44+
DoNotRotate
4145
};
4246

4347
std::string name() const override;
@@ -57,6 +61,7 @@ class MotionBlocks : public IBlockSection
5761
static void compileSetX(Compiler *compiler);
5862
static void compileChangeYBy(Compiler *compiler);
5963
static void compileSetY(Compiler *compiler);
64+
static void compileSetRotationStyle(Compiler *compiler);
6065

6166
static unsigned int moveSteps(VirtualMachine *vm);
6267
static unsigned int turnRight(VirtualMachine *vm);
@@ -90,6 +95,9 @@ class MotionBlocks : public IBlockSection
9095
static unsigned int setX(VirtualMachine *vm);
9196
static unsigned int changeYBy(VirtualMachine *vm);
9297
static unsigned int setY(VirtualMachine *vm);
98+
static unsigned int setLeftRightRotationStyle(VirtualMachine *vm);
99+
static unsigned int setDoNotRotateRotationStyle(VirtualMachine *vm);
100+
static unsigned int setAllAroundRotationStyle(VirtualMachine *vm);
93101

94102
static IRandomGenerator *rng;
95103
static IClock *clock;

test/blocks/motion_blocks_test.cpp

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ TEST_F(MotionBlocksTest, RegisterBlocks)
110110
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_setx", &MotionBlocks::compileSetX));
111111
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_changeyby", &MotionBlocks::compileChangeYBy));
112112
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_sety", &MotionBlocks::compileSetY));
113+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "motion_setrotationstyle", &MotionBlocks::compileSetRotationStyle));
113114

114115
// Inputs
115116
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "STEPS", MotionBlocks::STEPS));
@@ -123,6 +124,9 @@ TEST_F(MotionBlocksTest, RegisterBlocks)
123124
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "DX", MotionBlocks::DX));
124125
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "DY", MotionBlocks::DY));
125126

127+
// Fields
128+
EXPECT_CALL(m_engineMock, addField(m_section.get(), "STYLE", MotionBlocks::STYLE));
129+
126130
m_section->registerBlocks(&m_engineMock);
127131
}
128132

@@ -1082,3 +1086,70 @@ TEST_F(MotionBlocksTest, SetYImpl)
10821086
ASSERT_EQ(vm.registerCount(), 0);
10831087
ASSERT_EQ(sprite.y(), 189.42);
10841088
}
1089+
1090+
TEST_F(MotionBlocksTest, SetRotationStyle)
1091+
{
1092+
Compiler compiler(&m_engineMock);
1093+
1094+
// set rotation style [left-right]
1095+
auto block1 = std::make_shared<Block>("a", "motion_setrotationstyle");
1096+
addDropdownField(block1, "STYLE", MotionBlocks::STYLE, "left-right", MotionBlocks::LeftRight);
1097+
1098+
// set rotation style [don't rotate]
1099+
auto block2 = std::make_shared<Block>("b", "motion_setrotationstyle");
1100+
addDropdownField(block2, "STYLE", MotionBlocks::STYLE, "don't rotate", MotionBlocks::DoNotRotate);
1101+
1102+
// set rotation style [all around]
1103+
auto block3 = std::make_shared<Block>("c", "motion_setrotationstyle");
1104+
addDropdownField(block3, "STYLE", MotionBlocks::STYLE, "all around", MotionBlocks::AllAround);
1105+
1106+
compiler.init();
1107+
1108+
EXPECT_CALL(m_engineMock, functionIndex(&MotionBlocks::setLeftRightRotationStyle)).WillOnce(Return(0));
1109+
compiler.setBlock(block1);
1110+
MotionBlocks::compileSetRotationStyle(&compiler);
1111+
1112+
EXPECT_CALL(m_engineMock, functionIndex(&MotionBlocks::setDoNotRotateRotationStyle)).WillOnce(Return(1));
1113+
compiler.setBlock(block2);
1114+
MotionBlocks::compileSetRotationStyle(&compiler);
1115+
1116+
EXPECT_CALL(m_engineMock, functionIndex(&MotionBlocks::setAllAroundRotationStyle)).WillOnce(Return(2));
1117+
compiler.setBlock(block3);
1118+
MotionBlocks::compileSetRotationStyle(&compiler);
1119+
1120+
compiler.end();
1121+
1122+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_EXEC, 0, vm::OP_EXEC, 1, vm::OP_EXEC, 2, vm::OP_HALT }));
1123+
ASSERT_TRUE(compiler.constValues().empty());
1124+
}
1125+
1126+
TEST_F(MotionBlocksTest, SetRotationStyleImpl)
1127+
{
1128+
static unsigned int bytecode1[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT };
1129+
static unsigned int bytecode2[] = { vm::OP_START, vm::OP_EXEC, 1, vm::OP_HALT };
1130+
static unsigned int bytecode3[] = { vm::OP_START, vm::OP_EXEC, 2, vm::OP_HALT };
1131+
static BlockFunc functions[] = { &MotionBlocks::setLeftRightRotationStyle, &MotionBlocks::setDoNotRotateRotationStyle, &MotionBlocks::setAllAroundRotationStyle };
1132+
1133+
Sprite sprite;
1134+
1135+
VirtualMachine vm(&sprite, nullptr, nullptr);
1136+
vm.setFunctions(functions);
1137+
1138+
vm.setBytecode(bytecode1);
1139+
vm.run();
1140+
1141+
ASSERT_EQ(vm.registerCount(), 0);
1142+
ASSERT_EQ(sprite.rotationStyle(), Sprite::RotationStyle::LeftRight);
1143+
1144+
vm.setBytecode(bytecode2);
1145+
vm.run();
1146+
1147+
ASSERT_EQ(vm.registerCount(), 0);
1148+
ASSERT_EQ(sprite.rotationStyle(), Sprite::RotationStyle::DoNotRotate);
1149+
1150+
vm.setBytecode(bytecode3);
1151+
vm.run();
1152+
1153+
ASSERT_EQ(vm.registerCount(), 0);
1154+
ASSERT_EQ(sprite.rotationStyle(), Sprite::RotationStyle::AllAround);
1155+
}

0 commit comments

Comments
 (0)