Undo?

bitwise bitwise.pvt at gmail.com
Thu Oct 12 22:26:44 UTC 2017


On Tuesday, 10 October 2017 at 02:36:56 UTC, Mr. Jonse wrote:
> I requiring an undo feature in my code. Rather than go the 
> regular route of using commands, I'm wondering if D can 
> facilitate an undo system quite easily?
>
> We can think of an undo system in an app as a sort of recorder. 
> The traditional method is to use commands and inverse-commands. 
> By recording the commands one can "unwind" the program by 
> applying the inverse commands. The down side is that the app 
> must be written with this approach in mind.
>
> Storing the complete state of the app is another way which some 
> apps use but usually it is too much data to store.
>
> Since the only thing that one has to store from state of the 
> app to the next is the change in data long with creation and 
> deletion of the data, I think one could simplify the task?
>
> Is it possible to write a generic system that records the the 
> entire state changes without much boilerplate?
>
> I'm thinking that two types of attributes would work, one for 
> aggregates for creation and deletion of objects and one for 
> properties to handle the data changes. If D can be used to 
> automatically hook properties to have them report the changes 
> to the undo system and one can properly deal with object 
> creation and assignment, it might be a pretty sleek way to 
> support undo.
>
>
> Help appreciated!

I wrote an undo system for a level editor once:
https://github.com/nicolasjinchereau/pizza-quest/blob/90d1a2ae75c1f80ee13cedcfb634c6de0f9528db/source/editor/History.h

That class made it trivial to implement unlimited undo/redo.

Each object that's passed to History::AddObjectState() has to 
have `Undoable` implemented so that its state can be copied and 
replaced later if the object needs to be restored. In D though, 
you don't even really have to implement `Undoable`. You can make 
something like AddObjectState() into a template that uses D's 
`__traits`, or `tupleof` to record all of an object's fields into 
some generic undo state. I wrote that code so long ago that I 
don't really remember how I dealt with pointer ownership, but if 
you use GC allocation, or POD types, it should be easy.

With an approach like this, you don't need a discrete set of 
commands, but only objects that can be serialized before an 
operation, and restored afterward if you don't like the result.






More information about the Digitalmars-d-learn mailing list