Skip to content

Commit 53414c3

Browse files
authored
Merge pull request #252 from scratchcpp/switch_backdrop_and_wait
Implement switch backdrop and wait block
2 parents 0838494 + 0a6bfc7 commit 53414c3

File tree

17 files changed

+1078
-65
lines changed

17 files changed

+1078
-65
lines changed

include/scratchcpp/costume.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
namespace libscratchcpp
1010
{
1111

12+
class Broadcast;
1213
class CostumePrivate;
1314

1415
/*! \brief The Costume class represents a Scratch costume. */
@@ -27,6 +28,8 @@ class LIBSCRATCHCPP_EXPORT Costume : public Asset
2728
int rotationCenterY() const;
2829
void setRotationCenterY(int newRotationCenterY);
2930

31+
Broadcast *broadcast();
32+
3033
private:
3134
spimpl::unique_impl_ptr<CostumePrivate> impl;
3235
};

include/scratchcpp/iengine.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
6565
/*! Starts the script of the broadcast with the given index. */
6666
virtual void broadcast(unsigned int index, VirtualMachine *sourceScript, bool wait = false) = 0;
6767

68+
/*! Starts the script of the given broadcast. */
69+
virtual void broadcastByPtr(Broadcast *broadcast, VirtualMachine *sourceScript, bool wait = false) = 0;
70+
6871
/*! Stops the given script. */
6972
virtual void stopScript(VirtualMachine *vm) = 0;
7073

@@ -122,6 +125,9 @@ class LIBSCRATCHCPP_EXPORT IEngine
122125
/*! Returns true if there are any running script of the broadcast with the given index. */
123126
virtual bool broadcastRunning(unsigned int index, VirtualMachine *sourceScript) = 0;
124127

128+
/*! Returns true if there are any running script of the given broadcast. */
129+
virtual bool broadcastByPtrRunning(Broadcast *broadcast, VirtualMachine *sourceScript) = 0;
130+
125131
/*!
126132
* Call this from a block implementation to force a "screen refresh".
127133
* \note This has no effect in "run without screen refresh" custom blocks.
@@ -199,7 +205,7 @@ class LIBSCRATCHCPP_EXPORT IEngine
199205
virtual int findBroadcastById(const std::string &broadcastId) const = 0;
200206

201207
/*! Registers the broadcast script. */
202-
virtual void addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, std::shared_ptr<Broadcast> broadcast) = 0;
208+
virtual void addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, Broadcast *broadcast) = 0;
203209

204210
/* Registers the given "when I start as clone" script. */
205211
virtual void addCloneInitScript(std::shared_ptr<Block> hatBlock) = 0;

src/blocks/eventblocks.cpp

Lines changed: 16 additions & 1 deletion
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)
@@ -66,7 +70,18 @@ void EventBlocks::compileWhenBroadcastReceived(Compiler *compiler)
6670
{
6771
auto broadcast = std::static_pointer_cast<Broadcast>(compiler->field(BROADCAST_OPTION)->valuePtr());
6872

69-
compiler->engine()->addBroadcastScript(compiler->block(), broadcast);
73+
compiler->engine()->addBroadcastScript(compiler->block(), broadcast.get());
74+
}
75+
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+
}
7085
}
7186

7287
unsigned int EventBlocks::broadcast(VirtualMachine *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);

src/blocks/looksblocks.cpp

Lines changed: 147 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ void LooksBlocks::registerBlocks(IEngine *engine)
3131
engine->addCompileFunction(this, "looks_switchcostumeto", &compileSwitchCostumeTo);
3232
engine->addCompileFunction(this, "looks_nextcostume", &compileNextCostume);
3333
engine->addCompileFunction(this, "looks_switchbackdropto", &compileSwitchBackdropTo);
34+
engine->addCompileFunction(this, "looks_switchbackdroptoandwait", &compileSwitchBackdropToAndWait);
3435
engine->addCompileFunction(this, "looks_nextbackdrop", &compileNextBackdrop);
3536
engine->addCompileFunction(this, "looks_costumenumbername", &compileCostumeNumberName);
3637
engine->addCompileFunction(this, "looks_backdropnumbername", &compileBackdropNumberName);
@@ -157,6 +158,47 @@ void LooksBlocks::compileSwitchBackdropTo(Compiler *compiler)
157158
}
158159
}
159160

