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,10 @@ std::string LooksBlocks::name() const
25
27
void LooksBlocks::registerBlocks (IEngine *engine)
26
28
{
27
29
// Blocks
30
+ engine->addCompileFunction (this , " looks_sayforsecs" , &compileSayForSecs);
31
+ engine->addCompileFunction (this , " looks_say" , &compileSay);
32
+ engine->addCompileFunction (this , " looks_thinkforsecs" , &compileThinkForSecs);
33
+ engine->addCompileFunction (this , " looks_think" , &compileThink);
28
34
engine->addCompileFunction (this , " looks_show" , &compileShow);
29
35
engine->addCompileFunction (this , " looks_hide" , &compileHide);
30
36
engine->addCompileFunction (this , " looks_changeeffectby" , &compileChangeEffectBy);
@@ -49,6 +55,8 @@ void LooksBlocks::registerBlocks(IEngine *engine)
49
55
engine->addMonitorNameFunction (this , " looks_size" , &sizeMonitorName);
50
56
51
57
// Inputs
58
+ engine->addInput (this , " MESSAGE" , MESSAGE);
59
+ engine->addInput (this , " SECS" , SECS);
52
60
engine->addInput (this , " CHANGE" , CHANGE);
53
61
engine->addInput (this , " SIZE" , SIZE);
54
62
engine->addInput (this , " COSTUME" , COSTUME);
@@ -77,6 +85,34 @@ void LooksBlocks::registerBlocks(IEngine *engine)
77
85
engine->addFieldValue (this , " backward" , Backward);
78
86
}
79
87
88
+ void LooksBlocks::compileSayForSecs (Compiler *compiler)
89
+ {
90
+ compiler->addInput (MESSAGE);
91
+ compiler->addInput (SECS);
92
+ compiler->addFunctionCall (&startSayForSecs);
93
+ compiler->addFunctionCall (&sayForSecs);
94
+ }
95
+
96
+ void LooksBlocks::compileSay (Compiler *compiler)
97
+ {
98
+ compiler->addInput (MESSAGE);
99
+ compiler->addFunctionCall (&say);
100
+ }
101
+
102
+ void LooksBlocks::compileThinkForSecs (Compiler *compiler)
103
+ {
104
+ compiler->addInput (MESSAGE);
105
+ compiler->addInput (SECS);
106
+ compiler->addFunctionCall (&startThinkForSecs);
107
+ compiler->addFunctionCall (&thinkForSecs);
108
+ }
109
+
110
+ void LooksBlocks::compileThink (Compiler *compiler)
111
+ {
112
+ compiler->addInput (MESSAGE);
113
+ compiler->addFunctionCall (&think);
114
+ }
115
+
80
116
void LooksBlocks::compileShow (Compiler *compiler)
81
117
{
82
118
compiler->addFunctionCall (&show);
@@ -515,6 +551,114 @@ const std::string &LooksBlocks::sizeMonitorName(Block *block)
515
551
return name;
516
552
}
517
553
554
+ void LooksBlocks::startWait (VirtualMachine *vm, double secs)
555
+ {
556
+ if (!clock)
557
+ clock = Clock::instance ().get ();
558
+
559
+ auto currentTime = clock->currentSteadyTime ();
560
+ m_timeMap[vm] = { currentTime, secs * 1000 };
561
+ vm->engine ()->requestRedraw ();
562
+ }
563
+
564
+ bool LooksBlocks::wait (VirtualMachine *vm)
565
+ {
566
+ if (!clock)
567
+ clock = Clock::instance ().get ();
568
+
569
+ auto currentTime = clock->currentSteadyTime ();
570
+ assert (m_timeMap.count (vm) == 1 );
571
+
572
+ if (std::chrono::duration_cast<std::chrono::milliseconds>(currentTime - m_timeMap[vm].first ).count () >= m_timeMap[vm].second ) {
573
+ m_timeMap.erase (vm);
574
+ vm->stop (true , true , false );
575
+ return true ;
576
+ } else {
577
+ vm->stop (true , true , true );
578
+ return false ;
579
+ }
580
+ }
581
+
582
+ void LooksBlocks::showBubble (VirtualMachine *vm, Target::BubbleType type, const std::string &text)
583
+ {
584
+ Target *target = vm->target ();
585
+
586
+ if (target) {
587
+ target->setBubbleType (type);
588
+ target->setBubbleText (text);
589
+ m_waitingBubbles.erase (target);
590
+ }
591
+ }
592
+
593
+ void LooksBlocks::hideBubble (Target *target)
594
+ {
595
+ if (!target)
596
+ return ;
597
+
598
+ target->setBubbleText (" " );
599
+ m_waitingBubbles.erase (target);
600
+ }
601
+
602
+ unsigned int LooksBlocks::startSayForSecs (VirtualMachine *vm)
603
+ {
604
+ Target *target = vm->target ();
605
+
606
+ if (target) {
607
+ showBubble (vm, Target::BubbleType::Say, vm->getInput (0 , 2 )->toString ());
608
+ m_waitingBubbles[target] = vm;
609
+ startWait (vm, vm->getInput (1 , 2 )->toDouble ());
610
+ }
611
+
612
+ return 2 ;
613
+ }
614
+
615
+ unsigned int LooksBlocks::sayForSecs (VirtualMachine *vm)
616
+ {
617
+ if (wait (vm)) {
618
+ Target *target = vm->target ();
619
+
620
+ if (target) {
621
+ auto it = m_waitingBubbles.find (target);
622
+
623
+ // Clear bubble if it hasn't been changed
624
+ if (it != m_waitingBubbles.cend () && it->second == vm)
625
+ hideBubble (vm->target ());
626
+ }
627
+ }
628
+
629
+ return 0 ;
630
+ }
631
+
632
+ unsigned int LooksBlocks::say (VirtualMachine *vm)
633
+ {
634
+ showBubble (vm, Target::BubbleType::Say, vm->getInput (0 , 1 )->toString ());
635
+ return 1 ;
636
+ }
637
+
638
+ unsigned int LooksBlocks::startThinkForSecs (VirtualMachine *vm)
639
+ {
640
+ Target *target = vm->target ();
641
+
642
+ if (target) {
643
+ showBubble (vm, Target::BubbleType::Think, vm->getInput (0 , 2 )->toString ());
644
+ m_waitingBubbles[target] = vm;
645
+ startWait (vm, vm->getInput (1 , 2 )->toDouble ());
646
+ }
647
+
648
+ return 2 ;
649
+ }
650
+
651
+ unsigned int LooksBlocks::thinkForSecs (VirtualMachine *vm)
652
+ {
653
+ return sayForSecs (vm); // there isn't any difference
654
+ }
655
+
656
+ unsigned int LooksBlocks::think (VirtualMachine *vm)
657
+ {
658
+ showBubble (vm, Target::BubbleType::Think, vm->getInput (0 , 1 )->toString ());
659
+ return 1 ;
660
+ }
661
+
518
662
unsigned int LooksBlocks::show (VirtualMachine *vm)
519
663
{
520
664
Sprite *sprite = dynamic_cast <Sprite *>(vm->target ());
0 commit comments