-
-
Notifications
You must be signed in to change notification settings - Fork 21.1k
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 per-scene UndoRedo #59564
Add per-scene UndoRedo #59564
Conversation
Good job, I definitely prefer your approach of using multiple UndoRedo objects; far more clean and object-oriented compared to multiple stacks in one UndoRedo. Would it be alright for me to integrate this into my system? My PR #59544 uses my approach to multiple stacks in the background, but this can be replaced with your EditorUndoRedoManager approach while keeping the parts of my idea that work well (in my opinion). |
Sure, whatever. I'm going to finish this anyway, so then we can just pick the implementation that works better. EDIT: |
6687771
to
1cc0494
Compare
One way in which our PRs differ is that you use a string (the file path?) to identify stacks, whereas I use the relevant ObjectID. Do you think the path string will work reliably enough for this usage? I'm just a bit concerned that it might stop working if something is saved to a different location, but maybe that makes it a different resource/scene anyway. |
I might need to change that, right now it doesn't work properly with empty scenes. But using ObjectID would not really help either, I think. |
No, mine doesn't work for empty scenes either - it uses the ObjectID of the root node. My reason for preference is that an ObjectID is guaranteed to be unique, stay unique throughout the session, and not change for any given object (whereas I'm thinking that the string file path would change if a resource is saved somewhere else). There should also be a memory improvement - being an integer instead of a string - but of course this is negligible. |
Just something I'd like to bring up - there are some things that (so far as I can tell) cannot be made to work correctly without additional contributor effort. Both of our approaches detect context automatically where possible, but in cases such as renaming a node there is nothing passed to UndoRedo which can be sensibly used to detect the node being modified. For my approach I'm thinking of having contributors add an extra line to pass in an object which can be used to detect context, such as the node being renamed, and you seem to use a similar approach with getting and passing in an UndoRedo object. Are we happy with the effect of this on Godot development, and can it be mitigated? In most cases UndoRedo will work the same as before, but as soon as someone changes/adds an action so that context isn't easily detectable, it creates an opportunity for undo/redo to mysteriously fail in the future. This can't be tested for because undo/redo is all created on the fly. |
1cc0494
to
90877d9
Compare
EditorUndoRedoManager can take an optional context object in btw inspector and most editors are finished (still need fixing ofc). |
I see, that's what I'm doing as well, except that don't have a global context (at least in my current approach). I have a fail condition for if no context could be detected and none was passed in, which I think might help eliminate some confusion.
Well done, sounds like it's going well (; |
90877d9
to
1fcdd55
Compare
Almost finished with moving stuff to the new system. Note that I'm just replacing UndoRedo * with Ref. Surprisingly it works in many cases, but lots of stuff is likely broken.
I can check when I finish this.
I'd wait until I mark the PR as ready for review. EDIT: I also added Action struct to EditorUndoRedoManager. It's created for every action and holds action name, context id and timestamp. It's not stored nor used yet, but this will be needed later. |
f6186c2
to
4f22c81
Compare
Ok timestamps and global/scene mixed contexts seem to work. So base functionality is roughly done and works as planned (although that's not surprise). Now onto fixing bugs and adding missing features... (like scene versioning) |
4f22c81
to
8fbd587
Compare
Oof. I just pushed a commit that removes There was some code I couldn't port, so for now it's marked with |
22da6fe
to
5a1095e
Compare
5044c09
to
c663011
Compare
c191665
to
741081c
Compare
<return type="int" /> | ||
<param index="0" name="object" type="Object" /> | ||
<description> | ||
Returns the history id deduced from the given [param object]. It can be used with [method get_history_undo_redo]. |
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.
That's a matter for a different PR, but I think we should harmonize our usage of "ID" and "id" in the classref.
$ rg -g'*.xml' " ID " | wc -l
122
$ rg -g'*.xml' " id " | wc -l
25
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.
Left some non-blocking documentation comments, should be good to merge as is or once amended IMO.
741081c
to
ece3df3
Compare
Thanks! |
Is this coming to 3.x by any chance? |
This relies on backwards-incompatible core refactoring, so I'm afraid not. |
Compatibility breaking would only affect editor plugins. While EditorUndoRedoManager has almost the same interface as UndoRedo, it requires doing extra steps in some cases and obviously it would break if someone uses typing. But if such (rather minor IMO) breakage is acceptable, I guess it could be backported. But someone would have to do it and the PR is quite big, soo... |
* Godot 4.0 beta 1 import file updates * API rename: `update` is now `queue_redraw` Per godotengine/godot#64377 * API rename: `x2y` functions are now `x_to_y` Per godotengine/godot#64367 * Update types: `UndoRedo` is now an internal of `EditorUndoRedoManager` Per godotengine/godot#59564 * beta 3 Co-authored-by: Jeff <jeffrey.arneson@gmail.com>
This is just a proof-of-concept, but looks promising so far:(it's finished, just needs bugfixing)
Right now implemented only in scene tree dock and everything is completely broken xd It needs quite a bit work to finish this PR. But the idea is that there are minimal changes to usage of UndoRedo, everything is magically performed behind the scenes. Most of the changes right now come from the fact that EditorData returns a reference to UndoRedo, so it was accessed with
.
operator in some places and I had to change it.How does this work:
When you undo, the editor will again infer the current context (i.e. the current scene) and undo actions done on that scene. The global actions are mixed-in, I'm planning to add timestamps to actions, so that scenes and global operations can work together.
As I said, the PR is heavily in progress. The new system is hacked together with the old one. I added a method
get_undo_redo2()
, so that I can test parts of the code with the new system. I will remove the old UndoRedo once everything is finished.Also, this does not change the old UndoRedo. It will still be used, but internally by the central EditorUndoRedoManager object. There is a chance that this all might fail at some point (i.e. there will be something that can't be easily replaced), but so far the work is smooth.
Closes godotengine/godot-proposals#1630
Fixes #45601