161+
void LooksBlocks::compileSwitchBackdropToAndWait(Compiler *compiler)
162+
{
163+
Stage *stage = compiler->engine()->stage();
164+
165+
if (!stage)
166+
return;
167+
168+
Input *input = compiler->input(BACKDROP);
169+
170+
if (input->type() != Input::Type::ObscuredShadow) {
171+
assert(input->pointsToDropdownMenu());
172+
std::string value = input->selectedMenuItem();
173+
int index = stage->findCostume(value);
174+
175+
if (index == -1) {
176+
if (value == "next backdrop")
177+
compiler->addFunctionCall(&nextBackdropAndWait);
178+
else if (value == "previous backdrop")
179+
compiler->addFunctionCall(&previousBackdropAndWait);
180+
else if (value == "random backdrop")
181+
compiler->addFunctionCall(&randomBackdropAndWait);
182+
else {
183+
Value v(value);
184+
185+
if (v.type() == Value::Type::Integer) {
186+
compiler->addConstValue(v.toLong() - 1);
187+
compiler->addFunctionCall(&switchBackdropToByIndexAndWait);
188+
}
189+
}
190+
} else {
191+
compiler->addConstValue(index);
192+
compiler->addFunctionCall(&switchBackdropToByIndexAndWait);
193+
}
194+
} else {
195+
compiler->addInput(input);
196+
compiler->addFunctionCall(&switchBackdropToAndWait);
197+
}
198+
199+
compiler->addFunctionCall(&checkBackdropScripts);
200+
}
201+
160202
void LooksBlocks::compileNextBackdrop(Compiler *compiler)
161203
{
162204
compiler->addFunctionCall(&nextBackdrop);
@@ -308,59 +350,59 @@ unsigned int LooksBlocks::previousCostume(VirtualMachine *vm)
308350
return 0;
309351
}
310352

311-
unsigned int LooksBlocks::switchBackdropToByIndex(VirtualMachine *vm)
353+
void LooksBlocks::startBackdropScripts(VirtualMachine *vm, bool wait)
354+
{
355+
if (Stage *stage = vm->engine()->stage()) {
356+
if (stage->costumes().size() > 0)
357+
vm->engine()->broadcastByPtr(stage->costumeAt(stage->currentCostume() - 1)->broadcast(), vm, wait);
358+
}
359+
}
360+
361+
void LooksBlocks::switchBackdropToByIndexImpl(VirtualMachine *vm)
312362
{
313363
if (Stage *stage = vm->engine()->stage())
314364
setCostumeByIndex(stage, vm->getInput(0, 1)->toLong());
315-
316-
return 1;
317365
}
318366

319-
unsigned int LooksBlocks::switchBackdropTo(VirtualMachine *vm)
367+
void LooksBlocks::switchBackdropToImpl(VirtualMachine *vm)
320368
{
321369
Stage *stage = vm->engine()->stage();
322370

323371
if (!stage)
324-
return 1;
372+
return;
325373

326374
const Value *name = vm->getInput(0, 1);
327375
std::string nameStr = name->toString();
328376
int index = stage->findCostume(nameStr);
329377

330378
if (index == -1) {
331379
if (nameStr == "next backdrop")
332-
nextBackdrop(vm);
380+
nextBackdropImpl(vm);
333381
else if (nameStr == "previous backdrop")
334-
previousBackdrop(vm);
382+
previousBackdropImpl(vm);
335383
else if (nameStr == "random backdrop") {
336-
randomBackdrop(vm);
384+
randomBackdropImpl(vm);
337385
} else {
338386
if (name->type() == Value::Type::Integer)
339387
setCostumeByIndex(stage, name->toLong() - 1);
340388
}
341389
} else
342390
setCostumeByIndex(stage, index);
343-
344-
return 1;
345391
}
346392

347-
unsigned int LooksBlocks::nextBackdrop(VirtualMachine *vm)
393+
void LooksBlocks::nextBackdropImpl(VirtualMachine *vm)
348394
{
349395
if (Stage *stage = vm->engine()->stage())
350396
setCostumeByIndex(stage, stage->currentCostume());
351-
352-
return 0;
353397
}
354398

355-
unsigned int LooksBlocks::previousBackdrop(VirtualMachine *vm)
399+
void LooksBlocks::previousBackdropImpl(VirtualMachine *vm)
356400
{
357401
if (Stage *stage = vm->engine()->stage())
358402
setCostumeByIndex(stage, stage->currentCostume() - 2);
359-
360-
return 0;
361403
}
362404

363-
unsigned int LooksBlocks::randomBackdrop(VirtualMachine *vm)
405+
void LooksBlocks::randomBackdropImpl(VirtualMachine *vm)
364406
{
365407
if (!rng)
366408
rng = RandomGenerator::instance().get();
@@ -371,6 +413,94 @@ unsigned int LooksBlocks::randomBackdrop(VirtualMachine *vm)
371413
if (count > 0)
372414
stage->setCurrentCostume(rng->randint(1, count));
373415
}
416+
}
417+
418+
unsigned int LooksBlocks::switchBackdropToByIndex(VirtualMachine *vm)
419+
{
420+
switchBackdropToByIndexImpl(vm);
421+
startBackdropScripts(vm, false);
422+
423+
return 1;
424+
}
425+
426+
unsigned int LooksBlocks::switchBackdropTo(VirtualMachine *vm)
427+
{
428+
switchBackdropToImpl(vm);
429+
startBackdropScripts(vm, false);
430+
431+
return 1;
432+
}
433+
434+
unsigned int LooksBlocks::switchBackdropToByIndexAndWait(VirtualMachine *vm)
435+
{
436+
switchBackdropToByIndexImpl(vm);
437+
startBackdropScripts(vm, true);
438+
439+
return 1;
440+
}
441+
442+
unsigned int LooksBlocks::switchBackdropToAndWait(VirtualMachine *vm)
443+
{
444+
switchBackdropToImpl(vm);
445+
startBackdropScripts(vm, true);
446+
447+
return 1;
448+
}
449+
450+
unsigned int LooksBlocks::nextBackdrop(VirtualMachine *vm)
451+
{
452+
nextBackdropImpl(vm);
453+
startBackdropScripts(vm, false);
454+
455+
return 0;
456+
}
457+
458+
unsigned int LooksBlocks::nextBackdropAndWait(VirtualMachine *vm)
459+
{
460+
nextBackdropImpl(vm);
461+
startBackdropScripts(vm, true);
462+
463+
return 0;
464+
}
465+
466+
unsigned int LooksBlocks::previousBackdrop(VirtualMachine *vm)
467+
{
468+
previousBackdropImpl(vm);
469+
startBackdropScripts(vm, false);
470+
471+
return 0;
472+
}
473+
474+
unsigned int LooksBlocks::previousBackdropAndWait(VirtualMachine *vm)
475+
{
476+
previousBackdropImpl(vm);
477+
startBackdropScripts(vm, true);
478+
479+
return 0;
480+
}
481+
482+
unsigned int LooksBlocks::randomBackdrop(VirtualMachine *vm)
483+
{
484+
randomBackdropImpl(vm);
485+
startBackdropScripts(vm, false);
486+
487+
return 0;
488+
}
489+
490+
unsigned int LooksBlocks::randomBackdropAndWait(VirtualMachine *vm)
491+
{
492+
randomBackdropImpl(vm);
493+
startBackdropScripts(vm, true);
494+
495+
return 0;
496+
}
497+
498+
unsigned int LooksBlocks::checkBackdropScripts(VirtualMachine *vm)
499+
{
500+
if (Stage *stage = vm->engine()->stage()) {
501+
if ((stage->costumes().size() > 0) && vm->engine()->broadcastByPtrRunning(stage->costumeAt(stage->currentCostume() - 1)->broadcast(), vm))
502+
vm->stop(true, true, true);
503+
}
374504

375505
return 0;
376506
}

src/blocks/looksblocks.h

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace libscratchcpp
88
{
99

1010
class Target;
11+
class Stage;
12+
class Value;
1113
class IRandomGenerator;
1214

1315
/*! \brief The LooksBlocks class contains the implementation of looks blocks. */
@@ -45,6 +47,7 @@ class LooksBlocks : public IBlockSection
4547
static void compileSwitchCostumeTo(Compiler *compiler);
4648
static void compileNextCostume(Compiler *compiler);
4749
static void compileSwitchBackdropTo(Compiler *compiler);
50+
static void compileSwitchBackdropToAndWait(Compiler *compiler);
4851
static void compileNextBackdrop(Compiler *compiler);
4952
static void compileCostumeNumberName(Compiler *compiler);
5053
static void compileBackdropNumberName(Compiler *compiler);
@@ -61,11 +64,24 @@ class LooksBlocks : public IBlockSection
6164
static unsigned int nextCostume(VirtualMachine *vm);
6265
static unsigned int previousCostume(VirtualMachine *vm);
6366

67+
static void startBackdropScripts(VirtualMachine *vm, bool wait);
68+
static void switchBackdropToByIndexImpl(VirtualMachine *vm);
69+
static void switchBackdropToImpl(VirtualMachine *vm);
70+
static void nextBackdropImpl(VirtualMachine *vm);
71+
static void previousBackdropImpl(VirtualMachine *vm);
72+
static void randomBackdropImpl(VirtualMachine *vm);
73+
6474
static unsigned int switchBackdropToByIndex(VirtualMachine *vm);
6575
static unsigned int switchBackdropTo(VirtualMachine *vm);
76+
static unsigned int switchBackdropToByIndexAndWait(VirtualMachine *vm);
77+
static unsigned int switchBackdropToAndWait(VirtualMachine *vm);
6678
static unsigned int nextBackdrop(VirtualMachine *vm);
79+
static unsigned int nextBackdropAndWait(VirtualMachine *vm);
6780
static unsigned int previousBackdrop(VirtualMachine *vm);
81+
static unsigned int previousBackdropAndWait(VirtualMachine *vm);
6882
static unsigned int randomBackdrop(VirtualMachine *vm);
83+
static unsigned int randomBackdropAndWait(VirtualMachine *vm);
84+
static unsigned int checkBackdropScripts(VirtualMachine *vm);
6985

7086
static unsigned int costumeNumber(VirtualMachine *vm);
7187
static unsigned int costumeName(VirtualMachine *vm);

0 commit comments

Comments
 (0)