Executing rings with JS

It is mostly due to the amount of objects I create, the amount of custom blocks, and the amount of loops. Things can get very unoptimized that way and it was clearly and evidently the case in my last attempt. Now that my workflow is almost entirely JS-based, it runs smooth like butter with the blocks only providing an interface.

Okay, looking at your code again, my new guess is that THIS at the time your function is called isn't what you think it is. If it's a sprite you win, if something else you lose, or maybe vice versa.

So, your problem is solved?

Well what was very strange is that you saw that it was working in the image, but I had no idea why because every other time I tried it it either worked or spat out something very, very strange like undefined while still managing to run execute (because it would throw errors when it is getting too many arguments). I was wondering:

  • If there is a more reliable and less convoluted way of executing a ringed reporter
  • How do I make sure it works all the time and gives a proper return value?


Why does this not work yet this does????

It also seems to randomly error at times saying this.context is null

Actually, what seems to be happening is execute is overwriting some context here so that the return is actually of 4 the result of the reporter, not the call. How do I make it so that I can execute the reporter and give its result back to JS without messing up the context? It would be pretty sick if there is some sort of JS API solution where u just execute the context and it returns the results back.

Okay, I'm getting more and more annoyed by threads like this under the "Help with Snap!" headline. Can we move this somewhere hidden from everybody else who might be looking for help?

Should I move it into Advanced Topics or Advanced Topics - Development?

that would be great, thank you! The point is, I'm afraid we're scaring off users with topics that revolve around special hacks around JS in these forums. Compared to what I'm seeing in my Email-inbox we're getting very few actual questions here, and I suspect it might have something to do with the kinds of questions and suggestions that happen here, that it's off-putting novices and my target audience.

I am still trying to look through the source code but I cannot seem to understand how these ring contexts become evaluated and how their return is properly associated with whatever input requires it.

Ok so after a little bit of digging I think I understand how most of it works now. It appears that what map does is it uses a thing called an accumulator to do recursive calls. pushContext appears calls the same selector until it returns a value. So it seems that eventually it satisfies the iteration and returns all the way back to the first push context call. The final evaluate just seems to be a way to push the return value to the whatever called it.
I think this is sort of how it works so does that mean that in order for me to do something like this, I would also have to use accumulators to iterate through it with pushContext and returnValueToParentContext in JS and get the response value? Also, what is the use of the cdr function?
I do not really want to do it like in reportMap though as I would rather just compute the reporter block one time and then do it as many times as I want after because this simplifies the script.

I think the point is that you don't need to follow the evaluator to make Snap projects at all. If you want to understand how programming languages work there are better ways to study them than to sift through the Snap! source code.

I know how to use Javascript but I am trying to do one thing in specific which is computing what is in a reporter ring and using it in Javascript which means I have to figure out how Snap! is doing things, but it is a bit difficult to understand what the interpreter is trying to do in cases like doCall and reportMap.

you can use invoke() on the ring.

invoke requires a lot of parameters apparently and does it have global access? (Is it available in just general global space?)
Also which parameters are necessary and what is the most common way to set up a call with a ring? I know the parameters have comments but I still don't fully understand how the structure of Snap! is layed out in terms of Processes and Context and etc.
Is this sort of how you do it?

return invoke(
    myRing,
    new List(args)
);

Wait is it really just that easy ^ holy crap! Well there is a magical API then! Thanks a bunch! I will test more when I can get on PC
I managed to somehow test it on mobile though which at least means I know it works

You mentioned before that the visuals are what would be slowing Snap! down...


Look how fast it is now! :smiley:
Just from switching minimum distance to have a JS mode already bumped up performance to an insane degree! Thanks to all involved!
This is what it looks like now:
old:

new:

Is there a version of invoke that will allow the process to yield? How do I make it execute command block rings without freezing Snap?

Okay, think about this for a minute. "Yielding" means stopping JS and surrendering control to the browser. After JS has stopped, you can't continue a function call. So, of course there cannot be a version of invoke() that yields. The version that yields is the Snap! programming language :slight_smile:.

The key missing thing that Jens didn't say is that when your web page yields in JS and then eventually the browser starts you up again, it starts you from the beginning, with nothing on the stack. So any state you'd like to have after the yield has to be stored semi-permanently. Life would be so much easier if browsers were true multithreading systems in which returning from a yield started you where you left off.

I'm afraid it's not exactly the truth.
You may take a look at the test project
https://snap.berkeley.edu/snap/snap.html#present:Username=dardoro&ProjectName=MIcro%20lag%20test&editMode&noRun
Exactly the same amount of work - 60 iterations of "move(8)" for 400 sprites is performed in three ways.
Simple loop initiated by broadcast took 1-1.5sm as expected.
The same loop started by "launch" for each sprite took 5-7 times longer.
Iterations "powered" by broadcast tick are 10 times longer.
Amount of graphic work is exactly the same only control structures differ. Also difference in sprites movement is astonishing.

Okay, I believe you. More work to do...