Skip to content

Commit dfdaf52

Browse files
committed
Implement looks_sayforsecs block
1 parent 27a732f commit dfdaf52

File tree

3 files changed

+269
-4
lines changed

3 files changed

+269
-4
lines changed

src/blocks/looksblocks.cpp

Lines changed: 87 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212

1313
#include "looksblocks.h"
1414
#include "../engine/internal/randomgenerator.h"
15+
#include "../engine/internal/clock.h"
1516

1617
using namespace libscratchcpp;
1718

1819
IRandomGenerator *LooksBlocks::rng = nullptr;
20+
IClock *LooksBlocks::clock = nullptr;
1921

2022
std::string LooksBlocks::name() const
2123
{
@@ -25,6 +27,7 @@ std::string LooksBlocks::name() const
2527
void LooksBlocks::registerBlocks(IEngine *engine)
2628
{
2729
// Blocks
30+
engine->addCompileFunction(this, "looks_sayforsecs", &compileSayForSecs);
2831
engine->addCompileFunction(this, "looks_say", &compileSay);
2932
engine->addCompileFunction(this, "looks_show", &compileShow);
3033
engine->addCompileFunction(this, "looks_hide", &compileHide);
@@ -51,6 +54,7 @@ void LooksBlocks::registerBlocks(IEngine *engine)
5154

5255
// Inputs
5356
engine->addInput(this, "MESSAGE", MESSAGE);
57+
engine->addInput(this, "SECS", SECS);
5458
engine->addInput(this, "CHANGE", CHANGE);
5559
engine->addInput(this, "SIZE", SIZE);
5660
engine->addInput(this, "COSTUME", COSTUME);
@@ -79,6 +83,14 @@ void LooksBlocks::registerBlocks(IEngine *engine)
7983
engine->addFieldValue(this, "backward", Backward);
8084
}
8185

86+
void LooksBlocks::compileSayForSecs(Compiler *compiler)
87+
{
88+
compiler->addInput(MESSAGE);
89+
compiler->addInput(SECS);
90+
compiler->addFunctionCall(&startSayForSecs);
91+
compiler->addFunctionCall(&sayForSecs);
92+
}
93+
8294
void LooksBlocks::compileSay(Compiler *compiler)
8395
{
8496
compiler->addInput(MESSAGE);
@@ -523,15 +535,87 @@ const std::string &LooksBlocks::sizeMonitorName(Block *block)
523535
return name;
524536
}
525537

526-
unsigned int LooksBlocks::say(VirtualMachine *vm)
538+
void LooksBlocks::startWait(VirtualMachine *vm, double secs)
539+
{
540+
if (!clock)
541+
clock = Clock::instance().get();
542+
543+
auto currentTime = clock->currentSteadyTime();
544+
m_timeMap[vm] = { currentTime, secs * 1000 };
545+
vm->engine()->requestRedraw();
546+
}
547+
548+
bool LooksBlocks::wait(VirtualMachine *vm)
549+
{
550+
if (!clock)
551+
clock = Clock::instance().get();
552+
553+
auto currentTime = clock->currentSteadyTime();
554+
assert(m_timeMap.count(vm) == 1);
555+
556+
if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - m_timeMap[vm].first).count() >= m_timeMap[vm].second) {
557+
m_timeMap.erase(vm);
558+
vm->stop(true, true, false);
559+
return true;
560+
} else {
561+
vm->stop(true, true, true);
562+
return false;
563+
}
564+
}
565+
566+
void LooksBlocks::showBubble(VirtualMachine *vm, Target::BubbleType type, const std::string &text)
527567
{
528568
Target *target = vm->target();
529569

530570
if (target) {
531-
target->setBubbleType(Target::BubbleType::Say);
532-
target->setBubbleText(vm->getInput(0, 1)->toString());
571+
target->setBubbleType(type);
572+
target->setBubbleText(text);
573+
m_waitingBubbles.erase(target);
533574
}
575+
}
534576

