Skip to content
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

Freeze inconsistent in every loops #588

Open
hallpell opened this issue Jan 29, 2021 · 1 comment
Open

Freeze inconsistent in every loops #588

hallpell opened this issue Jan 29, 2021 · 1 comment

Comments

@hallpell
Copy link
Collaborator

Freeze seems to interact oddly with every loops in a way that doesn't happen in forever loops.

https://woofjs.com/create.html#hallpell_freezing_exploration

is an example that appears non-deterministic. If you run it multiple times, sometimes the text sprite will hide before freezing and sometimes it won't. (To make it worse, if you speed up the every loop to every 0.01 seconds, you can get the text sprite to be frozen showing numbers greater than 1).

With some exploration of the code, this appears to be happening because every loops are off doing their own thing with setIntervals, while forever loops are part of the _repeats infrastructure that is guaranteed to run before rendering. This is most apparent here

WoofJS/woof.js

Lines 561 to 568 in 6e40e96

thisContext._render = () => {
thisContext._runRepeats(); // we need to run the repeats even if stopped because the defrost() code likely lives in a repeat
thisContext._calculateMouseSpeed();
thisContext.renderInterval = window.requestAnimationFrame(thisContext._render); // WARNING this line makes render recursive. Only call is once and it will continue to call itself ~30fps.
if (thisContext.stopped) { return; }
thisContext._renderSprites();
};
thisContext.ready(thisContext._render);
where I suspect the setInterval based loops are able to set thisContext.stopped = true between one render and the next.

It's also important to bring up

WoofJS/woof.js

Lines 257 to 269 in 6e40e96

// WARNING - freeze is notoriously difficult to get right
// Any change you make to it will have unintended consequenses.
// Only change this code if absolutely neccesary and after rigerous testing.
thisContext.freezing = false // whether or not a freeze is currently in progress
thisContext.freeze = function() {
if (arguments.length > 0) { throw new TypeError("freeze() requires no inputs."); }
if (thisContext.freezing || thisContext.stopped) { return }
thisContext.freezing = true
thisContext.after(10, "miliseconds", () => {
thisContext.stopped = true
thisContext.freezing = false
});
};
which makes me think there likely isn't a great solution to this. I'm still in the early stages of thinking through this, but will go through it a bit more.

@hallpell
Copy link
Collaborator Author

hallpell commented Feb 2, 2021

I'm considering moving the confirmation of freezing->stopped from freeze() to the render loop to 'bridge the gap' between the setTimeouts of everys and the render loop we see here. I expect to run into some bugs, so want to write out the tests cases that I want to pass before considering checking in.

  • a freeze should allow at least one more frame to render. (i.e. let the code inside 'this' every loop impact the render) This is currently violated by the initial example, where a freeze in [every 0.1 sec] will sometimes not render another frame. I think this is essential, as cases such as player.hide(); gameOver.show(); freeze() are very common and should work.
  • a freeze should allow no more than 1 frame to render after it is invoked. This is currently violated occasionally by forevers, and more frequently violated by everys.

https://woofjs.com/create.html#hallpell_freezing_exploration_v3 is a good example of the failures both ways, where I would like it to freeze with the text sprite showing "0", but I've got it to range from -2 to 2 without too many trials. This feels like what I'll use as a baseline to judge potential changes against.

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

No branches or pull requests

1 participant