-
-
Notifications
You must be signed in to change notification settings - Fork 2
Keep the brushes an undo would have rebuilt identically #642
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -164,7 +164,14 @@ func restore_state(state: Dictionary) -> void: | |
| if root.has_signal("user_message"): | ||
| root.user_message.emit("Level not loaded: %s" % problem, 2) | ||
| return | ||
| root.clear_brushes() | ||
| # Undo and redo are whole-level snapshots, so taking back a nudge of one brush | ||
| # used to free and rebuild every brush in the level (#600). A brush whose | ||
| # record is identical to what it would capture right now is the brush that | ||
| # record describes, so it is kept across the clear and put back into the | ||
| # registries rather than rebuilt. At 400 brushes a one-brush edit rebuilds one. | ||
| var brushes: Array = state.get("brushes", []) | ||
| var reusable: Dictionary = root.brush_system.reusable_draft_brushes(brushes) | ||
| root.clear_brushes(reusable) | ||
| root.entity_system.clear_entities() | ||
| var region_data = state.get("terrain_regions", {}) | ||
| if region_data is Dictionary and not region_data.is_empty(): | ||
|
|
@@ -192,8 +199,16 @@ func restore_state(state: Dictionary) -> void: | |
| # already works this way for a malformed brush (#318), and a state can hold | ||
| # one for the same reasons — an older version, a partial write, a hand edit. | ||
| var skipped := 0 | ||
| var brushes: Array = state.get("brushes", []) | ||
| for info in brushes: | ||
| var kept_id := "" | ||
| if info is Dictionary: | ||
| kept_id = str((info as Dictionary).get("brush_id", "")) | ||
| if kept_id != "" and reusable.has(kept_id): | ||
| root.brush_system.reregister_draft_brush(reusable[kept_id]) | ||
|
Comment on lines
+206
to
+207
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When an undo restores a deleted brush ahead of an unchanged sibling, this re-registers the sibling in place while the missing brush is rebuilt at the end of Useful? React with 👍 / 👎. |
||
| # Erased so a record that names the same brush twice cannot register | ||
| # one node into the level twice. | ||
| reusable.erase(kept_id) | ||
| continue | ||
| if not _restored_brush(info, {}): | ||
| skipped += 1 | ||
| var pending: Array = state.get("pending", []) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a successful bake has consumed all dirty tags, restoring a snapshot whose brush records all still match—such as undoing a palette-only edit—takes this branch for every brush, so no
create_brush_from_info()call tags a brush dirty and no full reconcile is requested. The sameclear_brushes()call still removes the baked container at line 870, leaving no baked output, but the next Bake Changed reports “No changed brushes since last bake” and cannot recreate it. Retaining brushes must still invalidate the bake when restoration clears its derived output.Useful? React with 👍 / 👎.