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

Add Undo/Redo support in the viewer #7546

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft

Add Undo/Redo support in the viewer #7546

wants to merge 5 commits into from

Conversation

emilk
Copy link
Member

@emilk emilk commented Sep 29, 2024

What

This PR implements Undo and Redo for any edit to the active blueprint.

undo.mp4

Implementation

This implements undo/redo by editing the "time cursor" for the blueprint timeline. Undo moves it backwards, redo forwards. When doing an action, all redo history is erased from the store with a new ChunkStore::drop_time_range function.

TODO

Closing a space-view and hitting undo fails to restore the space-view, and instead results in:

[WARN re_blueprint_tree::blueprint_tree] Bug: asked to show a UI for a space view that doesn't exist
[DEBUG egui_tiles::tiles] Failed to find tile #8930786982270384173 during simplify

The reason are these lines of code:

pub fn clear(&self, ctx: &ViewerContext<'_>) {
ctx.command_sender.send_system(SystemCommand::DropEntity(
ctx.store_context.blueprint.store_id().clone(),
self.entity_path(),
));
}

pub fn clear(&self, ctx: &ViewerContext<'_>) {
ctx.command_sender.send_system(SystemCommand::DropEntity(
ctx.store_context.blueprint.store_id().clone(),
self.entity_path(),
));
}

When clearing a container or blueprint, the entity is dropped from the store.
Just removing these lines fixes undo, but creates a problem of accumulating garbage, potentially wasting RAM as the blueprint grows (especially for users with thousands of entities).

Me and @jleibs came up with a very nice solution to this though:

  • Remove the DropEntity calls above. Just keep the entities, but don't reference them
  • Remove the GC flag that protects at least 1 copy of each entity
  • Add a GC flag that protects everything newer than a certain timepoint (make sure we have e.g. 100 undo points)
  • Optional optimization: Add a EntityDb::clear_index to remove references to components/entities that have no data (have all been GCed)
  • Optional optimization: Update this code to not walk the entity tree, but recursively collect entities from the root down

Checklist

  • I have read and agree to Contributor Guide and the Code of Conduct
  • I've included a screenshot or gif (if applicable)
  • I have tested the web demo (if applicable):
  • The PR title and labels are set such as to maximize their usefulness for the next release's CHANGELOG
  • If applicable, add a new check to the release checklist!
  • If have noted any breaking changes to the log API in CHANGELOG.md and the migration guide

To run all checks from main, comment on the PR with @rerun-bot full-check.

@emilk emilk added enhancement New feature or request 📺 re_viewer affects re_viewer itself include in changelog labels Sep 29, 2024
@emilk emilk mentioned this pull request Oct 6, 2024
6 tasks
@emilk emilk added the blocked can't make progress right now label Oct 6, 2024
@emilk emilk force-pushed the emilk/undo branch 2 times, most recently from d4b0b9c to 644c87c Compare October 6, 2024 15:19
teh-cmc added a commit that referenced this pull request Oct 7, 2024
### What
Adds `ChunkStore::drop_time_range` to drop all events within some time
range. Will be used to implement undo.

* Part of #3135
* Extracted from #7546

---------

Co-authored-by: Clement Rey <[email protected]>
@emilk emilk removed the blocked can't make progress right now label Oct 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request include in changelog 📺 re_viewer affects re_viewer itself
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Undo (and redo) in viewer
1 participant