Skip to content

Commit 12e6418

Browse files
committed
Implement event_broadcast
1 parent 11efc63 commit 12e6418

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

src/dev/blocks/eventblocks.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
#include <scratchcpp/block.h>
66
#include <scratchcpp/field.h>
77
#include <scratchcpp/broadcast.h>
8+
#include <scratchcpp/dev/executioncontext.h>
9+
#include <scratchcpp/thread.h>
810

911
#include "eventblocks.h"
1012

@@ -29,6 +31,7 @@ void EventBlocks::registerBlocks(IEngine *engine)
2931
engine->addCompileFunction(this, "event_whenbroadcastreceived", &compileWhenBroadcastReceived);
3032
engine->addCompileFunction(this, "event_whenbackdropswitchesto", &compileWhenBackdropSwitchesTo);
3133
engine->addCompileFunction(this, "event_whengreaterthan", &compileWhenGreaterThan);
34+
engine->addCompileFunction(this, "event_broadcast", &compileBroadcast);
3235
}
3336

3437
CompilerValue *EventBlocks::compileWhenTouchingObject(Compiler *compiler)
@@ -84,3 +87,20 @@ CompilerValue *EventBlocks::compileWhenGreaterThan(Compiler *compiler)
8487
compiler->engine()->addWhenGreaterThanScript(compiler->block());
8588
return nullptr;
8689
}
90+
91+
CompilerValue *EventBlocks::compileBroadcast(Compiler *compiler)
92+
{
93+
auto input = compiler->addInput("BROADCAST_INPUT");
94+
compiler->addFunctionCallWithCtx("event_broadcast", Compiler::StaticType::Void, { Compiler::StaticType::String }, { input });
95+
return nullptr;
96+
}
97+
98+
extern "C" void event_broadcast(ExecutionContext *ctx, const char *name)
99+
{
100+
Thread *thread = ctx->thread();
101+
IEngine *engine = thread->engine();
102+
std::vector<int> broadcasts = engine->findBroadcasts(name);
103+
104+
for (int index : broadcasts)
105+
engine->broadcast(index, thread, false);
106+
}

src/dev/blocks/eventblocks.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class EventBlocks : public IExtension
2323
static CompilerValue *compileWhenBroadcastReceived(Compiler *compiler);
2424
static CompilerValue *compileWhenBackdropSwitchesTo(Compiler *compiler);
2525
static CompilerValue *compileWhenGreaterThan(Compiler *compiler);
26+
static CompilerValue *compileBroadcast(Compiler *compiler);
2627
};
2728

2829
} // namespace libscratchcpp

test/dev/blocks/event_blocks_test.cpp

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
#include <scratchcpp/sprite.h>
55
#include <scratchcpp/broadcast.h>
66
#include <scratchcpp/block.h>
7+
#include <scratchcpp/script.h>
8+
#include <scratchcpp/thread.h>
9+
#include <scratchcpp/dev/executablecode.h>
710
#include <enginemock.h>
811

912
#include "../common.h"
@@ -12,6 +15,8 @@
1215
using namespace libscratchcpp;
1316
using namespace libscratchcpp::test;
1417

18+
using ::testing::Return;
19+
1520
class EventBlocksTest : public testing::Test
1621
{
1722
public:
@@ -130,3 +135,50 @@ TEST_F(EventBlocksTest, WhenGreaterThan)
130135
EXPECT_CALL(m_engineMock, addWhenGreaterThanScript(block));
131136
compiler.compile(block);
132137
}
138+
139+
TEST_F(EventBlocksTest, Broadcast)
140+
{
141+
auto broadcast = std::make_shared<Broadcast>("", "test");
142+
m_engine->setBroadcasts({ broadcast });
143+
144+
auto target = std::make_shared<Sprite>();
145+
ScriptBuilder builder(m_extension.get(), m_engine, target);
146+
147+
builder.addBlock("event_broadcast");
148+
builder.addEntityInput("BROADCAST_INPUT", "test", InputValue::Type::Broadcast, broadcast);
149+
auto block1 = builder.currentBlock();
150+
151+
builder.addBlock("event_broadcast");
152+
builder.addNullObscuredInput("BROADCAST_INPUT");
153+
auto block2 = builder.currentBlock();
154+
155+
block1->setNext(nullptr);
156+
block2->setParent(nullptr);
157+
158+
{
159+
Compiler compiler(&m_engineMock, target.get());
160+
auto code = compiler.compile(block1);
161+
Script script(target.get(), block1, &m_engineMock);
162+
script.setCode(code);
163+
Thread thread(target.get(), &m_engineMock, &script);
164+
165+
EXPECT_CALL(m_engineMock, findBroadcasts("test")).WillOnce(Return(std::vector<int>({ 1, 4 })));
166+
EXPECT_CALL(m_engineMock, broadcast(1, &thread, false));
167+
EXPECT_CALL(m_engineMock, broadcast(4, &thread, false));
168+
thread.run();
169+
}
170+
171+
{
172+
Compiler compiler(&m_engineMock, target.get());
173+
auto code = compiler.compile(block2);
174+
Script script(target.get(), block2, &m_engineMock);
175+
script.setCode(code);
176+
Thread thread(target.get(), &m_engineMock, &script);
177+
178+
EXPECT_CALL(m_engineMock, findBroadcasts("0")).WillOnce(Return(std::vector<int>({ 5, 7, 8 })));
179+
EXPECT_CALL(m_engineMock, broadcast(5, &thread, false));
180+
EXPECT_CALL(m_engineMock, broadcast(7, &thread, false));
181+
EXPECT_CALL(m_engineMock, broadcast(8, &thread, false));
182+
thread.run();
183+
}
184+
}

0 commit comments

Comments
 (0)