Skip to content

Commit 2d19185

Browse files
committed
Implement looks_costumenumbername block
1 parent 331fd98 commit 2d19185

File tree

3 files changed

+143
-0
lines changed

3 files changed

+143
-0
lines changed

src/blocks/looksblocks.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/compiler.h>
55
#include <scratchcpp/sprite.h>
6+
#include <scratchcpp/field.h>
7+
#include <scratchcpp/costume.h>
68

79
#include "looksblocks.h"
810

@@ -21,10 +23,18 @@ void LooksBlocks::registerBlocks(IEngine *engine)
2123
engine->addCompileFunction(this, "looks_changesizeby", &compileChangeSizeBy);
2224
engine->addCompileFunction(this, "looks_setsizeto", &compileSetSizeTo);
2325
engine->addCompileFunction(this, "looks_size", &compileSize);
26+
engine->addCompileFunction(this, "looks_costumenumbername", &compileCostumeNumberName);
2427

2528
// Inputs
2629
engine->addInput(this, "CHANGE", CHANGE);
2730
engine->addInput(this, "SIZE", SIZE);
31+
32+
// Fields
33+
engine->addField(this, "NUMBER_NAME", NUMBER_NAME);
34+
35+
// Field values
36+
engine->addFieldValue(this, "number", CostumeNumber);
37+
engine->addFieldValue(this, "name", CostumeName);
2838
}
2939

3040
void LooksBlocks::compileShow(Compiler *compiler)
@@ -54,6 +64,21 @@ void LooksBlocks::compileSize(Compiler *compiler)
5464
compiler->addFunctionCall(&size);
5565
}
5666

67+
void LooksBlocks::compileCostumeNumberName(Compiler *compiler)
68+
{
69+
int option = compiler->field(NUMBER_NAME)->specialValueId();
70+
71+
switch (option) {
72+
case CostumeNumber:
73+
compiler->addFunctionCall(&costumeNumber);
74+
break;
75+
76+
case CostumeName:
77+
compiler->addFunctionCall(&costumeName);
78+
break;
79+
}
80+
}
81+
5782
unsigned int LooksBlocks::show(VirtualMachine *vm)
5883
{
5984
Sprite *sprite = dynamic_cast<Sprite *>(vm->target());
@@ -105,3 +130,28 @@ unsigned int LooksBlocks::size(VirtualMachine *vm)
105130

106131
return 0;
107132
}
133+
134+
unsigned int LooksBlocks::costumeNumber(VirtualMachine *vm)
135+
{
136+
if (Target *target = vm->target())
137+
vm->addReturnValue(target->currentCostume());
138+
else
139+
vm->addReturnValue(0);
140+
141+
return 0;
142+
}
143+
144+
unsigned int LooksBlocks::costumeName(VirtualMachine *vm)
145+
{
146+
if (Target *target = vm->target()) {
147+
auto costume = target->costumeAt(target->currentCostume() - 1);
148+
149+
if (costume)
150+
vm->addReturnValue(costume->name());
151+
else
152+
vm->addReturnValue("");
153+
} else
154+
vm->addReturnValue("");
155+
156+
return 0;
157+
}

src/blocks/looksblocks.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ class LooksBlocks : public IBlockSection
1919

2020
enum Fields
2121
{
22+
NUMBER_NAME
2223
};
2324

2425
enum FieldValues
2526
{
27+
CostumeNumber,
28+
CostumeName
2629
};
2730

2831
std::string name() const override;
@@ -34,12 +37,15 @@ class LooksBlocks : public IBlockSection
3437
static void compileChangeSizeBy(Compiler *compiler);
3538
static void compileSetSizeTo(Compiler *compiler);
3639
static void compileSize(Compiler *compiler);
40+
static void compileCostumeNumberName(Compiler *compiler);
3741

3842
static unsigned int show(VirtualMachine *vm);
3943
static unsigned int hide(VirtualMachine *vm);
4044
static unsigned int changeSizeBy(VirtualMachine *vm);
4145
static unsigned int setSizeTo(VirtualMachine *vm);
4246
static unsigned int size(VirtualMachine *vm);
47+
static unsigned int costumeNumber(VirtualMachine *vm);
48+
static unsigned int costumeName(VirtualMachine *vm);
4349
};
4450

4551
} // namespace libscratchcpp

test/blocks/looks_blocks_test.cpp

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/input.h>
44
#include <scratchcpp/field.h>
55
#include <scratchcpp/sprite.h>
6+
#include <scratchcpp/costume.h>
67
#include <enginemock.h>
78

89
#include "../common.h"
@@ -97,11 +98,19 @@ TEST_F(LooksBlocksTest, RegisterBlocks)
9798
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "looks_changesizeby", &LooksBlocks::compileChangeSizeBy));
9899
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "looks_setsizeto", &LooksBlocks::compileSetSizeTo));
99100
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "looks_size", &LooksBlocks::compileSize));
101+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "looks_costumenumbername", &LooksBlocks::compileCostumeNumberName));
100102

