Skip to content

Add support for "when timer greater than" #130

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 18, 2022

Conversation

adroitwhiz
Copy link
Collaborator

Resolves part of #122.

This PR adds support for "edge-activated" triggers, so named because they evaluate a predicate every step (e.g. "is the timer greater than N?") and trigger their script on the rising edge (when the predicate changes from false to true).

Trigger predicates/options can now be functions (which are passed the current target) as well as values. This is necessary because the input to a "greater than" block is actually droppable and can contain arbitrary scripts. For codegen purposes, it may be easier to have the function take no arguments and just bind the this value to the current target, but that seems jankier.

// Find triggers which match conditions
let matchingTriggers = [];
for (let i = 0; i < this.spritesAndStage.length; i++) {
const sprite = this.spritesAndStage[i];
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting quirk about the old code I noticed: spritesAndStage is actually a getter which returns a new array every time it's called 😬

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who would ever write such a thing 🙄

@PullJosh
Copy link
Collaborator

Right now it looks like the trigger is timer-specific. Could it be better to simply have a WHEN_TRUE trigger that takes a function as input and activates on the rising edge? (Might as well add WHEN_FALSE as well.)

That way you could trigger when loudness is greater than some number, but also when other conditions are true.

@adroitwhiz
Copy link
Collaborator Author

I thought about that--I was kinda worried there's some reason Scratch itself hasn't just implemented that.

It seems that Scratch previously wanted to implement a "when touching" block but ran into some issues--for instance, a script running in parallel that messes with the predicate you're testing for, which technically makes logical sense but is very unintuitive behavior.

@adroitwhiz
Copy link
Collaborator Author

adroitwhiz commented Jul 18, 2022

In general, I think any sort of "when predicate" block is unintuitive because you have to be acutely aware of execution order (IIRC, there were a ton of bugs in 3.0 relating to edge cases in the "when timer" block, showing that the developers themselves didn't even understand the behavior).

I'd prefer to steer users away from using a "when this predicate evaluates to true" block and only implementing the hat blocks that are necessary to ensure compatibility with Scratch.

EDIT: as an example of the silliness that results, this script allows you to create an infinite loop of meows that even the "stop all" button can't end:
image

@PullJosh
Copy link
Collaborator

Okay, that makes sense. I am on board with the current choice then. 👍

Copy link
Collaborator

@PullJosh PullJosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Behavior now looks correct to me :)

@adroitwhiz adroitwhiz merged commit 7f4295b into leopard-js:master Jul 18, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants