Skip to content

Commit 546c1f3

Browse files
committed
Implement pen_setPenColorToColor block
1 parent 47abf0c commit 546c1f3

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

src/blocks/penblocks.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@ void PenBlocks::registerBlocks(IEngine *engine)
2525
engine->addCompileFunction(this, "pen_clear", &compileClear);
2626
engine->addCompileFunction(this, "pen_penDown", &compilePenDown);
2727
engine->addCompileFunction(this, "pen_penUp", &compilePenUp);
28+
engine->addCompileFunction(this, "pen_setPenColorToColor", &compileSetPenColorToColor);
2829
engine->addCompileFunction(this, "pen_changePenSizeBy", &compileChangePenSizeBy);
2930
engine->addCompileFunction(this, "pen_setPenSizeTo", &compileSetPenSizeTo);
3031

3132
// Inputs
33+
engine->addInput(this, "COLOR", COLOR);
3234
engine->addInput(this, "SIZE", SIZE);
3335
}
3436

@@ -47,6 +49,12 @@ void PenBlocks::compilePenUp(Compiler *compiler)
4749
compiler->addFunctionCall(&penUp);
4850
}
4951

52+
void PenBlocks::compileSetPenColorToColor(libscratchcpp::Compiler *compiler)
53+
{
54+
compiler->addInput(COLOR);
55+
compiler->addFunctionCall(&setPenColorToColor);
56+
}
57+
5058
void PenBlocks::compileChangePenSizeBy(libscratchcpp::Compiler *compiler)
5159
{
5260
compiler->addInput(SIZE);
@@ -111,6 +119,41 @@ unsigned int PenBlocks::setPenSizeTo(libscratchcpp::VirtualMachine *vm)
111119
return 1;
112120
}
113121

122+
unsigned int PenBlocks::setPenColorToColor(libscratchcpp::VirtualMachine *vm)
123+
{
124+
SpriteModel *model = getSpriteModel(vm);
125+
126+
if (model) {
127+
const Value *value = vm->getInput(0, 1);
128+
std::string stringValue;
129+
PenAttributes &attributes = model->penAttributes();
130+
131+
if (value->isString())
132+
stringValue = value->toString();
133+
134+
if (!stringValue.empty() && stringValue[0] == '#') {
135+
bool valid = false;
136+
137+
if (stringValue.size() <= 7) // #RRGGBB
138+
{
139+
attributes.color = QColor::fromString(stringValue);
140+
valid = attributes.color.isValid();
141+
}
142+
143+
if (!valid)
144+
attributes.color = QColor(0, 0, 0);
145+
146+
} else {
147+
attributes.color = QColor::fromRgba(static_cast<QRgb>(value->toLong()));
148+
149+
if (attributes.color.alpha() == 0)
150+
attributes.color.setAlpha(255);
151+
}
152+
}
153+
154+
return 1;
155+
}
156+
114157
SpriteModel *PenBlocks::getSpriteModel(libscratchcpp::VirtualMachine *vm)
115158
{
116159
Target *target = vm->target();

src/blocks/penblocks.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class PenBlocks : public libscratchcpp::IBlockSection
1414
public:
1515
enum Inputs
1616
{
17+
COLOR,
1718
SIZE
1819
};
1920

@@ -24,12 +25,14 @@ class PenBlocks : public libscratchcpp::IBlockSection
2425
static void compileClear(libscratchcpp::Compiler *compiler);
2526
static void compilePenDown(libscratchcpp::Compiler *compiler);
2627
static void compilePenUp(libscratchcpp::Compiler *compiler);
28+
static void compileSetPenColorToColor(libscratchcpp::Compiler *compiler);
2729
static void compileChangePenSizeBy(libscratchcpp::Compiler *compiler);
2830
static void compileSetPenSizeTo(libscratchcpp::Compiler *compiler);
2931

3032
static unsigned int clear(libscratchcpp::VirtualMachine *vm);
3133
static unsigned int penDown(libscratchcpp::VirtualMachine *vm);
3234
static unsigned int penUp(libscratchcpp::VirtualMachine *vm);
35+
static unsigned int setPenColorToColor(libscratchcpp::VirtualMachine *vm);
3336
static unsigned int changePenSizeBy(libscratchcpp::VirtualMachine *vm);
3437
static unsigned int setPenSizeTo(libscratchcpp::VirtualMachine *vm);
3538

test/blocks/pen_blocks_test.cpp

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,10 +64,12 @@ TEST_F(PenBlocksTest, RegisterBlocks)
6464
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_clear", &PenBlocks::compileClear));
6565
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_penDown", &PenBlocks::compilePenDown));
6666
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_penUp", &PenBlocks::compilePenUp));
67+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_setPenColorToColor", &PenBlocks::compileSetPenColorToColor));
6768
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_changePenSizeBy", &PenBlocks::compileChangePenSizeBy));
6869
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "pen_setPenSizeTo", &PenBlocks::compileSetPenSizeTo));
6970

7071
// Inputs
72+
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "COLOR", PenBlocks::COLOR));
7173
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "SIZE", PenBlocks::SIZE));
7274

7375
m_section->registerBlocks(&m_engineMock);
@@ -193,6 +195,99 @@ TEST_F(PenBlocksTest, PenUpImpl)
193195
ASSERT_FALSE(model.penDown());
194196
}
195197