577+
void LooksBlocks::hideBubble(Target *target)
578+
{
579+
if (!target)
580+
return;
581+
582+
target->setBubbleText("");
583+
m_waitingBubbles.erase(target);
584+
}
585+
586+
unsigned int LooksBlocks::startSayForSecs(VirtualMachine *vm)
587+
{
588+
Target *target = vm->target();
589+
590+
if (target) {
591+
showBubble(vm, Target::BubbleType::Say, vm->getInput(0, 2)->toString());
592+
m_waitingBubbles[target] = vm;
593+
startWait(vm, vm->getInput(1, 2)->toDouble());
594+
}
595+
596+
return 2;
597+
}
598+
599+
unsigned int LooksBlocks::sayForSecs(VirtualMachine *vm)
600+
{
601+
if (wait(vm)) {
602+
Target *target = vm->target();
603+
604+
if (target) {
605+
auto it = m_waitingBubbles.find(target);
606+
607+
// Clear bubble if it hasn't been changed
608+
if (it != m_waitingBubbles.cend() && it->second == vm)
609+
hideBubble(vm->target());
610+
}
611+
}
612+
613+
return 0;
614+
}
615+
616+
unsigned int LooksBlocks::say(VirtualMachine *vm)
617+
{
618+
showBubble(vm, Target::BubbleType::Say, vm->getInput(0, 1)->toString());
535619
return 1;
536620
}
537621

src/blocks/looksblocks.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,19 @@
33
#pragma once
44

55
#include <scratchcpp/iblocksection.h>
6+
#include <scratchcpp/target.h>
67
#include <vector>
8+
#include <unordered_map>
9+
#include <chrono>
710

811
namespace libscratchcpp
912
{
1013

11-
class Target;
1214
class Stage;
1315
class Value;
1416
class IGraphicsEffect;
1517
class IRandomGenerator;
18+
class IClock;
1619

1720
/*! \brief The LooksBlocks class contains the implementation of looks blocks. */
1821
class LooksBlocks : public IBlockSection
@@ -21,6 +24,7 @@ class LooksBlocks : public IBlockSection
2124
enum Inputs
2225
{
2326
MESSAGE,
27+
SECS,
2428
CHANGE,
2529
SIZE,
2630
COSTUME,
@@ -58,6 +62,7 @@ class LooksBlocks : public IBlockSection
5862

5963
void registerBlocks(IEngine *engine) override;
6064

65+
static void compileSayForSecs(Compiler *compiler);
6166
static void compileSay(Compiler *compiler);
6267
static void compileShow(Compiler *compiler);
6368
static void compileHide(Compiler *compiler);
@@ -81,7 +86,15 @@ class LooksBlocks : public IBlockSection
8186
static const std::string &backdropNumberNameMonitorName(Block *block);
8287
static const std::string &sizeMonitorName(Block *block);
8388

89+
static void startWait(VirtualMachine *vm, double secs);
90+
static bool wait(VirtualMachine *vm);
91+
static void showBubble(VirtualMachine *vm, Target::BubbleType type, const std::string &text);
92+
static void hideBubble(Target *target);
93+
94+
static unsigned int startSayForSecs(VirtualMachine *vm);
95+
static unsigned int sayForSecs(VirtualMachine *vm);
8496
static unsigned int say(VirtualMachine *vm);
97+
8598
static unsigned int show(VirtualMachine *vm);
8699
static unsigned int hide(VirtualMachine *vm);
87100

@@ -144,6 +157,9 @@ class LooksBlocks : public IBlockSection
144157
static unsigned int backdropNumber(VirtualMachine *vm);
145158
static unsigned int backdropName(VirtualMachine *vm);
146159

160+
static inline std::unordered_map<VirtualMachine *, std::pair<std::chrono::steady_clock::time_point, int>> m_timeMap;
161+
static inline std::unordered_map<Target *, VirtualMachine *> m_waitingBubbles;
162+
147163
static inline std::vector<IGraphicsEffect *> m_customGraphicsEffects;
148164
static inline IGraphicsEffect *m_colorEffect = nullptr;
149165
static inline IGraphicsEffect *m_fisheyeEffect = nullptr;
@@ -154,6 +170,7 @@ class LooksBlocks : public IBlockSection
154170
static inline IGraphicsEffect *m_ghostEffect = nullptr;
155171

156172
static IRandomGenerator *rng;
173+
static IClock *clock;
157174
};
158175

159176
} // namespace libscratchcpp

0 commit comments

Comments
 (0)