12
12
13
13
#include " looksblocks.h"
14
14
#include " ../engine/internal/randomgenerator.h"
15
+ #include " ../engine/internal/clock.h"
15
16
16
17
using namespace libscratchcpp ;
17
18
18
19
IRandomGenerator *LooksBlocks::rng = nullptr ;
20
+ IClock *LooksBlocks::clock = nullptr ;
19
21
20
22
std::string LooksBlocks::name () const
21
23
{
@@ -25,6 +27,7 @@ std::string LooksBlocks::name() const
25
27
void LooksBlocks::registerBlocks (IEngine *engine)
26
28
{
27
29
// Blocks
30
+ engine->addCompileFunction (this , " looks_sayforsecs" , &compileSayForSecs);
28
31
engine->addCompileFunction (this , " looks_say" , &compileSay);
29
32
engine->addCompileFunction (this , " looks_show" , &compileShow);
30
33
engine->addCompileFunction (this , " looks_hide" , &compileHide);
@@ -51,6 +54,7 @@ void LooksBlocks::registerBlocks(IEngine *engine)
51
54
52
55
// Inputs
53
56
engine->addInput (this , " MESSAGE" , MESSAGE);
57
+ engine->addInput (this , " SECS" , SECS);
54
58
engine->addInput (this , " CHANGE" , CHANGE);
55
59
engine->addInput (this , " SIZE" , SIZE);
56
60
engine->addInput (this , " COSTUME" , COSTUME);
@@ -79,6 +83,14 @@ void LooksBlocks::registerBlocks(IEngine *engine)
79
83
engine->addFieldValue (this , " backward" , Backward);
80
84
}
81
85
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
+
82
94
void LooksBlocks::compileSay (Compiler *compiler)
83
95
{
84
96
compiler->addInput (MESSAGE);
@@ -523,15 +535,87 @@ const std::string &LooksBlocks::sizeMonitorName(Block *block)
523
535
return name;
524
536
}
525
537
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)
527
567
{
528
568
Target *target = vm->target ();
529
569
530
570
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);
533
574
}
575
+ }
534
576
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 ());
535
619
return 1 ;
536
620
}
537
621
0 commit comments