198+
TEST_F(PenBlocksTest, SetPenColorToColor)
199+
{
200+
Compiler compiler(&m_engineMock);
201+
202+
// set pen color to ("#AABBCC")
203+
auto block1 = std::make_shared<Block>("a", "pen_setPenColorToColor");
204+
addValueInput(block1, "COLOR", PenBlocks::COLOR, "#AABBCC");
205+
206+
// set pen color to (null block)
207+
auto block2 = std::make_shared<Block>("b", "pen_setPenColorToColor");
208+
addObscuredInput(block2, "COLOR", PenBlocks::COLOR, createNullBlock("c"));
209+
210+
compiler.init();
211+
212+
EXPECT_CALL(m_engineMock, functionIndex(&PenBlocks::setPenColorToColor)).WillOnce(Return(2));
213+
compiler.setBlock(block1);
214+
PenBlocks::compileSetPenColorToColor(&compiler);
215+
216+
EXPECT_CALL(m_engineMock, functionIndex(&PenBlocks::setPenColorToColor)).WillOnce(Return(2));
217+
compiler.setBlock(block2);
218+
PenBlocks::compileSetPenColorToColor(&compiler);
219+
220+
compiler.end();
221+
222+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 2, vm::OP_NULL, vm::OP_EXEC, 2, vm::OP_HALT }));
223+
ASSERT_EQ(compiler.constValues().size(), 1);
224+
ASSERT_EQ(compiler.constValues()[0].toString(), "#AABBCC");
225+
ASSERT_TRUE(compiler.variables().empty());
226+
ASSERT_TRUE(compiler.lists().empty());
227+
}
228+
229+
TEST_F(PenBlocksTest, SetPenColorToColorImpl)
230+
{
231+
static unsigned int bytecode1[] = { vm::OP_START, vm::OP_CONST, 0, vm::OP_EXEC, 0, vm::OP_HALT };
232+
static unsigned int bytecode2[] = { vm::OP_START, vm::OP_CONST, 1, vm::OP_EXEC, 0, vm::OP_HALT };
233+
static unsigned int bytecode3[] = { vm::OP_START, vm::OP_CONST, 2, vm::OP_EXEC, 0, vm::OP_HALT };
234+
static unsigned int bytecode4[] = { vm::OP_START, vm::OP_CONST, 3, vm::OP_EXEC, 0, vm::OP_HALT };
235+
static unsigned int bytecode5[] = { vm::OP_START, vm::OP_CONST, 4, vm::OP_EXEC, 0, vm::OP_HALT };
236+
static unsigned int bytecode6[] = { vm::OP_START, vm::OP_CONST, 5, vm::OP_EXEC, 0, vm::OP_HALT };
237+
static unsigned int bytecode7[] = { vm::OP_START, vm::OP_CONST, 6, vm::OP_EXEC, 0, vm::OP_HALT };
238+
static BlockFunc functions[] = { &PenBlocks::setPenColorToColor };
239+
static Value constValues[] = { "#AABbCC", "#03F", "#FFGFFF", "#AABBCCDD", "FFFFFF", 1228097602, 255 };
240+
241+
SpriteModel model;
242+
Sprite sprite;
243+
sprite.setInterface(&model);
244+
245+
VirtualMachine vm(&sprite, &m_engineMock, nullptr);
246+
vm.setBytecode(bytecode1);
247+
vm.setFunctions(functions);
248+
vm.setConstValues(constValues);
249+
250+
vm.run();
251+
ASSERT_EQ(vm.registerCount(), 0);
252+
ASSERT_EQ(model.penAttributes().color, QColor(170, 187, 204));
253+
254+
vm.reset();
255+
vm.setBytecode(bytecode2);
256+
vm.run();
257+
ASSERT_EQ(vm.registerCount(), 0);
258+
ASSERT_EQ(model.penAttributes().color, QColor(0, 51, 255));
259+
260+
vm.reset();
261+
vm.setBytecode(bytecode3);
262+
vm.run();
263+
ASSERT_EQ(vm.registerCount(), 0);
264+
ASSERT_EQ(model.penAttributes().color, QColor(0, 0, 0));
265+
266+
vm.reset();
267+
vm.setBytecode(bytecode4);
268+
vm.run();
269+
ASSERT_EQ(vm.registerCount(), 0);
270+
ASSERT_EQ(model.penAttributes().color, QColor(0, 0, 0));
271+
272+
vm.reset();
273+
vm.setBytecode(bytecode5);
274+
vm.run();
275+
ASSERT_EQ(vm.registerCount(), 0);
276+
ASSERT_EQ(model.penAttributes().color, QColor(0, 0, 0));
277+
278+
vm.reset();
279+
vm.setBytecode(bytecode6);
280+
vm.run();
281+
ASSERT_EQ(vm.registerCount(), 0);
282+
ASSERT_EQ(model.penAttributes().color, QColor::fromRgba(1228097602));
283+
284+
vm.reset();
285+
vm.setBytecode(bytecode7);
286+
vm.run();
287+
ASSERT_EQ(vm.registerCount(), 0);
288+
ASSERT_EQ(model.penAttributes().color, QColor::fromRgb(255));
289+
}
290+
196291
TEST_F(PenBlocksTest, ChangePenSizeBy)
197292
{
198293
Compiler compiler(&m_engineMock);

0 commit comments

Comments
 (0)