fix: Ensure immovable blocks are considered during workspace tidying#8550
Merged
Conversation
At a high-level, this change ensures that cleaning up a workspace doesn't move blocks in a way that overlaps with immovable blocks. It also adds missing testing coverage for both Rect (used for bounding box calculations during workspace cleanup) and WorkspaceSvg (for verifying the updated clean up functionality). This also renames the clean up function to be 'tidyUp' since that better suits what's happening (as opposed to other clean-up routines which are actually deinitializing objects).
…ring-workspace-tidying
Contributor
There was a problem hiding this comment.
Welcome! It looks like this is your first pull request in Blockly, so here are a couple of tips:
- You can find tips about contributing to Blockly and how to validate your changes on our developer site.
- All contributors must sign the Google Contributor License Agreement (CLA). If the google-cla bot leaves a comment on this PR, make sure you follow the instructions.
- We use conventional commits to make versioning the package easier. Make sure your commit message is in the proper format or learn how to fix it.
- If any of the other checks on this PR fail, you can click on them to learn why. It might be that your change caused a test failure, or that you need to double-check the style guide.
Thank you for opening this PR! A member of the Blockly team will review it soon.
BenHenning
commented
Aug 22, 2024
Collaborator
Author
BenHenning
left a comment
There was a problem hiding this comment.
Self-reviewed changes.
BenHenning
commented
Aug 22, 2024
Collaborator
Author
BenHenning
left a comment
There was a problem hiding this comment.
Self-reviewed test rename.
Collaborator
Author
|
Looks like this is now ready for review. |
gonfunko
approved these changes
Aug 23, 2024
Collaborator
Author
|
NB: Comments should be limited to 80 characters (ES lint doesn't catch this). |
BenHenning
commented
Sep 3, 2024
Collaborator
Author
BenHenning
left a comment
There was a problem hiding this comment.
Self-reviewed changes renaming back to 'cleanUp'.
Collaborator
Author
|
@gonfunko could you PTAL per latest changes and let me know if the PR still looks good to you? |
gonfunko
approved these changes
Sep 5, 2024
Collaborator
Author
|
Thanks @gonfunko! |
Contributor
|
Thanks so much for this! |
This was referenced Nov 28, 2024
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The basics
The details
Resolves
Fixes #6889
Proposed Changes
This PR introduces a fix for #6889 (
WorkspaceSvg.cleanUp) when a workspace contains an immovable block. Previously, immovable blocks were ignored incleanUpwhich could lead to situations where movable blocks were stacked on top of the immovable blocks. The updated algorithm addresses this.The old algorithm was essentially the following steps:
getTopBlocksandWorkspace's sorting logic).(0, 0).ycoordinate plus its height plus a minimum height spacing defined by the renderer'sMIN_BLOCK_HEIGHTproperty. Also, left-align the block at anxvalue of0.The updated algorithm augments this by considering any immovable blocks that the new block's position might intersect with (by using
Rect'sintersectsmethod), as so:Rect(to be used later).(0, 0). If not, assume it to be(0, y)whereyis the previous block's position plus the previous block's height plus the minimum block spacing (as described above).yin the same way as the previous step except use the conflicting immovable block's position and size, rather than the previous movable block.NOTE:
This PR is also renamingWorkspaceSvg.cleanUptoWorkspaceSvg.tidyUpsince 'clean up' is an overloaded term in the codebase and generally means "deinitialize." This PR does not rename the context menu item since cleaning up the workspace has a different context for the user and probably makes equal sense to 'tidy' (so there wasn't an obvious reason to change it other than to keep the two aligned).This has been reverted after a discussion with the team--the preference is to avoid unnecessary code changes and this rename has few benefits.
Reason for Changes
Trying to tidy up the workspace without considering immovable blocks leads to undesirable results. See previous behavior:
Screen.recording.2024-08-21.1.42.28.PM.webm
With the changes, the new behavior is:
Screen.recording.2024-08-21.1.40.37.PM.webm
This is a much better user experience. Note that the above was demoed by importing the following JSON into a local Blockly playground:
{ "blocks": { "languageVersion": 0, "blocks": [ { "type": "math_number", "id": "block1", "x": 1, "y": 2, "fields": { "NUM": 1 } }, { "type": "math_number", "id": "block2", "x": 10, "y": 20, "movable": false, "fields": { "NUM": 2 } }, { "type": "math_number", "id": "block3", "x": 2, "y": 30, "fields": { "NUM": 3 } }, { "type": "controls_repeat_ext", "id": "block4", "x": 3, "y": 40, "inputs": { "TIMES": { "shadow": { "type": "math_number", "fields": { "NUM": 10 } } }, "DO": { "block": { "type": "controls_if", "inputs": { "IF0": { "block": { "type": "logic_boolean", "fields": { "BOOL": "TRUE" } } }, "DO0": { "block": { "type": "text_print", "inputs": { "TEXT": { "shadow": { "type": "text", "fields": { "TEXT": "abc" } } } } } } } } } } }, { "type": "math_number", "id": "block5", "x": 20, "y": 200, "movable": false, "fields": { "NUM": 5 } } ] } }Test Coverage
cleanUphad no functional tests, so a bunch were added (including for verifying existing behaviors). All of this function's new tests passed without the algorithmic changes except for the test"multiple block types immovable blocks are not moved"(which was verified to fail, as expected, without the algorithmic fixes).Separately,
Recthad some additional functionality and documentation added, along with an entire new test suite meant to thoroughly test all aspects of the class (since it plays a pivotal role in the new functionality, plus a bunch of other existing functionality throughout Blockly core).Documentation
It doesn't seem any documentation changes are needed at this time since the fix was entirely infrastructural and implementation-specific. Since this is a public API function, it's certainly possible some documentation work will be needed.
Additional Information
The needs of
cleanUpfunctional changes and its tests led to needing a bounding box class. This was added beforeRectwas discovered, and its intersection algorithm was independently derived.Rect's own intersection code is actually replaced in this PR with the derived version (the same logic, just inverted) with some documentation to logically explain why it works to help any future readers who come across it.Separately, the workspace tests prefer to use JSON for block initialization vs. direct API access. This seems to be the recommended way to approach such test condition arrangement after discussions with other Blockly team members.