1212
1313#include " looksblocks.h"
1414#include " ../engine/internal/randomgenerator.h"
15+ #include " ../engine/internal/clock.h"
1516
1617using namespace libscratchcpp ;
1718
1819IRandomGenerator *LooksBlocks::rng = nullptr ;
20+ IClock *LooksBlocks::clock = nullptr ;
1921
2022std::string LooksBlocks::name () const
2123{
@@ -25,6 +27,7 @@ std::string LooksBlocks::name() const
2527void 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+
8294void 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
0 commit comments