2424#include " timer.h"
2525#include " clock.h"
2626#include " blocks/standardblocks.h"
27- #include " blocks/eventblocks.h"
2827
2928using namespace libscratchcpp ;
3029
@@ -205,12 +204,12 @@ void Engine::broadcast(unsigned int index)
205204
206205void Engine::broadcastByPtr (Broadcast *broadcast)
207206{
208- startHats (HatType::BroadcastReceived, { { EventBlocks::Fields::BROADCAST_OPTION , broadcast->name () } }, nullptr );
207+ startHats (HatType::BroadcastReceived, { { HatField::BroadcastOption , broadcast->name () } }, nullptr );
209208}
210209
211210void Engine::startBackdropScripts (Broadcast *broadcast)
212211{
213- startHats (HatType::BackdropChanged, { { EventBlocks::Fields::BACKDROP , broadcast->name () } }, nullptr );
212+ startHats (HatType::BackdropChanged, { { HatField::Backdrop , broadcast->name () } }, nullptr );
214213}
215214
216215void Engine::stopScript (VirtualMachine *vm)
@@ -472,8 +471,8 @@ void Engine::setKeyState(const KeyEvent &event, bool pressed)
472471
473472 // Start "when key pressed" scripts
474473 if (pressed) {
475- startHats (HatType::KeyPressed, { { EventBlocks::Fields::KEY_OPTION , event.name () } }, nullptr );
476- startHats (HatType::KeyPressed, { { EventBlocks::Fields::KEY_OPTION , " any" } }, nullptr );
474+ startHats (HatType::KeyPressed, { { HatField::KeyOption , event.name () } }, nullptr );
475+ startHats (HatType::KeyPressed, { { HatField::KeyOption , " any" } }, nullptr );
477476 }
478477}
479478
@@ -483,7 +482,7 @@ void Engine::setAnyKeyPressed(bool pressed)
483482
484483 // Start "when key pressed" scripts
485484 if (pressed)
486- startHats (HatType::KeyPressed, { { EventBlocks::Fields::KEY_OPTION , " any" } }, nullptr );
485+ startHats (HatType::KeyPressed, { { HatField::KeyOption , " any" } }, nullptr );
487486}
488487
489488double Engine::mouseX () const
@@ -590,9 +589,17 @@ bool Engine::broadcastByPtrRunning(Broadcast *broadcast)
590589
591590 const auto &scripts = m_backdropChangeHats[script->target ()];
592591 auto scriptIt = std::find (scripts.begin (), scripts.end (), script);
592+ auto scriptFieldMapIt = m_scriptHatFields.find (script);
593593
594- if ((scriptIt != scripts.end ()) && (topBlock->findFieldById (EventBlocks::BACKDROP)->value ().toString () == broadcast->name ()))
595- return true ;
594+ if (scriptFieldMapIt != m_scriptHatFields.cend ()) {
595+ const auto &fieldMap = scriptFieldMapIt->second ;
596+ auto fieldIt = fieldMap.find (HatField::Backdrop);
597+ assert (fieldIt != fieldMap.cend ());
598+ assert (topBlock->findFieldById (fieldIt->second ));
599+
600+ if ((scriptIt != scripts.end ()) && (topBlock->findFieldById (fieldIt->second )->value ().toString () == broadcast->name ()))
601+ return true ;
602+ }
596603 }
597604 }
598605 } else {
@@ -744,7 +751,7 @@ void Engine::addGreenFlagScript(std::shared_ptr<Block> hatBlock)
744751 addHatToMap (m_greenFlagHats, m_scripts[hatBlock].get ());
745752}
746753
747- void Engine::addBroadcastScript (std::shared_ptr<Block> whenReceivedBlock, Broadcast *broadcast)
754+ void Engine::addBroadcastScript (std::shared_ptr<Block> whenReceivedBlock, int fieldId, Broadcast *broadcast)
748755{
749756 assert (!broadcast->isBackdropBroadcast ());
750757 Script *script = m_scripts[whenReceivedBlock].get ();
@@ -760,21 +767,26 @@ void Engine::addBroadcastScript(std::shared_ptr<Block> whenReceivedBlock, Broadc
760767 m_broadcastMap[broadcast] = { script };
761768
762769 addHatToMap (m_broadcastHats, script);
770+ addHatField (script, HatField::BroadcastOption, fieldId);
763771}
764772
765- void Engine::addBackdropChangeScript (std::shared_ptr<Block> hatBlock)
773+ void Engine::addBackdropChangeScript (std::shared_ptr<Block> hatBlock, int fieldId )
766774{
767- addHatToMap (m_backdropChangeHats, m_scripts[hatBlock].get ());
775+ Script *script = m_scripts[hatBlock].get ();
776+ addHatToMap (m_backdropChangeHats, script);
777+ addHatField (script, HatField::Backdrop, fieldId);
768778}
769779
770780void Engine::addCloneInitScript (std::shared_ptr<Block> hatBlock)
771781{
772782 addHatToMap (m_cloneInitHats, m_scripts[hatBlock].get ());
773783}
774784
775- void Engine::addKeyPressScript (std::shared_ptr<Block> hatBlock)
785+ void Engine::addKeyPressScript (std::shared_ptr<Block> hatBlock, int fieldId )
776786{
777- addHatToMap (m_whenKeyPressedHats, m_scripts[hatBlock].get ());
787+ Script *script = m_scripts[hatBlock].get ();
788+ addHatToMap (m_whenKeyPressedHats, script);
789+ addHatField (script, HatField::KeyOption, fieldId);
778790}
779791
780792const std::vector<std::shared_ptr<Target>> &Engine::targets () const
@@ -1086,6 +1098,18 @@ void Engine::addHatToMap(std::unordered_map<Target *, std::vector<Script *>> &ma
10861098 map[target] = { script };
10871099}
10881100
1101+ void Engine::addHatField (Script *script, HatField field, int fieldId)
1102+ {
1103+ auto it = m_scriptHatFields.find (script);
1104+
1105+ if (it == m_scriptHatFields.cend ())
1106+ m_scriptHatFields[script] = { { field, fieldId } };
1107+ else {
1108+ auto &fieldMap = it->second ;
1109+ fieldMap[field] = fieldId;
1110+ }
1111+ }
1112+
10891113const std::vector<Script *> &Engine::getHats (Target *target, HatType type)
10901114{
10911115 assert (target);
@@ -1269,7 +1293,7 @@ void Engine::allScriptsByOpcodeDo(HatType hatType, F &&f, Target *optTarget)
12691293 delete targetsPtr;
12701294}
12711295
1272- std::vector<std::shared_ptr<VirtualMachine>> Engine::startHats (HatType hatType, const std::unordered_map<int , std::string> &optMatchFields, Target *optTarget)
1296+ std::vector<std::shared_ptr<VirtualMachine>> Engine::startHats (HatType hatType, const std::unordered_map<HatField , std::string> &optMatchFields, Target *optTarget)
12731297{
12741298 // https://github.com/scratchfoundation/scratch-vm/blob/f1aa92fad79af17d9dd1c41eeeadca099339a9f1/src/engine/runtime.js#L1818-L1889
12751299 std::vector<std::shared_ptr<VirtualMachine>> newThreads;
@@ -1282,14 +1306,28 @@ std::vector<std::shared_ptr<VirtualMachine>> Engine::startHats(HatType hatType,
12821306 assert (it != m_scripts.end ());
12831307 auto topBlock = it->first ;
12841308
1285- // Match any requested fields
1286- for (const auto &[fieldId, fieldValue] : optMatchFields) {
1287- assert (fieldId > -1 );
1288- assert (topBlock->findFieldById (fieldId));
1309+ if (!optMatchFields.empty ()) {
1310+ // Get the field map for this script
1311+ auto fieldMapIt = m_scriptHatFields.find (script);
1312+ assert (fieldMapIt != m_scriptHatFields.cend ());
1313+
1314+ if (fieldMapIt != m_scriptHatFields.cend ()) {
1315+ const auto &fieldMap = fieldMapIt->second ;
12891316
1290- if (topBlock->findFieldById (fieldId)->value ().toString () != fieldValue) {
1291- // Field mismatch
1292- return ;
1317+ // Match any requested fields
1318+ for (const auto &[fieldId, fieldValue] : optMatchFields) {
1319+ auto fieldIt = fieldMap.find (fieldId);
1320+ assert (fieldIt != fieldMap.cend ());
1321+
1322+ if (fieldIt != fieldMap.cend ()) {
1323+ assert (topBlock->findFieldById (fieldIt->second ));
1324+
1325+ if (topBlock->findFieldById (fieldIt->second )->value ().toString () != fieldValue) {
1326+ // Field mismatch
1327+ return ;
1328+ }
1329+ }
1330+ }
12931331 }
12941332 }
12951333
0 commit comments