"Broadcast and wait" in "when I receive <any message>" doesn't continue

I'm running into an issue that's similar to this (since solved) one, but with its own unique twist. I'm not sure if this is a bug that only arises in very specific situations or a feature to nudge me to tone it down with the recursive messages :laughing:

Per usual, I'm running a program where most of the good stuff happens in a [scratchblocks]
when I receive [any message v] :: hat control [/scratchblocks]

block so that I can pass extra parameters alongside the message and parse it with the [scratchblocks] (message) [/scratchblocks] upvar. I'm in a situation where one section within the "when I receive..." script needs to broadcast another message, wait for that handler to complete, and then resume execution.

I have a simplified demo here. When the green flag script triggers the "any" message script, you'll see the subsequent messages are broadcast, but the final "say" block in the "when I receive any..." script never fires.

Changing this from "when I receive any message" to an explicit "when I receive [some specific message]" seems to fix this. If you swap in the script at the bottom, it triggers the other broadcasts and still returns for the final "say" block.

I'm hoping to confirm whether this is a bug or expected behavior, and, if it's the latter, whether there are any clever workarounds. I've tried playing around with a few combinations of 'launch', 'do in parallel and wait', etc, but so far haven't found anything that works.

1st thing to note is that using say blocks for debugging in tight situations can cause it own problems as a new say block will immediately overwrite one in progress

So I modified (hopefully successfully as it's a bit complicated :slight_smile: ) to use some logging instead

And this is the result I got

So following the log
Broadcast begin triggers the when I receive any message and it logs begin

Then it logs the native when I receive test1 it and then logs its own broadcast test1 and as well
(The order of this may be different on different computers as a race condition is occurring at this point)

So you can see that as soon as the when I receive any message script broadcasts test 1 and wait, its sits waiting for test 1 to complete

However, since test 1 then issues its own broadcast and the when I receive any message is then re-entered and the previous instance of it is stopped running so it never gets to add test 3 to the log

I could be wrong with all this as, but this is my take on it

Right, Snap! doesn't have an event queue. Instead, depending on the phase of the moon, when a second event triggers a script that's already running, either the second event is ignored or the first event is stopped early to handle the second one. Sounds like you're seeing the latter behavior.

After a bit of testing, I found that if you use a broadcast and wait block under a receive any message script, the receive hat will run again, stopping the currently running script. My solution was to stick everything in the if block, in a launch block. This way, the code will finish. The only downside to this method is, you can't broadcast and wait, you have to use a variable, or something else.

Here's a project demonstrating my workaround Snap! Build Your Own Blocks

Looks good :slight_smile:

Your method does seem to use broadcast and wait so I'm a little confused when you said

No, you can't use broadcast [begin] and wait. Using broadcast and wait in the receive script is fine. Sorry if I'm confusing. I prefer to let the project speak for itself.

Well changing to
image

seems to still work out alright for me

image

I think I've got what you mean now

image

The sprite says hello straightaway after the broadcast and wait as it returns before test3 is issued because it's in a launch statement

[edit]
Totally with it now :slight_smile:

I've used a variable in a complicated project to do what your suggesting and set it to false - do my broadcast - and then use a wait until block

image

[/edit]

Thanks everyone!

@cymplecy, good call on the logging. When I'm testing on my own, I usually use a JS block and log to the browser's console. But that feels wrong, so I switch it to "say" blocks when I need to post publicly. I don't know why it never occurred to me to use a list!

And thanks for the workaround @ego-lay_atman-bay! I knew there had to be something I was missing.

#TopTip when using log list is to manually set log to empty list, setup your watcher the way you want - e.g longer than 3 items, then put the delete all items in your normal start script, which doesn't alter the look of the watcher

Instead of untitled script pic (1), if you use untitled script pic (2) to clear out the log list, then the watcher will retain the shape from before.

em - that's what I said but maybe I wasn't clear :slight_smile:

image

I'm sure it's what you meant, but "manually set log to empty list" was a direct quotation from your message. ;~P

Follow the whole sentence and don't just cherry pick :slight_smile:

The full picture including the "manual set log to empty list" that's needed before you can delete all of log in future :slight_smile:

image

If you dont pre-set log to a list you get his

image

But you know all this :slight_smile:

Hey, so I just found a workaround to be able to use a script var to wait until a broadcast is finished without using a global variable. I was genuinely surprised this actually works

Oh, and btw, the var can actually be passed to a different sprite as well. It also doesn't matter if it's sent through a broadcast or not.

Here's the project Snap! Build Your Own Blocks

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.