Skip to content

Commit 500feb0

Browse files
committed
Implement event_whenbackdropswitchesto block
1 parent 81c9307 commit 500feb0

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

src/blocks/eventblocks.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#include <scratchcpp/input.h>
77
#include <scratchcpp/inputvalue.h>
88
#include <scratchcpp/field.h>
9+
#include <scratchcpp/stage.h>
10+
#include <scratchcpp/costume.h>
911

1012
#include "eventblocks.h"
1113

@@ -23,12 +25,14 @@ void EventBlocks::registerBlocks(IEngine *engine)
2325
engine->addCompileFunction(this, "event_broadcast", &compileBroadcast);
2426
engine->addCompileFunction(this, "event_broadcastandwait", &compileBroadcastAndWait);
2527
engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived);
28+
engine->addCompileFunction(this, "event_whenbackdropswitchesto", &compileWhenBackdropSwitchesTo);
2629

2730
// Inputs
2831
engine->addInput(this, "BROADCAST_INPUT", BROADCAST_INPUT);
2932

3033
// Fields
3134
engine->addField(this, "BROADCAST_OPTION", BROADCAST_OPTION);
35+
engine->addField(this, "BACKDROP", BACKDROP);
3236
}
3337

3438
void EventBlocks::compileBroadcast(Compiler *compiler)
@@ -69,6 +73,17 @@ void EventBlocks::compileWhenBroadcastReceived(Compiler *compiler)
6973
compiler->engine()->addBroadcastScript(compiler->block(), broadcast.get());
7074
}
7175

76+
void EventBlocks::compileWhenBackdropSwitchesTo(Compiler *compiler)
77+
{
78+
if (Stage *stage = compiler->engine()->stage()) {
79+
std::string backdropName = compiler->field(BACKDROP)->value().toString();
80+
int index = stage->findCostume(backdropName);
81+
82+
if (index != -1)
83+
compiler->engine()->addBroadcastScript(compiler->block(), stage->costumeAt(index)->broadcast());
84+
}
85+
}
86+
7287
unsigned int EventBlocks::broadcast(VirtualMachine *vm)
7388
{
7489
vm->engine()->broadcast(vm->engine()->findBroadcast(vm->getInput(0, 1)->toString()), vm);

src/blocks/eventblocks.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ class EventBlocks : public IBlockSection
2121

2222
enum Fields
2323
{
24-
BROADCAST_OPTION
24+
BROADCAST_OPTION,
25+
BACKDROP
2526
};
2627

2728
std::string name() const override;
@@ -31,6 +32,7 @@ class EventBlocks : public IBlockSection
3132
static void compileBroadcast(Compiler *compiler);
3233
static void compileBroadcastAndWait(Compiler *compiler);
3334
static void compileWhenBroadcastReceived(Compiler *compiler);
35+
static void compileWhenBackdropSwitchesTo(Compiler *compiler);
3436

3537
static unsigned int broadcast(VirtualMachine *vm);
3638
static unsigned int broadcastByIndex(VirtualMachine *vm);

test/blocks/event_blocks_test.cpp

Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include <scratchcpp/inputvalue.h>
55
#include <scratchcpp/field.h>
66
#include <scratchcpp/broadcast.h>
7+
#include <scratchcpp/stage.h>
8+
#include <scratchcpp/costume.h>
79
#include <enginemock.h>
810

911
#include "../common.h"
@@ -50,6 +52,14 @@ class EventBlocksTest : public testing::Test
5052
block->updateInputMap();
5153
}
5254

55+
void addValueField(std::shared_ptr<Block> block, const std::string &name, EventBlocks::Fields id, const std::string &value) const
56+
{
57+
auto field = std::make_shared<Field>(name, value);
58+
field->setFieldId(id);
59+
block->addField(field);
60+
block->updateFieldMap();
61+
}
62+
5363
void addBroadcastField(std::shared_ptr<Block> block, const std::string &name, EventBlocks::Fields id, std::shared_ptr<Broadcast> broadcast) const
5464
{
5565
auto field = std::make_shared<Field>(name, Value(), broadcast);
@@ -77,16 +87,18 @@ TEST_F(EventBlocksTest, CategoryVisible)
7787
TEST_F(EventBlocksTest, RegisterBlocks)
7888
{
7989
// Blocks
80-
EXPECT_CALL(m_engineMock, addHatBlock(m_section.get(), "event_whenflagclicked")).Times(1);
81-
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcast", &EventBlocks::compileBroadcast)).Times(1);
82-
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcastandwait", &EventBlocks::compileBroadcastAndWait)).Times(1);
83-
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_whenbroadcastreceived", &EventBlocks::compileWhenBroadcastReceived)).Times(1);
90+
EXPECT_CALL(m_engineMock, addHatBlock(m_section.get(), "event_whenflagclicked"));
91+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcast", &EventBlocks::compileBroadcast));
92+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_broadcastandwait", &EventBlocks::compileBroadcastAndWait));
93+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_whenbroadcastreceived", &EventBlocks::compileWhenBroadcastReceived));
94+
EXPECT_CALL(m_engineMock, addCompileFunction(m_section.get(), "event_whenbackdropswitchesto", &EventBlocks::compileWhenBackdropSwitchesTo));
8495

8596
// Inputs
8697
EXPECT_CALL(m_engineMock, addInput(m_section.get(), "BROADCAST_INPUT", EventBlocks::BROADCAST_INPUT)).Times(1);
8798

8899
// Fields
89100
EXPECT_CALL(m_engineMock, addField(m_section.get(), "BROADCAST_OPTION", EventBlocks::BROADCAST_OPTION));
101+
EXPECT_CALL(m_engineMock, addField(m_section.get(), "BACKDROP", EventBlocks::BACKDROP));
90102

91103
m_section->registerBlocks(&m_engineMock);
92104
}
@@ -233,3 +245,29 @@ TEST_F(EventBlocksTest, WhenBroadcastReceived)
233245
ASSERT_TRUE(compiler.variables().empty());
234246
ASSERT_TRUE(compiler.lists().empty());
235247
}
248+
249+
TEST_F(EventBlocksTest, WhenBackdropSwitchesTo)
250+
{
251+
Compiler compiler(&m_engineMock);
252+
Stage stage;
253+
254+
// when backdrop switches to "backdrop2"
255+
auto block1 = createEventBlock("a", "event_whenbackdropswitchesto");
256+
addValueField(block1, "BACKDROP", EventBlocks::BACKDROP, "backdrop2");
257+
258+
auto backdrop = std::make_shared<Costume>("backdrop2", "a", "svg");
259+
stage.addCostume(backdrop);
260+
261+
EXPECT_CALL(m_engineMock, stage()).WillOnce(Return(&stage));
262+
EXPECT_CALL(m_engineMock, addBroadcastScript(block1, backdrop->broadcast()));
263+
264+
compiler.init();
265+
compiler.setBlock(block1);
266+
EventBlocks::compileWhenBackdropSwitchesTo(&compiler);
267+
compiler.end();
268+
269+
ASSERT_EQ(compiler.bytecode(), std::vector<unsigned int>({ vm::OP_START, vm::OP_HALT }));
270+
ASSERT_TRUE(compiler.constValues().empty());
271+
ASSERT_TRUE(compiler.variables().empty());
272+
ASSERT_TRUE(compiler.lists().empty());
273+
}

0 commit comments

Comments
 (0)