@@ -347,36 +347,8 @@ void LooksBlocks::compileSwitchCostumeTo(Compiler *compiler)
347347 if (!target)
348348 return ;
349349
350- Input *input = compiler->input (COSTUME);
351-
352- if (input->pointsToDropdownMenu ()) {
353- std::string value = input->selectedMenuItem ();
354- int index = target->findCostume (value);
355-
356- if (index == -1 ) {
357- if (value == " next costume" )
358- compiler->addFunctionCall (&nextCostume);
359- else if (value == " previous costume" )
360- compiler->addFunctionCall (&previousCostume);
361- else {
362- Value v (value);
363-
364- if (v.type () == Value::Type::Integer) {
365- compiler->addConstValue (v.toLong () - 1 );
366- compiler->addFunctionCall (&switchCostumeToByIndex);
367- } else {
368- compiler->addInput (input);
369- compiler->addFunctionCall (&switchCostumeTo);
370- }
371- }
372- } else {
373- compiler->addConstValue (index);
374- compiler->addFunctionCall (&switchCostumeToByIndex);
375- }
376- } else {
377- compiler->addInput (input);
378- compiler->addFunctionCall (&switchCostumeTo);
379- }
350+ compiler->addInput (COSTUME);
351+ compiler->addFunctionCall (&switchCostumeTo);
380352}
381353
382354void LooksBlocks::compileNextCostume (Compiler *compiler)
@@ -386,85 +358,14 @@ void LooksBlocks::compileNextCostume(Compiler *compiler)
386358
387359void LooksBlocks::compileSwitchBackdropTo (Compiler *compiler)
388360{
389- Stage *stage = compiler->engine ()->stage ();
390-
391- if (!stage)
392- return ;
393-
394- Input *input = compiler->input (BACKDROP);
395-
396- if (input->pointsToDropdownMenu ()) {
397- std::string value = input->selectedMenuItem ();
398- int index = stage->findCostume (value);
399-
400- if (index == -1 ) {
401- if (value == " next backdrop" )
402- compiler->addFunctionCall (&nextBackdrop);
403- else if (value == " previous backdrop" )
404- compiler->addFunctionCall (&previousBackdrop);
405- else if (value == " random backdrop" )
406- compiler->addFunctionCall (&randomBackdrop);
407- else {
408- Value v (value);
409-
410- if (v.type () == Value::Type::Integer) {
411- compiler->addConstValue (v.toLong () - 1 );
412- compiler->addFunctionCall (&switchBackdropToByIndex);
413- } else {
414- compiler->addInput (input);
415- compiler->addFunctionCall (&switchBackdropTo);
416- }
417- }
418- } else {
419- compiler->addConstValue (index);
420- compiler->addFunctionCall (&switchBackdropToByIndex);
421- }
422- } else {
423- compiler->addInput (input);
424- compiler->addFunctionCall (&switchBackdropTo);
425- }
361+ compiler->addInput (BACKDROP);
362+ compiler->addFunctionCall (&switchBackdropTo);
426363}
427364
428365void LooksBlocks::compileSwitchBackdropToAndWait (Compiler *compiler)
429366{
430- Stage *stage = compiler->engine ()->stage ();
431-
432- if (!stage)
433- return ;
434-
435- Input *input = compiler->input (BACKDROP);
436-
437- if (input->pointsToDropdownMenu ()) {
438- std::string value = input->selectedMenuItem ();
439- int index = stage->findCostume (value);
440-
441- if (index == -1 ) {
442- if (value == " next backdrop" )
443- compiler->addFunctionCall (&nextBackdropAndWait);
444- else if (value == " previous backdrop" )
445- compiler->addFunctionCall (&previousBackdropAndWait);
446- else if (value == " random backdrop" )
447- compiler->addFunctionCall (&randomBackdropAndWait);
448- else {
449- Value v (value);
450-
451- if (v.type () == Value::Type::Integer) {
452- compiler->addConstValue (v.toLong () - 1 );
453- compiler->addFunctionCall (&switchBackdropToByIndexAndWait);
454- } else {
455- compiler->addInput (input);
456- compiler->addFunctionCall (&switchBackdropToAndWait);
457- }
458- }
459- } else {
460- compiler->addConstValue (index);
461- compiler->addFunctionCall (&switchBackdropToByIndexAndWait);
462- }
463- } else {
464- compiler->addInput (input);
465- compiler->addFunctionCall (&switchBackdropToAndWait);
466- }
467-
367+ compiler->addInput (BACKDROP);
368+ compiler->addFunctionCall (&switchBackdropToAndWait);
468369 compiler->addFunctionCall (&backdropNumber);
469370 compiler->addFunctionCall (&checkBackdropScripts);
470371}
@@ -932,36 +833,43 @@ void LooksBlocks::setCostumeByIndex(Target *target, long index)
932833 target->setCostumeIndex (index);
933834}
934835
935- unsigned int LooksBlocks::switchCostumeToByIndex (VirtualMachine *vm)
936- {
937- if (Target *target = vm->target ())
938- setCostumeByIndex (target, vm->getInput (0 , 1 )->toLong ());
939-
940- return 1 ;
941- }
942-
943836unsigned int LooksBlocks::switchCostumeTo (VirtualMachine *vm)
944837{
838+ // https://github.com/scratchfoundation/scratch-vm/blob/8dbcc1fc8f8d8c4f1e40629fe8a388149d6dfd1c/src/blocks/scratch3_looks.js#L389-L413
945839 Target *target = vm->target ();
946840
947841 if (!target)
948842 return 1 ;
949843
950844 const Value *name = vm->getInput (0 , 1 );
951- std::string nameStr = name->toString ();
952- int index = target->findCostume (nameStr);
953845
954- if (index == -1 ) {
955- if (nameStr == " next costume" )
846+ if (!name->isString ()) {
847+ // Numbers should be treated as costume indices, always
848+ if (name->isNaN () || name->isInfinity () || name->isNegativeInfinity ())
849+ target->setCostumeIndex (0 );
850+ else
851+ setCostumeByIndex (target, name->toLong () - 1 );
852+ } else {
853+ // Strings should be treated as costume names, where possible
854+ const int costumeIndex = target->findCostume (name->toString ());
855+ std::string nameStr = name->toString ();
856+
857+ auto it = std::find_if (nameStr.begin (), nameStr.end (), [](char c) { return !std::isspace (c); });
858+ bool isWhiteSpace = (it == nameStr.end ());
859+
860+ if (costumeIndex != -1 ) {
861+ setCostumeByIndex (target, costumeIndex);
862+ } else if (nameStr == " next costume" ) {
956863 nextCostume (vm);
957- else if (nameStr == " previous costume" )
864+ } else if (nameStr == " previous costume" ) {
958865 previousCostume (vm);
959- else {
960- if (name->isValidNumber ())
961- setCostumeByIndex (target, name->toLong () - 1 );
866+ // Try to cast the string to a number (and treat it as a costume index)
867+ // Pure whitespace should not be treated as a number
868+ // Note: isNaN will cast the string to a number before checking if it's NaN
869+ } else if (!(name->isNaN () || isWhiteSpace)) {
870+ target->setCostumeIndex (name->toInt () - 1 );
962871 }
963- } else
964- setCostumeByIndex (target, index);
872+ }
965873
966874 return 1 ;
967875}
@@ -990,36 +898,45 @@ void LooksBlocks::startBackdropScripts(VirtualMachine *vm, bool wait)
990898 }
991899}
992900
993- void LooksBlocks::switchBackdropToByIndexImpl (VirtualMachine *vm)
994- {
995- if (Stage *stage = vm->engine ()->stage ())
996- setCostumeByIndex (stage, vm->getInput (0 , 1 )->toLong ());
997- }
998-
999901void LooksBlocks::switchBackdropToImpl (VirtualMachine *vm)
1000902{
903+ // https://github.com/scratchfoundation/scratch-vm/blob/8dbcc1fc8f8d8c4f1e40629fe8a388149d6dfd1c/src/blocks/scratch3_looks.js#L423-L462
1001904 Stage *stage = vm->engine ()->stage ();
1002905
1003906 if (!stage)
1004907 return ;
1005908
1006909 const Value *name = vm->getInput (0 , 1 );
1007- std::string nameStr = name->toString ();
1008- int index = stage->findCostume (nameStr);
1009910
1010- if (index == -1 ) {
1011- if (nameStr == " next backdrop" )
911+ if (!name->isString ()) {
912+ // Numbers should be treated as costume indices, always
913+ if (name->isNaN () || name->isInfinity () || name->isNegativeInfinity ())
914+ stage->setCostumeIndex (0 );
915+ else
916+ setCostumeByIndex (stage, name->toLong () - 1 );
917+ } else {
918+ // Strings should be treated as costume names, where possible
919+ const int costumeIndex = stage->findCostume (name->toString ());
920+ std::string nameStr = name->toString ();
921+
922+ auto it = std::find_if (nameStr.begin (), nameStr.end (), [](char c) { return !std::isspace (c); });
923+ bool isWhiteSpace = (it == nameStr.end ());
924+
925+ if (costumeIndex != -1 ) {
926+ setCostumeByIndex (stage, costumeIndex);
927+ } else if (nameStr == " next backdrop" ) {
1012928 nextBackdropImpl (vm);
1013- else if (nameStr == " previous backdrop" )
929+ } else if (nameStr == " previous backdrop" ) {
1014930 previousBackdropImpl (vm);
1015- else if (nameStr == " random backdrop" ) {
931+ } else if (nameStr == " random backdrop" ) {
1016932 randomBackdropImpl (vm);
1017- } else {
1018- if (name->isValidNumber ())
1019- setCostumeByIndex (stage, name->toLong () - 1 );
933+ // Try to cast the string to a number (and treat it as a costume index)
934+ // Pure whitespace should not be treated as a number
935+ // Note: isNaN will cast the string to a number before checking if it's NaN
936+ } else if (!(name->isNaN () || isWhiteSpace)) {
937+ stage->setCostumeIndex (name->toInt () - 1 );
1020938 }
1021- } else
1022- setCostumeByIndex (stage, index);
939+ }
1023940}
1024941
1025942void LooksBlocks::nextBackdropImpl (VirtualMachine *vm)
@@ -1047,14 +964,6 @@ void LooksBlocks::randomBackdropImpl(VirtualMachine *vm)
1047964 }
1048965}
1049966
1050- unsigned int LooksBlocks::switchBackdropToByIndex (VirtualMachine *vm)
1051- {
1052- switchBackdropToByIndexImpl (vm);
1053- startBackdropScripts (vm, false );
1054-
1055- return 1 ;
1056- }
1057-
1058967unsigned int LooksBlocks::switchBackdropTo (VirtualMachine *vm)
1059968{
1060969 switchBackdropToImpl (vm);
@@ -1063,14 +972,6 @@ unsigned int LooksBlocks::switchBackdropTo(VirtualMachine *vm)
1063972 return 1 ;
1064973}
1065974
1066- unsigned int LooksBlocks::switchBackdropToByIndexAndWait (VirtualMachine *vm)
1067- {
1068- switchBackdropToByIndexImpl (vm);
1069- startBackdropScripts (vm, true );
1070-
1071- return 1 ;
1072- }
1073-
1074975unsigned int LooksBlocks::switchBackdropToAndWait (VirtualMachine *vm)
1075976{
1076977 switchBackdropToImpl (vm);
0 commit comments