101103
// Inputs
102104
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "CHANGE", LooksBlocks::CHANGE));
103105
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "SIZE", LooksBlocks::SIZE));
104106

107+
// Fields
108+
EXPECT_CALL(m_engineMock, addField(m_section.get(), "NUMBER_NAME", LooksBlocks::NUMBER_NAME));
109+
110+
// Field values
111+
EXPECT_CALL(m_engineMock, addFieldValue(m_section.get(), "number", LooksBlocks::CostumeNumber));
112+
EXPECT_CALL(m_engineMock, addFieldValue(m_section.get(), "name", LooksBlocks::CostumeName));
113+
105114
m_section->registerBlocks(&m_engineMock);
106115
}
107116

@@ -296,3 +305,81 @@ TEST_F(LooksBlocksTest, SizeImpl)
296305
ASSERT_EQ(vm.registerCount(), 1);
297306
ASSERT_EQ(vm.getInput(0, 1)->toDouble(), -51.0684);
298307
}
308+
309+
TEST_F(LooksBlocksTest, CostumeNumberName)
310+
{
311+
Compiler compiler(&m_engineMock);
312+
313+
// costume [number]
314+
auto block1 = std::make_shared<Block>("a", "looks_costumenumbername");
315+
addDropdownField(block1, "NUMBER_NAME", LooksBlocks::NUMBER_NAME, "number", LooksBlocks::CostumeNumber);
316+
317+
// costume [name]
318+
auto block2 = std::make_shared<Block>("b", "looks_costumenumbername");
319+
addDropdownField(block2, "NUMBER_NAME", LooksBlocks::NUMBER_NAME, "name", LooksBlocks::CostumeName);
320+
321+
compiler.init();
322+
323+
EXPECT_CALL(m_engineMock, functionIndex(&LooksBlocks::costumeNumber)).WillOnce(Return(0));
324+
compiler.setBlock(block1);
325+
LooksBlocks::compileCostumeNumberName(&compiler);
326+
327+
EXPECT_CALL(m_engineMock, functionIndex(&LooksBlocks::costumeName)).WillOnce(Return(1));
328+
compiler.setBlock(block2);
329+
LooksBlocks::compileCostumeNumberName(&compiler);
330+
331+
compiler.end();
332+
333+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_EXEC, 0, vm::OP_EXEC, 1, vm::OP_HALT }));
334+
ASSERT_TRUE(compiler.constValues().empty());
335+
}
336+
337+
TEST_F(LooksBlocksTest, CostumeNumberNameImpl)
338+
{
339+
static unsigned int bytecode1[] = { vm::OP_START, vm::OP_EXEC, 0, vm::OP_HALT };
340+
static unsigned int bytecode2[] = { vm::OP_START, vm::OP_EXEC, 1, vm::OP_HALT };
341+
static BlockFunc functions[] = { &LooksBlocks::costumeNumber, &LooksBlocks::costumeName };
342+
343+
auto c1 = std::make_shared<Costume>("costume1", "c1", "svg");
344+
auto c2 = std::make_shared<Costume>("costume2", "c2", "svg");
345+
auto c3 = std::make_shared<Costume>("costume3", "c3", "svg");
346+
347+
Target target;
348+
target.addCostume(c1);
349+
target.addCostume(c2);
350+
target.addCostume(c3);
351+
352+
VirtualMachine vm(&target, nullptr, nullptr);
353+
vm.setFunctions(functions);
354+
355+
target.setCurrentCostume(2);
356+
357+
vm.setBytecode(bytecode1);
358+
vm.run();
359+
360+
ASSERT_EQ(vm.registerCount(), 1);
361+
ASSERT_EQ(vm.getInput(0, 1)->toDouble(), 2);
362+
363+
vm.reset();
364+
vm.setBytecode(bytecode2);
365+
vm.run();
366+
367+
ASSERT_EQ(vm.registerCount(), 1);
368+
ASSERT_EQ(vm.getInput(0, 1)->toString(), "costume2");
369+
370+
target.setCurrentCostume(3);
371+
372+
vm.reset();
373+
vm.setBytecode(bytecode1);
374+
vm.run();
375+
376+
ASSERT_EQ(vm.registerCount(), 1);
377+
ASSERT_EQ(vm.getInput(0, 1)->toDouble(), 3);
378+
379+
vm.reset();
380+
vm.setBytecode(bytecode2);
381+
vm.run();
382+
383+
ASSERT_EQ(vm.registerCount(), 1);
384+
ASSERT_EQ(vm.getInput(0, 1)->toString(), "costume3");
385+
}

0 commit comments

Comments
 (0)